diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-01 12:07:22 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-01 13:48:13 -0400 |
commit | 25b11dcdbfcad69a5ec03265e2dce19e5eca936b (patch) | |
tree | f7f6ebbf62344f6cb6107815c489ce9918acd2c0 /fs/nfs/write.c | |
parent | 9146ab5055152bbacb5690c384df2fd610fb3c68 (diff) |
NFS: Clean up nfs read and write error paths
Move the error handling for nfs_generic_pagein() into a single function.
Ditto for nfs_generic_flush().
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Fred Isaman <iisaman@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 2f80aa50d967..d1e4f81ba057 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1058,6 +1058,19 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = { | |||
1058 | .completion = nfs_write_completion, | 1058 | .completion = nfs_write_completion, |
1059 | }; | 1059 | }; |
1060 | 1060 | ||
1061 | static void nfs_flush_error(struct nfs_pageio_descriptor *desc, | ||
1062 | struct nfs_pgio_header *hdr) | ||
1063 | { | ||
1064 | set_bit(NFS_IOHDR_REDO, &hdr->flags); | ||
1065 | while (!list_empty(&hdr->rpc_list)) { | ||
1066 | struct nfs_write_data *data = list_first_entry(&hdr->rpc_list, | ||
1067 | struct nfs_write_data, list); | ||
1068 | list_del(&data->list); | ||
1069 | nfs_writedata_release(data); | ||
1070 | } | ||
1071 | desc->pg_completion_ops->error_cleanup(&desc->pg_list); | ||
1072 | } | ||
1073 | |||
1061 | /* | 1074 | /* |
1062 | * Generate multiple small requests to write out a single | 1075 | * Generate multiple small requests to write out a single |
1063 | * contiguous dirty area on one page. | 1076 | * contiguous dirty area on one page. |
@@ -1071,12 +1084,9 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, | |||
1071 | size_t wsize = desc->pg_bsize, nbytes; | 1084 | size_t wsize = desc->pg_bsize, nbytes; |
1072 | unsigned int offset; | 1085 | unsigned int offset; |
1073 | int requests = 0; | 1086 | int requests = 0; |
1074 | int ret = 0; | ||
1075 | struct nfs_commit_info cinfo; | 1087 | struct nfs_commit_info cinfo; |
1076 | 1088 | ||
1077 | nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); | 1089 | nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); |
1078 | nfs_list_remove_request(req); | ||
1079 | nfs_list_add_request(req, &hdr->pages); | ||
1080 | 1090 | ||
1081 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && | 1091 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && |
1082 | (desc->pg_moreio || nfs_reqs_to_commit(&cinfo) || | 1092 | (desc->pg_moreio || nfs_reqs_to_commit(&cinfo) || |
@@ -1090,8 +1100,10 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, | |||
1090 | size_t len = min(nbytes, wsize); | 1100 | size_t len = min(nbytes, wsize); |
1091 | 1101 | ||
1092 | data = nfs_writedata_alloc(hdr, 1); | 1102 | data = nfs_writedata_alloc(hdr, 1); |
1093 | if (!data) | 1103 | if (!data) { |
1094 | goto out_bad; | 1104 | nfs_flush_error(desc, hdr); |
1105 | return -ENOMEM; | ||
1106 | } | ||
1095 | data->pages.pagevec[0] = page; | 1107 | data->pages.pagevec[0] = page; |
1096 | nfs_write_rpcsetup(data, len, offset, desc->pg_ioflags, &cinfo); | 1108 | nfs_write_rpcsetup(data, len, offset, desc->pg_ioflags, &cinfo); |
1097 | list_add(&data->list, &hdr->rpc_list); | 1109 | list_add(&data->list, &hdr->rpc_list); |
@@ -1099,17 +1111,10 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, | |||
1099 | nbytes -= len; | 1111 | nbytes -= len; |
1100 | offset += len; | 1112 | offset += len; |
1101 | } while (nbytes != 0); | 1113 | } while (nbytes != 0); |
1114 | nfs_list_remove_request(req); | ||
1115 | nfs_list_add_request(req, &hdr->pages); | ||
1102 | desc->pg_rpc_callops = &nfs_write_common_ops; | 1116 | desc->pg_rpc_callops = &nfs_write_common_ops; |
1103 | return ret; | 1117 | return 0; |
1104 | |||
1105 | out_bad: | ||
1106 | while (!list_empty(&hdr->rpc_list)) { | ||
1107 | data = list_first_entry(&hdr->rpc_list, struct nfs_write_data, list); | ||
1108 | list_del(&data->list); | ||
1109 | nfs_writedata_release(data); | ||
1110 | } | ||
1111 | desc->pg_completion_ops->error_cleanup(&hdr->pages); | ||
1112 | return -ENOMEM; | ||
1113 | } | 1118 | } |
1114 | 1119 | ||
1115 | /* | 1120 | /* |
@@ -1127,15 +1132,13 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc, | |||
1127 | struct page **pages; | 1132 | struct page **pages; |
1128 | struct nfs_write_data *data; | 1133 | struct nfs_write_data *data; |
1129 | struct list_head *head = &desc->pg_list; | 1134 | struct list_head *head = &desc->pg_list; |
1130 | int ret = 0; | ||
1131 | struct nfs_commit_info cinfo; | 1135 | struct nfs_commit_info cinfo; |
1132 | 1136 | ||
1133 | data = nfs_writedata_alloc(hdr, nfs_page_array_len(desc->pg_base, | 1137 | data = nfs_writedata_alloc(hdr, nfs_page_array_len(desc->pg_base, |
1134 | desc->pg_count)); | 1138 | desc->pg_count)); |
1135 | if (!data) { | 1139 | if (!data) { |
1136 | desc->pg_completion_ops->error_cleanup(head); | 1140 | nfs_flush_error(desc, hdr); |
1137 | ret = -ENOMEM; | 1141 | return -ENOMEM; |
1138 | goto out; | ||
1139 | } | 1142 | } |
1140 | 1143 | ||
1141 | nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); | 1144 | nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); |
@@ -1155,8 +1158,7 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc, | |||
1155 | nfs_write_rpcsetup(data, desc->pg_count, 0, desc->pg_ioflags, &cinfo); | 1158 | nfs_write_rpcsetup(data, desc->pg_count, 0, desc->pg_ioflags, &cinfo); |
1156 | list_add(&data->list, &hdr->rpc_list); | 1159 | list_add(&data->list, &hdr->rpc_list); |
1157 | desc->pg_rpc_callops = &nfs_write_common_ops; | 1160 | desc->pg_rpc_callops = &nfs_write_common_ops; |
1158 | out: | 1161 | return 0; |
1159 | return ret; | ||
1160 | } | 1162 | } |
1161 | 1163 | ||
1162 | int nfs_generic_flush(struct nfs_pageio_descriptor *desc, | 1164 | int nfs_generic_flush(struct nfs_pageio_descriptor *desc, |
@@ -1186,8 +1188,6 @@ static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | |||
1186 | ret = nfs_do_multiple_writes(&hdr->rpc_list, | 1188 | ret = nfs_do_multiple_writes(&hdr->rpc_list, |
1187 | desc->pg_rpc_callops, | 1189 | desc->pg_rpc_callops, |
1188 | desc->pg_ioflags); | 1190 | desc->pg_ioflags); |
1189 | else | ||
1190 | set_bit(NFS_IOHDR_REDO, &hdr->flags); | ||
1191 | if (atomic_dec_and_test(&hdr->refcnt)) | 1191 | if (atomic_dec_and_test(&hdr->refcnt)) |
1192 | hdr->completion_ops->completion(hdr); | 1192 | hdr->completion_ops->completion(hdr); |
1193 | return ret; | 1193 | return ret; |