Commit 8ce160c5ef06cc89c2b6b26bfa5ef7a5ce2c93e0
Committed by
Trond Myklebust
1 parent
1b0ae06877
Exists in
master
and in
6 other branches
pnfs: recoalesce when ld write pagelist fails
For pnfs pagelist write failure, we need to pg_recoalesce and resend IO to mds. Signed-off-by: Peng Tao <peng_tao@emc.com> Signed-off-by: Jim Rees <rees@umich.edu> Cc: stable@kernel.org [3.0] Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Showing 3 changed files with 32 additions and 15 deletions Side-by-side Diff
fs/nfs/pnfs.c
... | ... | @@ -1168,23 +1168,17 @@ |
1168 | 1168 | /* |
1169 | 1169 | * Called by non rpc-based layout drivers |
1170 | 1170 | */ |
1171 | -int | |
1172 | -pnfs_ld_write_done(struct nfs_write_data *data) | |
1171 | +void pnfs_ld_write_done(struct nfs_write_data *data) | |
1173 | 1172 | { |
1174 | - int status; | |
1175 | - | |
1176 | - if (!data->pnfs_error) { | |
1173 | + if (likely(!data->pnfs_error)) { | |
1177 | 1174 | pnfs_set_layoutcommit(data); |
1178 | 1175 | data->mds_ops->rpc_call_done(&data->task, data); |
1179 | - data->mds_ops->rpc_release(data); | |
1180 | - return 0; | |
1176 | + } else { | |
1177 | + put_lseg(data->lseg); | |
1178 | + data->lseg = NULL; | |
1179 | + dprintk("pnfs write error = %d\n", data->pnfs_error); | |
1181 | 1180 | } |
1182 | - | |
1183 | - dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, | |
1184 | - data->pnfs_error); | |
1185 | - status = nfs_initiate_write(data, NFS_CLIENT(data->inode), | |
1186 | - data->mds_ops, NFS_FILE_SYNC); | |
1187 | - return status ? : -EAGAIN; | |
1181 | + data->mds_ops->rpc_release(data); | |
1188 | 1182 | } |
1189 | 1183 | EXPORT_SYMBOL_GPL(pnfs_ld_write_done); |
1190 | 1184 |
fs/nfs/pnfs.h
... | ... | @@ -201,7 +201,7 @@ |
201 | 201 | void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data); |
202 | 202 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); |
203 | 203 | int _pnfs_return_layout(struct inode *); |
204 | -int pnfs_ld_write_done(struct nfs_write_data *); | |
204 | +void pnfs_ld_write_done(struct nfs_write_data *); | |
205 | 205 | int pnfs_ld_read_done(struct nfs_read_data *); |
206 | 206 | struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino, |
207 | 207 | struct nfs_open_context *ctx, |
fs/nfs/write.c
... | ... | @@ -1166,8 +1166,14 @@ |
1166 | 1166 | static void nfs_writeback_release_full(void *calldata) |
1167 | 1167 | { |
1168 | 1168 | struct nfs_write_data *data = calldata; |
1169 | - int status = data->task.tk_status; | |
1169 | + int ret, status = data->task.tk_status; | |
1170 | + struct nfs_pageio_descriptor pgio; | |
1170 | 1171 | |
1172 | + if (data->pnfs_error) { | |
1173 | + nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE); | |
1174 | + pgio.pg_recoalesce = 1; | |
1175 | + } | |
1176 | + | |
1171 | 1177 | /* Update attributes as result of writeback. */ |
1172 | 1178 | while (!list_empty(&data->pages)) { |
1173 | 1179 | struct nfs_page *req = nfs_list_entry(data->pages.next); |
... | ... | @@ -1182,6 +1188,11 @@ |
1182 | 1188 | req->wb_bytes, |
1183 | 1189 | (long long)req_offset(req)); |
1184 | 1190 | |
1191 | + if (data->pnfs_error) { | |
1192 | + dprintk(", pnfs error = %d\n", data->pnfs_error); | |
1193 | + goto next; | |
1194 | + } | |
1195 | + | |
1185 | 1196 | if (status < 0) { |
1186 | 1197 | nfs_set_pageerror(page); |
1187 | 1198 | nfs_context_set_write_error(req->wb_context, status); |
1188 | 1199 | |
... | ... | @@ -1201,7 +1212,19 @@ |
1201 | 1212 | next: |
1202 | 1213 | nfs_clear_page_tag_locked(req); |
1203 | 1214 | nfs_end_page_writeback(page); |
1215 | + if (data->pnfs_error) { | |
1216 | + lock_page(page); | |
1217 | + nfs_pageio_cond_complete(&pgio, page->index); | |
1218 | + ret = nfs_page_async_flush(&pgio, page, 0); | |
1219 | + if (ret) { | |
1220 | + nfs_set_pageerror(page); | |
1221 | + dprintk("rewrite to MDS error = %d\n", ret); | |
1222 | + } | |
1223 | + unlock_page(page); | |
1224 | + } | |
1204 | 1225 | } |
1226 | + if (data->pnfs_error) | |
1227 | + nfs_pageio_complete(&pgio); | |
1205 | 1228 | nfs_writedata_release(calldata); |
1206 | 1229 | } |
1207 | 1230 |