pnfs/flexfiles: retry getting layout segment for reads
commit eb3fabde15bccdf34f1c9b35a83aa4c0dacbb4ca upstream. If ff_layout_pg_get_read()'s attempt to get a layout segment results in -EAGAIN have ff_layout_pg_init_read() retry it after sleeping. If "softerr" mount is used, use 'io_maxretrans' to limit the number of attempts to get a layout segment. This fixes a long-standing issue of O_DIRECT reads failing with -EAGAIN (11) when using flexfiles Client Side Mirroring (CSM). Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
805bf50521
commit
f8e05df84b
@ -839,6 +839,9 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs4_pnfs_ds *ds;
|
||||
u32 ds_idx;
|
||||
|
||||
if (NFS_SERVER(pgio->pg_inode)->flags &
|
||||
(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
|
||||
pgio->pg_maxretrans = io_maxretrans;
|
||||
retry:
|
||||
ff_layout_pg_check_layout(pgio, req);
|
||||
/* Use full layout for now */
|
||||
@ -852,6 +855,8 @@ retry:
|
||||
if (!pgio->pg_lseg)
|
||||
goto out_nolseg;
|
||||
}
|
||||
/* Reset wb_nio, since getting layout segment was successful */
|
||||
req->wb_nio = 0;
|
||||
|
||||
ds = ff_layout_get_ds_for_read(pgio, &ds_idx);
|
||||
if (!ds) {
|
||||
@ -868,14 +873,24 @@ retry:
|
||||
pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
|
||||
|
||||
pgio->pg_mirror_idx = ds_idx;
|
||||
|
||||
if (NFS_SERVER(pgio->pg_inode)->flags &
|
||||
(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
|
||||
pgio->pg_maxretrans = io_maxretrans;
|
||||
return;
|
||||
out_nolseg:
|
||||
if (pgio->pg_error < 0)
|
||||
if (pgio->pg_error < 0) {
|
||||
if (pgio->pg_error != -EAGAIN)
|
||||
return;
|
||||
/* Retry getting layout segment if lower layer returned -EAGAIN */
|
||||
if (pgio->pg_maxretrans && req->wb_nio++ > pgio->pg_maxretrans) {
|
||||
if (NFS_SERVER(pgio->pg_inode)->flags & NFS_MOUNT_SOFTERR)
|
||||
pgio->pg_error = -ETIMEDOUT;
|
||||
else
|
||||
pgio->pg_error = -EIO;
|
||||
return;
|
||||
}
|
||||
pgio->pg_error = 0;
|
||||
/* Sleep for 1 second before retrying */
|
||||
ssleep(1);
|
||||
goto retry;
|
||||
}
|
||||
out_mds:
|
||||
trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode,
|
||||
0, NFS4_MAX_UINT64, IOMODE_READ,
|
||||
|
Loading…
Reference in New Issue
Block a user