Skip to content

Commit 29b928d

Browse files
committed
pnfs/flexfiles: retry getting layout segment for reads
JIRA: https://issues.redhat.com/browse/RHEL-87767 commit eb3fabd Author: Mike Snitzer <snitzer@kernel.org> Date: Thu Jan 16 20:05:39 2025 -0500 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: stable@vger.kernel.org Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
1 parent 36d0b8f commit 29b928d

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
@@ -831,6 +831,9 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
831831
struct nfs4_pnfs_ds *ds;
832832
u32 ds_idx;
833833

834+
if (NFS_SERVER(pgio->pg_inode)->flags &
835+
(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
836+
pgio->pg_maxretrans = io_maxretrans;
834837
retry:
835838
pnfs_generic_pg_check_layout(pgio, req);
836839
/* Use full layout for now */
@@ -844,6 +847,8 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
844847
if (!pgio->pg_lseg)
845848
goto out_nolseg;
846849
}
850+
/* Reset wb_nio, since getting layout segment was successful */
851+
req->wb_nio = 0;
847852

848853
ds = ff_layout_get_ds_for_read(pgio, &ds_idx);
849854
if (!ds) {
@@ -860,14 +865,24 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
860865
pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
861866

862867
pgio->pg_mirror_idx = ds_idx;
863-
864-
if (NFS_SERVER(pgio->pg_inode)->flags &
865-
(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
866-
pgio->pg_maxretrans = io_maxretrans;
867868
return;
868869
out_nolseg:
869-
if (pgio->pg_error < 0)
870-
return;
870+
if (pgio->pg_error < 0) {
871+
if (pgio->pg_error != -EAGAIN)
872+
return;
873+
/* Retry getting layout segment if lower layer returned -EAGAIN */
874+
if (pgio->pg_maxretrans && req->wb_nio++ > pgio->pg_maxretrans) {
875+
if (NFS_SERVER(pgio->pg_inode)->flags & NFS_MOUNT_SOFTERR)
876+
pgio->pg_error = -ETIMEDOUT;
877+
else
878+
pgio->pg_error = -EIO;
879+
return;
880+
}
881+
pgio->pg_error = 0;
882+
/* Sleep for 1 second before retrying */
883+
ssleep(1);
884+
goto retry;
885+
}
871886
out_mds:
872887
trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode,
873888
0, NFS4_MAX_UINT64, IOMODE_READ,

0 commit comments

Comments
 (0)