diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-04-14 14:54:53 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-04-19 16:53:08 -0400 |
commit | dbae4c73f08b8a7980cc912954ade3d4c1fb6147 (patch) | |
tree | 8a1ddd0b9df5ae7e919a235e9c765266d68a0e3f /fs | |
parent | c9d8f89d9816c1d16ada492aa547a4d692508c0d (diff) |
NFS: Ensure that rpc_run_task() errors are propagated back to the caller
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/direct.c | 10 | ||||
-rw-r--r-- | fs/nfs/read.c | 23 | ||||
-rw-r--r-- | fs/nfs/write.c | 33 |
3 files changed, 40 insertions, 26 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index abf8e0286e35..4757a2b326a1 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -347,8 +347,9 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, | |||
347 | NFS_PROTO(inode)->read_setup(data, &msg); | 347 | NFS_PROTO(inode)->read_setup(data, &msg); |
348 | 348 | ||
349 | task = rpc_run_task(&task_setup_data); | 349 | task = rpc_run_task(&task_setup_data); |
350 | if (!IS_ERR(task)) | 350 | if (IS_ERR(task)) |
351 | rpc_put_task(task); | 351 | break; |
352 | rpc_put_task(task); | ||
352 | 353 | ||
353 | dprintk("NFS: %5u initiated direct read call " | 354 | dprintk("NFS: %5u initiated direct read call " |
354 | "(req %s/%Ld, %zu bytes @ offset %Lu)\n", | 355 | "(req %s/%Ld, %zu bytes @ offset %Lu)\n", |
@@ -763,8 +764,9 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, | |||
763 | NFS_PROTO(inode)->write_setup(data, &msg); | 764 | NFS_PROTO(inode)->write_setup(data, &msg); |
764 | 765 | ||
765 | task = rpc_run_task(&task_setup_data); | 766 | task = rpc_run_task(&task_setup_data); |
766 | if (!IS_ERR(task)) | 767 | if (IS_ERR(task)) |
767 | rpc_put_task(task); | 768 | break; |
769 | rpc_put_task(task); | ||
768 | 770 | ||
769 | dprintk("NFS: %5u initiated direct write call " | 771 | dprintk("NFS: %5u initiated direct write call " |
770 | "(req %s/%Ld, %zu bytes @ offset %Lu)\n", | 772 | "(req %s/%Ld, %zu bytes @ offset %Lu)\n", |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 6f9208a549a0..16f57e0af999 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -153,7 +153,7 @@ static void nfs_readpage_release(struct nfs_page *req) | |||
153 | /* | 153 | /* |
154 | * Set up the NFS read request struct | 154 | * Set up the NFS read request struct |
155 | */ | 155 | */ |
156 | static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | 156 | static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, |
157 | const struct rpc_call_ops *call_ops, | 157 | const struct rpc_call_ops *call_ops, |
158 | unsigned int count, unsigned int offset) | 158 | unsigned int count, unsigned int offset) |
159 | { | 159 | { |
@@ -202,8 +202,10 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | |||
202 | (unsigned long long)data->args.offset); | 202 | (unsigned long long)data->args.offset); |
203 | 203 | ||
204 | task = rpc_run_task(&task_setup_data); | 204 | task = rpc_run_task(&task_setup_data); |
205 | if (!IS_ERR(task)) | 205 | if (IS_ERR(task)) |
206 | rpc_put_task(task); | 206 | return PTR_ERR(task); |
207 | rpc_put_task(task); | ||
208 | return 0; | ||
207 | } | 209 | } |
208 | 210 | ||
209 | static void | 211 | static void |
@@ -240,6 +242,7 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne | |||
240 | size_t rsize = NFS_SERVER(inode)->rsize, nbytes; | 242 | size_t rsize = NFS_SERVER(inode)->rsize, nbytes; |
241 | unsigned int offset; | 243 | unsigned int offset; |
242 | int requests = 0; | 244 | int requests = 0; |
245 | int ret = 0; | ||
243 | LIST_HEAD(list); | 246 | LIST_HEAD(list); |
244 | 247 | ||
245 | nfs_list_remove_request(req); | 248 | nfs_list_remove_request(req); |
@@ -261,6 +264,8 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne | |||
261 | offset = 0; | 264 | offset = 0; |
262 | nbytes = count; | 265 | nbytes = count; |
263 | do { | 266 | do { |
267 | int ret2; | ||
268 | |||
264 | data = list_entry(list.next, struct nfs_read_data, pages); | 269 | data = list_entry(list.next, struct nfs_read_data, pages); |
265 | list_del_init(&data->pages); | 270 | list_del_init(&data->pages); |
266 | 271 | ||
@@ -268,13 +273,15 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne | |||
268 | 273 | ||
269 | if (nbytes < rsize) | 274 | if (nbytes < rsize) |
270 | rsize = nbytes; | 275 | rsize = nbytes; |
271 | nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, | 276 | ret2 = nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, |
272 | rsize, offset); | 277 | rsize, offset); |
278 | if (ret == 0) | ||
279 | ret = ret2; | ||
273 | offset += rsize; | 280 | offset += rsize; |
274 | nbytes -= rsize; | 281 | nbytes -= rsize; |
275 | } while (nbytes != 0); | 282 | } while (nbytes != 0); |
276 | 283 | ||
277 | return 0; | 284 | return ret; |
278 | 285 | ||
279 | out_bad: | 286 | out_bad: |
280 | while (!list_empty(&list)) { | 287 | while (!list_empty(&list)) { |
@@ -292,6 +299,7 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned | |||
292 | struct nfs_page *req; | 299 | struct nfs_page *req; |
293 | struct page **pages; | 300 | struct page **pages; |
294 | struct nfs_read_data *data; | 301 | struct nfs_read_data *data; |
302 | int ret = -ENOMEM; | ||
295 | 303 | ||
296 | data = nfs_readdata_alloc(npages); | 304 | data = nfs_readdata_alloc(npages); |
297 | if (!data) | 305 | if (!data) |
@@ -307,11 +315,10 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned | |||
307 | } | 315 | } |
308 | req = nfs_list_entry(data->pages.next); | 316 | req = nfs_list_entry(data->pages.next); |
309 | 317 | ||
310 | nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0); | 318 | return nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0); |
311 | return 0; | ||
312 | out_bad: | 319 | out_bad: |
313 | nfs_async_read_error(head); | 320 | nfs_async_read_error(head); |
314 | return -ENOMEM; | 321 | return ret; |
315 | } | 322 | } |
316 | 323 | ||
317 | /* | 324 | /* |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 31681bb5e4c1..1ade11d1ba07 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -778,7 +778,7 @@ static int flush_task_priority(int how) | |||
778 | /* | 778 | /* |
779 | * Set up the argument/result storage required for the RPC call. | 779 | * Set up the argument/result storage required for the RPC call. |
780 | */ | 780 | */ |
781 | static void nfs_write_rpcsetup(struct nfs_page *req, | 781 | static int nfs_write_rpcsetup(struct nfs_page *req, |
782 | struct nfs_write_data *data, | 782 | struct nfs_write_data *data, |
783 | const struct rpc_call_ops *call_ops, | 783 | const struct rpc_call_ops *call_ops, |
784 | unsigned int count, unsigned int offset, | 784 | unsigned int count, unsigned int offset, |
@@ -841,8 +841,10 @@ static void nfs_write_rpcsetup(struct nfs_page *req, | |||
841 | (unsigned long long)data->args.offset); | 841 | (unsigned long long)data->args.offset); |
842 | 842 | ||
843 | task = rpc_run_task(&task_setup_data); | 843 | task = rpc_run_task(&task_setup_data); |
844 | if (!IS_ERR(task)) | 844 | if (IS_ERR(task)) |
845 | rpc_put_task(task); | 845 | return PTR_ERR(task); |
846 | rpc_put_task(task); | ||
847 | return 0; | ||
846 | } | 848 | } |
847 | 849 | ||
848 | /* If a nfs_flush_* function fails, it should remove reqs from @head and | 850 | /* If a nfs_flush_* function fails, it should remove reqs from @head and |
@@ -868,6 +870,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned | |||
868 | size_t wsize = NFS_SERVER(inode)->wsize, nbytes; | 870 | size_t wsize = NFS_SERVER(inode)->wsize, nbytes; |
869 | unsigned int offset; | 871 | unsigned int offset; |
870 | int requests = 0; | 872 | int requests = 0; |
873 | int ret = 0; | ||
871 | LIST_HEAD(list); | 874 | LIST_HEAD(list); |
872 | 875 | ||
873 | nfs_list_remove_request(req); | 876 | nfs_list_remove_request(req); |
@@ -889,6 +892,8 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned | |||
889 | offset = 0; | 892 | offset = 0; |
890 | nbytes = count; | 893 | nbytes = count; |
891 | do { | 894 | do { |
895 | int ret2; | ||
896 | |||
892 | data = list_entry(list.next, struct nfs_write_data, pages); | 897 | data = list_entry(list.next, struct nfs_write_data, pages); |
893 | list_del_init(&data->pages); | 898 | list_del_init(&data->pages); |
894 | 899 | ||
@@ -896,13 +901,15 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned | |||
896 | 901 | ||
897 | if (nbytes < wsize) | 902 | if (nbytes < wsize) |
898 | wsize = nbytes; | 903 | wsize = nbytes; |
899 | nfs_write_rpcsetup(req, data, &nfs_write_partial_ops, | 904 | ret2 = nfs_write_rpcsetup(req, data, &nfs_write_partial_ops, |
900 | wsize, offset, how); | 905 | wsize, offset, how); |
906 | if (ret == 0) | ||
907 | ret = ret2; | ||
901 | offset += wsize; | 908 | offset += wsize; |
902 | nbytes -= wsize; | 909 | nbytes -= wsize; |
903 | } while (nbytes != 0); | 910 | } while (nbytes != 0); |
904 | 911 | ||
905 | return 0; | 912 | return ret; |
906 | 913 | ||
907 | out_bad: | 914 | out_bad: |
908 | while (!list_empty(&list)) { | 915 | while (!list_empty(&list)) { |
@@ -943,9 +950,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i | |||
943 | req = nfs_list_entry(data->pages.next); | 950 | req = nfs_list_entry(data->pages.next); |
944 | 951 | ||
945 | /* Set up the argument struct */ | 952 | /* Set up the argument struct */ |
946 | nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how); | 953 | return nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how); |
947 | |||
948 | return 0; | ||
949 | out_bad: | 954 | out_bad: |
950 | while (!list_empty(head)) { | 955 | while (!list_empty(head)) { |
951 | req = nfs_list_entry(head->next); | 956 | req = nfs_list_entry(head->next); |
@@ -1183,7 +1188,7 @@ void nfs_commitdata_release(void *data) | |||
1183 | /* | 1188 | /* |
1184 | * Set up the argument/result storage required for the RPC call. | 1189 | * Set up the argument/result storage required for the RPC call. |
1185 | */ | 1190 | */ |
1186 | static void nfs_commit_rpcsetup(struct list_head *head, | 1191 | static int nfs_commit_rpcsetup(struct list_head *head, |
1187 | struct nfs_write_data *data, | 1192 | struct nfs_write_data *data, |
1188 | int how) | 1193 | int how) |
1189 | { | 1194 | { |
@@ -1232,8 +1237,10 @@ static void nfs_commit_rpcsetup(struct list_head *head, | |||
1232 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); | 1237 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); |
1233 | 1238 | ||
1234 | task = rpc_run_task(&task_setup_data); | 1239 | task = rpc_run_task(&task_setup_data); |
1235 | if (!IS_ERR(task)) | 1240 | if (IS_ERR(task)) |
1236 | rpc_put_task(task); | 1241 | return PTR_ERR(task); |
1242 | rpc_put_task(task); | ||
1243 | return 0; | ||
1237 | } | 1244 | } |
1238 | 1245 | ||
1239 | /* | 1246 | /* |
@@ -1251,9 +1258,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how) | |||
1251 | goto out_bad; | 1258 | goto out_bad; |
1252 | 1259 | ||
1253 | /* Set up the argument struct */ | 1260 | /* Set up the argument struct */ |
1254 | nfs_commit_rpcsetup(head, data, how); | 1261 | return nfs_commit_rpcsetup(head, data, how); |
1255 | |||
1256 | return 0; | ||
1257 | out_bad: | 1262 | out_bad: |
1258 | while (!list_empty(head)) { | 1263 | while (!list_empty(head)) { |
1259 | req = nfs_list_entry(head->next); | 1264 | req = nfs_list_entry(head->next); |