Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Mar 2010 23:50:09 +0000 (16:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Mar 2010 23:50:09 +0000 (16:50 -0700)
* '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

fs/nfs/callback_xdr.c
fs/nfs/delegation.h
fs/nfs/dir.c
fs/nfs/inode.c
fs/nfs/nfs4proc.c
fs/nfs/pagelist.c
fs/nfs/super.c
net/sunrpc/xprtsock.c

index db30c0b..a2b8b4d 100644 (file)
@@ -782,6 +782,7 @@ struct svc_version nfs4_callback_version1 = {
        .vs_proc = nfs4_callback_procedures1,
        .vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
        .vs_dispatch = NULL,
+       .vs_hidden = 1,
 };
 
 struct svc_version nfs4_callback_version4 = {
index 944b627..69e7b81 100644 (file)
@@ -71,4 +71,10 @@ static inline int nfs_inode_return_delegation(struct inode *inode)
 }
 #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
index a1f6b44..c6f2750 100644 (file)
@@ -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);
        if (cache == NULL)
                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))
                goto out_stale;
        res->jiffies = cache->jiffies;
index 657201a..e358df7 100644 (file)
@@ -729,7 +729,7 @@ int nfs_attribute_timeout(struct inode *inode)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
 
-       if (nfs_have_delegation(inode, FMODE_READ))
+       if (nfs_have_delegated_attributes(inode))
                return 0;
        return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
 }
index eda74c4..f9254fb 100644 (file)
@@ -5107,6 +5107,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
        res = kzalloc(sizeof(*res), GFP_KERNEL);
        if (!args || !res) {
                kfree(args);
+               kfree(res);
                nfs_put_client(clp);
                return -ENOMEM;
        }
index a12c45b..29d9d36 100644 (file)
@@ -112,12 +112,10 @@ void nfs_unlock_request(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))
                return 0;
        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;
 }
 
@@ -126,10 +124,10 @@ int nfs_set_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) {
+               struct inode *inode = req->wb_context->path.dentry->d_inode;
+               struct nfs_inode *nfsi = NFS_I(inode);
+
                spin_lock(&inode->i_lock);
                radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
                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
  * @req:
  *
- * Release page resources associated with a write request after it
- * has completed.
+ * Release page and open context resources associated with a read/write
+ * request after it has completed.
  */
 void nfs_clear_request(struct nfs_page *req)
 {
        struct page *page = req->wb_page;
+       struct nfs_open_context *ctx = req->wb_context;
+
        if (page != NULL) {
                page_cache_release(page);
                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);
 
-       /* Release struct file or cached credential */
+       /* Release struct file and open context */
        nfs_clear_request(req);
-       put_nfs_open_context(req->wb_context);
        nfs_page_free(req);
 }
 
index f1afee4..6baf9a3 100644 (file)
@@ -2214,7 +2214,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2256,6 +2256,9 @@ out_err_nosb:
 error_splat_root:
        dput(mntroot);
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        goto out;
 }
@@ -2326,7 +2329,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2363,6 +2366,9 @@ out_err_noserver:
        return error;
 
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
        return error;
@@ -2578,7 +2584,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2616,6 +2622,9 @@ out_free:
 error_splat_root:
        dput(mntroot);
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        goto out;
 }
@@ -2811,7 +2820,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2847,6 +2856,9 @@ out_err_noserver:
        return error;
 
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
        return error;
@@ -2893,7 +2905,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2929,6 +2941,9 @@ out_err_noserver:
        return error;
 
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
        return error;
index 75ab08e..e4839c0 100644 (file)
@@ -548,8 +548,6 @@ static int xs_udp_send_request(struct rpc_task *task)
                /* Still some bytes left; set up for a retry later. */
                status = -EAGAIN;
        }
-       if (!transport->sock)
-               goto out;
 
        switch (status) {
        case -ENOTSOCK:
@@ -569,7 +567,7 @@ static int xs_udp_send_request(struct rpc_task *task)
                 * prompts ECONNREFUSED. */
                clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
        }
-out:
+
        return status;
 }
 
@@ -651,8 +649,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
                status = -EAGAIN;
                break;
        }
-       if (!transport->sock)
-               goto out;
 
        switch (status) {
        case -ENOTSOCK:
@@ -672,7 +668,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
        case -ENOTCONN:
                clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
        }
-out:
+
        return status;
 }