Commit 9b7eecdcfeb943f130d86bbc249fde4994b6fe30
Committed by
Trond Myklebust
1 parent
8ce160c5ef
Exists in
master
and in
6 other branches
pnfs: recoalesce when ld read pagelist fails
For pnfs pagelist read 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 19 additions and 15 deletions Side-by-side Diff
fs/nfs/pnfs.c
... | ... | @@ -1262,23 +1262,17 @@ |
1262 | 1262 | /* |
1263 | 1263 | * Called by non rpc-based layout drivers |
1264 | 1264 | */ |
1265 | -int | |
1266 | -pnfs_ld_read_done(struct nfs_read_data *data) | |
1265 | +void pnfs_ld_read_done(struct nfs_read_data *data) | |
1267 | 1266 | { |
1268 | - int status; | |
1269 | - | |
1270 | - if (!data->pnfs_error) { | |
1267 | + if (likely(!data->pnfs_error)) { | |
1271 | 1268 | __nfs4_read_done_cb(data); |
1272 | 1269 | data->mds_ops->rpc_call_done(&data->task, data); |
1273 | - data->mds_ops->rpc_release(data); | |
1274 | - return 0; | |
1270 | + } else { | |
1271 | + put_lseg(data->lseg); | |
1272 | + data->lseg = NULL; | |
1273 | + dprintk("pnfs write error = %d\n", data->pnfs_error); | |
1275 | 1274 | } |
1276 | - | |
1277 | - dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, | |
1278 | - data->pnfs_error); | |
1279 | - status = nfs_initiate_read(data, NFS_CLIENT(data->inode), | |
1280 | - data->mds_ops); | |
1281 | - return status ? : -EAGAIN; | |
1275 | + data->mds_ops->rpc_release(data); | |
1282 | 1276 | } |
1283 | 1277 | EXPORT_SYMBOL_GPL(pnfs_ld_read_done); |
1284 | 1278 |
fs/nfs/pnfs.h
... | ... | @@ -202,7 +202,7 @@ |
202 | 202 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); |
203 | 203 | int _pnfs_return_layout(struct inode *); |
204 | 204 | void pnfs_ld_write_done(struct nfs_write_data *); |
205 | -int pnfs_ld_read_done(struct nfs_read_data *); | |
205 | +void 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, |
208 | 208 | loff_t pos, |
fs/nfs/read.c
... | ... | @@ -541,13 +541,23 @@ |
541 | 541 | static void nfs_readpage_release_full(void *calldata) |
542 | 542 | { |
543 | 543 | struct nfs_read_data *data = calldata; |
544 | + struct nfs_pageio_descriptor pgio; | |
544 | 545 | |
546 | + if (data->pnfs_error) { | |
547 | + nfs_pageio_init_read_mds(&pgio, data->inode); | |
548 | + pgio.pg_recoalesce = 1; | |
549 | + } | |
545 | 550 | while (!list_empty(&data->pages)) { |
546 | 551 | struct nfs_page *req = nfs_list_entry(data->pages.next); |
547 | 552 | |
548 | 553 | nfs_list_remove_request(req); |
549 | - nfs_readpage_release(req); | |
554 | + if (!data->pnfs_error) | |
555 | + nfs_readpage_release(req); | |
556 | + else | |
557 | + nfs_pageio_add_request(&pgio, req); | |
550 | 558 | } |
559 | + if (data->pnfs_error) | |
560 | + nfs_pageio_complete(&pgio); | |
551 | 561 | nfs_readdata_release(calldata); |
552 | 562 | } |
553 | 563 |