diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-18 19:50:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-18 19:50:09 -0400 |
commit | 7c34691abe23741bfc7d2514efd5a39f0e0ecb06 (patch) | |
tree | f5c673eda066f4d7870d502d52d705b629eb8c03 | |
parent | 5f87e54d7d6f58e8f15819cf8901860d9512e8b4 (diff) | |
parent | cfbc0683af235106e7dabe92003870b82ad6f0ba (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.c | 1 | ||||
-rw-r--r-- | fs/nfs/delegation.h | 6 | ||||
-rw-r--r-- | fs/nfs/dir.c | 2 | ||||
-rw-r--r-- | fs/nfs/inode.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 1 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 23 | ||||
-rw-r--r-- | fs/nfs/super.c | 25 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 8 |
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 | ||
787 | struct svc_version nfs4_callback_version4 = { | 788 | struct 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 | ||
74 | static 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 | */ |
113 | int nfs_set_page_tag_locked(struct nfs_page *req) | 113 | int 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 | */ |
127 | void nfs_clear_page_tag_locked(struct nfs_page *req) | 125 | void 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 | */ |
148 | void nfs_clear_request(struct nfs_page *req) | 146 | void 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: | |||
2256 | error_splat_root: | 2256 | error_splat_root: |
2257 | dput(mntroot); | 2257 | dput(mntroot); |
2258 | error_splat_super: | 2258 | error_splat_super: |
2259 | if (server && !s->s_root) | ||
2260 | bdi_unregister(&server->backing_dev_info); | ||
2261 | error_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 | ||
2365 | error_splat_super: | 2368 | error_splat_super: |
2369 | if (server && !s->s_root) | ||
2370 | bdi_unregister(&server->backing_dev_info); | ||
2371 | error_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: | |||
2616 | error_splat_root: | 2622 | error_splat_root: |
2617 | dput(mntroot); | 2623 | dput(mntroot); |
2618 | error_splat_super: | 2624 | error_splat_super: |
2625 | if (server && !s->s_root) | ||
2626 | bdi_unregister(&server->backing_dev_info); | ||
2627 | error_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 | ||
2849 | error_splat_super: | 2858 | error_splat_super: |
2859 | if (server && !s->s_root) | ||
2860 | bdi_unregister(&server->backing_dev_info); | ||
2861 | error_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 | ||
2931 | error_splat_super: | 2943 | error_splat_super: |
2944 | if (server && !s->s_root) | ||
2945 | bdi_unregister(&server->backing_dev_info); | ||
2946 | error_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 | } |
572 | out: | 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 | } |
675 | out: | 671 | |
676 | return status; | 672 | return status; |
677 | } | 673 | } |
678 | 674 | ||