Skip to content

Commit eb3fabd

Browse files
Mike SnitzerAnna Schumaker
authored andcommitted
pnfs/flexfiles: retry getting layout segment for reads
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: [email protected] Signed-off-by: Mike Snitzer <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 0b96c75 commit eb3fabd

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,9 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
848848
struct nfs4_pnfs_ds *ds;
849849
u32 ds_idx;
850850

851+
if (NFS_SERVER(pgio->pg_inode)->flags &
852+
(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
853+
pgio->pg_maxretrans = io_maxretrans;
851854
retry:
852855
pnfs_generic_pg_check_layout(pgio, req);
853856
/* Use full layout for now */
@@ -861,6 +864,8 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
861864
if (!pgio->pg_lseg)
862865
goto out_nolseg;
863866
}
867+
/* Reset wb_nio, since getting layout segment was successful */
868+
req->wb_nio = 0;
864869

865870
ds = ff_layout_get_ds_for_read(pgio, &ds_idx);
866871
if (!ds) {
@@ -877,14 +882,24 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
877882
pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
878883

879884
pgio->pg_mirror_idx = ds_idx;
880-
881-
if (NFS_SERVER(pgio->pg_inode)->flags &
882-
(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
883-
pgio->pg_maxretrans = io_maxretrans;
884885
return;
885886
out_nolseg:
886-
if (pgio->pg_error < 0)
887-
return;
887+
if (pgio->pg_error < 0) {
888+
if (pgio->pg_error != -EAGAIN)
889+
return;
890+
/* Retry getting layout segment if lower layer returned -EAGAIN */
891+
if (pgio->pg_maxretrans && req->wb_nio++ > pgio->pg_maxretrans) {
892+
if (NFS_SERVER(pgio->pg_inode)->flags & NFS_MOUNT_SOFTERR)
893+
pgio->pg_error = -ETIMEDOUT;
894+
else
895+
pgio->pg_error = -EIO;
896+
return;
897+
}
898+
pgio->pg_error = 0;
899+
/* Sleep for 1 second before retrying */
900+
ssleep(1);
901+
goto retry;
902+
}
888903
out_mds:
889904
trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode,
890905
0, NFS4_MAX_UINT64, IOMODE_READ,

0 commit comments

Comments
 (0)