Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: NFS: ensure bdi_unregister is called on mount failure. NFS: Avoid a deadlock in nfs_release_page NFSv4: Don't ignore the NFS_INO_REVAL_FORCED flag in nfs_revalidate_inode() nfs4: Make the v4 callback service hidden nfs: fix unlikely memory leak rpc client can not deal with ENOSOCK, so translate it into ENOCONN
This commit is contained in:
commit
7c34691abe
8 changed files with 45 additions and 23 deletions
|
@ -782,6 +782,7 @@ struct svc_version nfs4_callback_version1 = {
|
||||||
.vs_proc = nfs4_callback_procedures1,
|
.vs_proc = nfs4_callback_procedures1,
|
||||||
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
|
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
|
||||||
.vs_dispatch = NULL,
|
.vs_dispatch = NULL,
|
||||||
|
.vs_hidden = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct svc_version nfs4_callback_version4 = {
|
struct svc_version nfs4_callback_version4 = {
|
||||||
|
|
|
@ -71,4 +71,10 @@ static inline int nfs_inode_return_delegation(struct inode *inode)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline int nfs_have_delegated_attributes(struct inode *inode)
|
||||||
|
{
|
||||||
|
return nfs_have_delegation(inode, FMODE_READ) &&
|
||||||
|
!(NFS_I(inode)->cache_validity & NFS_INO_REVAL_FORCED);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1789,7 +1789,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
|
||||||
cache = nfs_access_search_rbtree(inode, cred);
|
cache = nfs_access_search_rbtree(inode, cred);
|
||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
if (!nfs_have_delegation(inode, FMODE_READ) &&
|
if (!nfs_have_delegated_attributes(inode) &&
|
||||||
!time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
|
!time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
|
||||||
goto out_stale;
|
goto out_stale;
|
||||||
res->jiffies = cache->jiffies;
|
res->jiffies = cache->jiffies;
|
||||||
|
|
|
@ -729,7 +729,7 @@ int nfs_attribute_timeout(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct nfs_inode *nfsi = NFS_I(inode);
|
struct nfs_inode *nfsi = NFS_I(inode);
|
||||||
|
|
||||||
if (nfs_have_delegation(inode, FMODE_READ))
|
if (nfs_have_delegated_attributes(inode))
|
||||||
return 0;
|
return 0;
|
||||||
return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
|
return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5107,6 +5107,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
|
||||||
res = kzalloc(sizeof(*res), GFP_KERNEL);
|
res = kzalloc(sizeof(*res), GFP_KERNEL);
|
||||||
if (!args || !res) {
|
if (!args || !res) {
|
||||||
kfree(args);
|
kfree(args);
|
||||||
|
kfree(res);
|
||||||
nfs_put_client(clp);
|
nfs_put_client(clp);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,12 +112,10 @@ void nfs_unlock_request(struct nfs_page *req)
|
||||||
*/
|
*/
|
||||||
int nfs_set_page_tag_locked(struct nfs_page *req)
|
int nfs_set_page_tag_locked(struct nfs_page *req)
|
||||||
{
|
{
|
||||||
struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode);
|
|
||||||
|
|
||||||
if (!nfs_lock_request_dontget(req))
|
if (!nfs_lock_request_dontget(req))
|
||||||
return 0;
|
return 0;
|
||||||
if (req->wb_page != NULL)
|
if (req->wb_page != NULL)
|
||||||
radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
|
radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,10 +124,10 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
|
||||||
*/
|
*/
|
||||||
void nfs_clear_page_tag_locked(struct nfs_page *req)
|
void nfs_clear_page_tag_locked(struct nfs_page *req)
|
||||||
{
|
{
|
||||||
struct inode *inode = req->wb_context->path.dentry->d_inode;
|
|
||||||
struct nfs_inode *nfsi = NFS_I(inode);
|
|
||||||
|
|
||||||
if (req->wb_page != NULL) {
|
if (req->wb_page != NULL) {
|
||||||
|
struct inode *inode = req->wb_context->path.dentry->d_inode;
|
||||||
|
struct nfs_inode *nfsi = NFS_I(inode);
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
|
radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
|
||||||
nfs_unlock_request(req);
|
nfs_unlock_request(req);
|
||||||
|
@ -142,16 +140,22 @@ void nfs_clear_page_tag_locked(struct nfs_page *req)
|
||||||
* nfs_clear_request - Free up all resources allocated to the request
|
* nfs_clear_request - Free up all resources allocated to the request
|
||||||
* @req:
|
* @req:
|
||||||
*
|
*
|
||||||
* Release page resources associated with a write request after it
|
* Release page and open context resources associated with a read/write
|
||||||
* has completed.
|
* request after it has completed.
|
||||||
*/
|
*/
|
||||||
void nfs_clear_request(struct nfs_page *req)
|
void nfs_clear_request(struct nfs_page *req)
|
||||||
{
|
{
|
||||||
struct page *page = req->wb_page;
|
struct page *page = req->wb_page;
|
||||||
|
struct nfs_open_context *ctx = req->wb_context;
|
||||||
|
|
||||||
if (page != NULL) {
|
if (page != NULL) {
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
req->wb_page = NULL;
|
req->wb_page = NULL;
|
||||||
}
|
}
|
||||||
|
if (ctx != NULL) {
|
||||||
|
put_nfs_open_context(ctx);
|
||||||
|
req->wb_context = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,9 +169,8 @@ static void nfs_free_request(struct kref *kref)
|
||||||
{
|
{
|
||||||
struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
|
struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
|
||||||
|
|
||||||
/* Release struct file or cached credential */
|
/* Release struct file and open context */
|
||||||
nfs_clear_request(req);
|
nfs_clear_request(req);
|
||||||
put_nfs_open_context(req->wb_context);
|
|
||||||
nfs_page_free(req);
|
nfs_page_free(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2214,7 +2214,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
|
||||||
} else {
|
} else {
|
||||||
error = nfs_bdi_register(server);
|
error = nfs_bdi_register(server);
|
||||||
if (error)
|
if (error)
|
||||||
goto error_splat_super;
|
goto error_splat_bdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->s_root) {
|
if (!s->s_root) {
|
||||||
|
@ -2256,6 +2256,9 @@ out_err_nosb:
|
||||||
error_splat_root:
|
error_splat_root:
|
||||||
dput(mntroot);
|
dput(mntroot);
|
||||||
error_splat_super:
|
error_splat_super:
|
||||||
|
if (server && !s->s_root)
|
||||||
|
bdi_unregister(&server->backing_dev_info);
|
||||||
|
error_splat_bdi:
|
||||||
deactivate_locked_super(s);
|
deactivate_locked_super(s);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -2326,7 +2329,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
|
||||||
} else {
|
} else {
|
||||||
error = nfs_bdi_register(server);
|
error = nfs_bdi_register(server);
|
||||||
if (error)
|
if (error)
|
||||||
goto error_splat_super;
|
goto error_splat_bdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->s_root) {
|
if (!s->s_root) {
|
||||||
|
@ -2363,6 +2366,9 @@ out_err_noserver:
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error_splat_super:
|
error_splat_super:
|
||||||
|
if (server && !s->s_root)
|
||||||
|
bdi_unregister(&server->backing_dev_info);
|
||||||
|
error_splat_bdi:
|
||||||
deactivate_locked_super(s);
|
deactivate_locked_super(s);
|
||||||
dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
|
dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
|
||||||
return error;
|
return error;
|
||||||
|
@ -2578,7 +2584,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
|
||||||
} else {
|
} else {
|
||||||
error = nfs_bdi_register(server);
|
error = nfs_bdi_register(server);
|
||||||
if (error)
|
if (error)
|
||||||
goto error_splat_super;
|
goto error_splat_bdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->s_root) {
|
if (!s->s_root) {
|
||||||
|
@ -2616,6 +2622,9 @@ out_free:
|
||||||
error_splat_root:
|
error_splat_root:
|
||||||
dput(mntroot);
|
dput(mntroot);
|
||||||
error_splat_super:
|
error_splat_super:
|
||||||
|
if (server && !s->s_root)
|
||||||
|
bdi_unregister(&server->backing_dev_info);
|
||||||
|
error_splat_bdi:
|
||||||
deactivate_locked_super(s);
|
deactivate_locked_super(s);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -2811,7 +2820,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
|
||||||
} else {
|
} else {
|
||||||
error = nfs_bdi_register(server);
|
error = nfs_bdi_register(server);
|
||||||
if (error)
|
if (error)
|
||||||
goto error_splat_super;
|
goto error_splat_bdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->s_root) {
|
if (!s->s_root) {
|
||||||
|
@ -2847,6 +2856,9 @@ out_err_noserver:
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error_splat_super:
|
error_splat_super:
|
||||||
|
if (server && !s->s_root)
|
||||||
|
bdi_unregister(&server->backing_dev_info);
|
||||||
|
error_splat_bdi:
|
||||||
deactivate_locked_super(s);
|
deactivate_locked_super(s);
|
||||||
dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
|
dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
|
||||||
return error;
|
return error;
|
||||||
|
@ -2893,7 +2905,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
|
||||||
} else {
|
} else {
|
||||||
error = nfs_bdi_register(server);
|
error = nfs_bdi_register(server);
|
||||||
if (error)
|
if (error)
|
||||||
goto error_splat_super;
|
goto error_splat_bdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->s_root) {
|
if (!s->s_root) {
|
||||||
|
@ -2929,6 +2941,9 @@ out_err_noserver:
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error_splat_super:
|
error_splat_super:
|
||||||
|
if (server && !s->s_root)
|
||||||
|
bdi_unregister(&server->backing_dev_info);
|
||||||
|
error_splat_bdi:
|
||||||
deactivate_locked_super(s);
|
deactivate_locked_super(s);
|
||||||
dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
|
dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -548,8 +548,6 @@ static int xs_udp_send_request(struct rpc_task *task)
|
||||||
/* Still some bytes left; set up for a retry later. */
|
/* Still some bytes left; set up for a retry later. */
|
||||||
status = -EAGAIN;
|
status = -EAGAIN;
|
||||||
}
|
}
|
||||||
if (!transport->sock)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case -ENOTSOCK:
|
case -ENOTSOCK:
|
||||||
|
@ -569,7 +567,7 @@ static int xs_udp_send_request(struct rpc_task *task)
|
||||||
* prompts ECONNREFUSED. */
|
* prompts ECONNREFUSED. */
|
||||||
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
|
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,8 +649,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
|
||||||
status = -EAGAIN;
|
status = -EAGAIN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!transport->sock)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case -ENOTSOCK:
|
case -ENOTSOCK:
|
||||||
|
@ -672,7 +668,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
|
||||||
case -ENOTCONN:
|
case -ENOTCONN:
|
||||||
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
|
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue