aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-01 12:07:22 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-01 13:48:13 -0400
commit25b11dcdbfcad69a5ec03265e2dce19e5eca936b (patch)
treef7f6ebbf62344f6cb6107815c489ce9918acd2c0 /fs/nfs/write.c
parent9146ab5055152bbacb5690c384df2fd610fb3c68 (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.c46
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
1061static 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
1105out_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;
1158out: 1161 return 0;
1159 return ret;
1160} 1162}
1161 1163
1162int nfs_generic_flush(struct nfs_pageio_descriptor *desc, 1164int 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;