aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-14 14:54:53 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-19 16:53:08 -0400
commitdbae4c73f08b8a7980cc912954ade3d4c1fb6147 (patch)
tree8a1ddd0b9df5ae7e919a235e9c765266d68a0e3f
parentc9d8f89d9816c1d16ada492aa547a4d692508c0d (diff)
NFS: Ensure that rpc_run_task() errors are propagated back to the caller
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/direct.c10
-rw-r--r--fs/nfs/read.c23
-rw-r--r--fs/nfs/write.c33
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 */
156static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, 156static 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
209static void 211static 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
279out_bad: 286out_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;
312out_bad: 319out_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 */
781static void nfs_write_rpcsetup(struct nfs_page *req, 781static 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
907out_bad: 914out_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 */
1186static void nfs_commit_rpcsetup(struct list_head *head, 1191static 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);