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/nfs/write.c | |
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/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 33 |
1 files changed, 19 insertions, 14 deletions
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); |