aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 19:50:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 19:50:09 -0400
commit7c34691abe23741bfc7d2514efd5a39f0e0ecb06 (patch)
treef5c673eda066f4d7870d502d52d705b629eb8c03
parent5f87e54d7d6f58e8f15819cf8901860d9512e8b4 (diff)
parentcfbc0683af235106e7dabe92003870b82ad6f0ba (diff)
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
-rw-r--r--fs/nfs/callback_xdr.c1
-rw-r--r--fs/nfs/delegation.h6
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/pagelist.c23
-rw-r--r--fs/nfs/super.c25
-rw-r--r--net/sunrpc/xprtsock.c8
8 files changed, 45 insertions, 23 deletions
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index db30c0b398b..a2b8b4df125 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -782,6 +782,7 @@ struct svc_version nfs4_callback_version1 = {
782 .vs_proc = nfs4_callback_procedures1, 782 .vs_proc = nfs4_callback_procedures1,
783 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, 783 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
784 .vs_dispatch = NULL, 784 .vs_dispatch = NULL,
785 .vs_hidden = 1,
785}; 786};
786 787
787struct svc_version nfs4_callback_version4 = { 788struct svc_version nfs4_callback_version4 = {
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 944b627ec6e..69e7b814012 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -71,4 +71,10 @@ static inline int nfs_inode_return_delegation(struct inode *inode)
71} 71}
72#endif 72#endif
73 73
74static inline int nfs_have_delegated_attributes(struct inode *inode)
75{
76 return nfs_have_delegation(inode, FMODE_READ) &&
77 !(NFS_I(inode)->cache_validity & NFS_INO_REVAL_FORCED);
78}
79
74#endif 80#endif
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index a1f6b4438fb..c6f2750648f 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1789,7 +1789,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
1789 cache = nfs_access_search_rbtree(inode, cred); 1789 cache = nfs_access_search_rbtree(inode, cred);
1790 if (cache == NULL) 1790 if (cache == NULL)
1791 goto out; 1791 goto out;
1792 if (!nfs_have_delegation(inode, FMODE_READ) && 1792 if (!nfs_have_delegated_attributes(inode) &&
1793 !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo)) 1793 !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
1794 goto out_stale; 1794 goto out_stale;
1795 res->jiffies = cache->jiffies; 1795 res->jiffies = cache->jiffies;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 657201acda8..e358df75a6a 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -729,7 +729,7 @@ int nfs_attribute_timeout(struct inode *inode)
729{ 729{
730 struct nfs_inode *nfsi = NFS_I(inode); 730 struct nfs_inode *nfsi = NFS_I(inode);
731 731
732 if (nfs_have_delegation(inode, FMODE_READ)) 732 if (nfs_have_delegated_attributes(inode))
733 return 0; 733 return 0;
734 return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo); 734 return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
735} 735}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index eda74c42d55..f9254fb0c9d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5107,6 +5107,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
5107 res = kzalloc(sizeof(*res), GFP_KERNEL); 5107 res = kzalloc(sizeof(*res), GFP_KERNEL);
5108 if (!args || !res) { 5108 if (!args || !res) {
5109 kfree(args); 5109 kfree(args);
5110 kfree(res);
5110 nfs_put_client(clp); 5111 nfs_put_client(clp);
5111 return -ENOMEM; 5112 return -ENOMEM;
5112 } 5113 }
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index a12c45b65dd..29d9d36cd5f 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -112,12 +112,10 @@ void nfs_unlock_request(struct nfs_page *req)
112 */ 112 */
113int nfs_set_page_tag_locked(struct nfs_page *req) 113int nfs_set_page_tag_locked(struct nfs_page *req)
114{ 114{
115 struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode);
116
117 if (!nfs_lock_request_dontget(req)) 115 if (!nfs_lock_request_dontget(req))
118 return 0; 116 return 0;
119 if (req->wb_page != NULL) 117 if (req->wb_page != NULL)
120 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); 118 radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
121 return 1; 119 return 1;
122} 120}
123 121
@@ -126,10 +124,10 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
126 */ 124 */
127void nfs_clear_page_tag_locked(struct nfs_page *req) 125void nfs_clear_page_tag_locked(struct nfs_page *req)
128{ 126{
129 struct inode *inode = req->wb_context->path.dentry->d_inode;
130 struct nfs_inode *nfsi = NFS_I(inode);
131
132 if (req->wb_page != NULL) { 127 if (req->wb_page != NULL) {
128 struct inode *inode = req->wb_context->path.dentry->d_inode;
129 struct nfs_inode *nfsi = NFS_I(inode);
130
133 spin_lock(&inode->i_lock); 131 spin_lock(&inode->i_lock);
134 radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); 132 radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
135 nfs_unlock_request(req); 133 nfs_unlock_request(req);
@@ -142,16 +140,22 @@ void nfs_clear_page_tag_locked(struct nfs_page *req)
142 * nfs_clear_request - Free up all resources allocated to the request 140 * nfs_clear_request - Free up all resources allocated to the request
143 * @req: 141 * @req:
144 * 142 *
145 * Release page resources associated with a write request after it 143 * Release page and open context resources associated with a read/write
146 * has completed. 144 * request after it has completed.
147 */ 145 */
148void nfs_clear_request(struct nfs_page *req) 146void nfs_clear_request(struct nfs_page *req)
149{ 147{
150 struct page *page = req->wb_page; 148 struct page *page = req->wb_page;
149 struct nfs_open_context *ctx = req->wb_context;
150
151 if (page != NULL) { 151 if (page != NULL) {
152 page_cache_release(page); 152 page_cache_release(page);
153 req->wb_page = NULL; 153 req->wb_page = NULL;
154 } 154 }
155 if (ctx != NULL) {
156 put_nfs_open_context(ctx);
157 req->wb_context = NULL;
158 }
155} 159}
156 160
157 161
@@ -165,9 +169,8 @@ static void nfs_free_request(struct kref *kref)
165{ 169{
166 struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref); 170 struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
167 171
168 /* Release struct file or cached credential */ 172 /* Release struct file and open context */
169 nfs_clear_request(req); 173 nfs_clear_request(req);
170 put_nfs_open_context(req->wb_context);
171 nfs_page_free(req); 174 nfs_page_free(req);
172} 175}
173 176
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f1afee4eea7..6baf9a39346 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2214,7 +2214,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
2214 } else { 2214 } else {
2215 error = nfs_bdi_register(server); 2215 error = nfs_bdi_register(server);
2216 if (error) 2216 if (error)
2217 goto error_splat_super; 2217 goto error_splat_bdi;
2218 } 2218 }
2219 2219
2220 if (!s->s_root) { 2220 if (!s->s_root) {
@@ -2256,6 +2256,9 @@ out_err_nosb:
2256error_splat_root: 2256error_splat_root:
2257 dput(mntroot); 2257 dput(mntroot);
2258error_splat_super: 2258error_splat_super:
2259 if (server && !s->s_root)
2260 bdi_unregister(&server->backing_dev_info);
2261error_splat_bdi:
2259 deactivate_locked_super(s); 2262 deactivate_locked_super(s);
2260 goto out; 2263 goto out;
2261} 2264}
@@ -2326,7 +2329,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
2326 } else { 2329 } else {
2327 error = nfs_bdi_register(server); 2330 error = nfs_bdi_register(server);
2328 if (error) 2331 if (error)
2329 goto error_splat_super; 2332 goto error_splat_bdi;
2330 } 2333 }
2331 2334
2332 if (!s->s_root) { 2335 if (!s->s_root) {
@@ -2363,6 +2366,9 @@ out_err_noserver:
2363 return error; 2366 return error;
2364 2367
2365error_splat_super: 2368error_splat_super:
2369 if (server && !s->s_root)
2370 bdi_unregister(&server->backing_dev_info);
2371error_splat_bdi:
2366 deactivate_locked_super(s); 2372 deactivate_locked_super(s);
2367 dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); 2373 dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
2368 return error; 2374 return error;
@@ -2578,7 +2584,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
2578 } else { 2584 } else {
2579 error = nfs_bdi_register(server); 2585 error = nfs_bdi_register(server);
2580 if (error) 2586 if (error)
2581 goto error_splat_super; 2587 goto error_splat_bdi;
2582 } 2588 }
2583 2589
2584 if (!s->s_root) { 2590 if (!s->s_root) {
@@ -2616,6 +2622,9 @@ out_free:
2616error_splat_root: 2622error_splat_root:
2617 dput(mntroot); 2623 dput(mntroot);
2618error_splat_super: 2624error_splat_super:
2625 if (server && !s->s_root)
2626 bdi_unregister(&server->backing_dev_info);
2627error_splat_bdi:
2619 deactivate_locked_super(s); 2628 deactivate_locked_super(s);
2620 goto out; 2629 goto out;
2621} 2630}
@@ -2811,7 +2820,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
2811 } else { 2820 } else {
2812 error = nfs_bdi_register(server); 2821 error = nfs_bdi_register(server);
2813 if (error) 2822 if (error)
2814 goto error_splat_super; 2823 goto error_splat_bdi;
2815 } 2824 }
2816 2825
2817 if (!s->s_root) { 2826 if (!s->s_root) {
@@ -2847,6 +2856,9 @@ out_err_noserver:
2847 return error; 2856 return error;
2848 2857
2849error_splat_super: 2858error_splat_super:
2859 if (server && !s->s_root)
2860 bdi_unregister(&server->backing_dev_info);
2861error_splat_bdi:
2850 deactivate_locked_super(s); 2862 deactivate_locked_super(s);
2851 dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); 2863 dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
2852 return error; 2864 return error;
@@ -2893,7 +2905,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
2893 } else { 2905 } else {
2894 error = nfs_bdi_register(server); 2906 error = nfs_bdi_register(server);
2895 if (error) 2907 if (error)
2896 goto error_splat_super; 2908 goto error_splat_bdi;
2897 } 2909 }
2898 2910
2899 if (!s->s_root) { 2911 if (!s->s_root) {
@@ -2929,6 +2941,9 @@ out_err_noserver:
2929 return error; 2941 return error;
2930 2942
2931error_splat_super: 2943error_splat_super:
2944 if (server && !s->s_root)
2945 bdi_unregister(&server->backing_dev_info);
2946error_splat_bdi:
2932 deactivate_locked_super(s); 2947 deactivate_locked_super(s);
2933 dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); 2948 dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
2934 return error; 2949 return error;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 75ab08eac66..e4839c07c91 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -548,8 +548,6 @@ static int xs_udp_send_request(struct rpc_task *task)
548 /* Still some bytes left; set up for a retry later. */ 548 /* Still some bytes left; set up for a retry later. */
549 status = -EAGAIN; 549 status = -EAGAIN;
550 } 550 }
551 if (!transport->sock)
552 goto out;
553 551
554 switch (status) { 552 switch (status) {
555 case -ENOTSOCK: 553 case -ENOTSOCK:
@@ -569,7 +567,7 @@ static int xs_udp_send_request(struct rpc_task *task)
569 * prompts ECONNREFUSED. */ 567 * prompts ECONNREFUSED. */
570 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); 568 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
571 } 569 }
572out: 570
573 return status; 571 return status;
574} 572}
575 573
@@ -651,8 +649,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
651 status = -EAGAIN; 649 status = -EAGAIN;
652 break; 650 break;
653 } 651 }
654 if (!transport->sock)
655 goto out;
656 652
657 switch (status) { 653 switch (status) {
658 case -ENOTSOCK: 654 case -ENOTSOCK:
@@ -672,7 +668,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
672 case -ENOTCONN: 668 case -ENOTCONN:
673 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); 669 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
674 } 670 }
675out: 671
676 return status; 672 return status;
677} 673}
678 674