diff options
| author | Tigran Mkrtchyan <tigran.mkrtchyan@desy.de> | 2026-10-11 00:18:38 +0200 |
|---|---|---|
| committer | Anna Schumaker <anna.schumaker@hammerspace.com> | 2026-10-19 11:45:00 -0400 |
| commit | fde27289503beabe7e0856dac164a5ced4be0342 (patch) | |
| tree | ee3eab929004eb33d4c3098fe7a51b58ed33bbab | |
| parent | 4b27670ea25b955b710021151471cb252240b1e0 (diff) | |
pNFS/flexfiles: make pg_init retry loops killable
When a task is killed while the pNFS client connects to a data server,
nfs4_pnfs_ds_connect() fails with -ERESTARTSYS. If the layout has
FF_FLAGS_NO_IO_THRU_MDS set, ff_layout_pg_init_read() cannot fall back
to the MDS and retries after an uninterruptible ssleep. As the fatal
signal stays pending, every new connect attempt is aborted the same
way and the task loops forever without returning to user space:
# grep -E 'SigPnd|ShdPnd' /proc/156021/status
SigPnd: 0000000000000100
ShdPnd: 0000000000000100
# cat /proc/156021/stack
msleep+0x2e/0x50
ff_layout_pg_init_read+0x267/0x310 [nfs_layout_flexfiles]
__nfs_pageio_add_request+0x1c1/0x480 [nfs]
nfs_pageio_add_request+0x21d/0x2c0 [nfs]
nfs_read_add_folio+0x143/0x200 [nfs]
nfs_readahead+0x204/0x290 [nfs]
read_pages+0x62/0x230
page_cache_ra_unbounded+0x136/0x180
filemap_get_pages+0xf2/0x350
filemap_read+0xd5/0x320
nfs_file_read+0x6d/0xc0 [nfs]
vfs_read+0x24f/0x3a0
__x64_sys_pread64+0x90/0xc0
do_syscall_64+0x5f/0xe0
Previous attempt propagates the error from nfs4_ff_layout_prepare_ds(), but
only ff_layout_{read,write}_pagelist() look at it. The pg_init functions
test IS_ERR() and retry on any error.
Check for a fatal signal or an exiting task before sleeping in
ff_layout_pg_init_read() and ff_layout_pg_init_write() and fail the I/O
instead of retrying.
Fixes: f06bedfa62d5 ("pNFS/flexfiles: don't attempt pnfs on fatal DS errors")
Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
| -rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index d4f2b57e9d5b..ce3bb5f7a60a 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -960,6 +960,20 @@ ff_layout_get_ds_for_read(struct nfs_pageio_descriptor *pgio, offset, dss_id); } +/* + * Wait before retrying pg_init. Returns false, with pgio->pg_error set, + * if the task was killed or is exiting and must not retry. + */ +static bool ff_layout_pg_retry_wait(struct nfs_pageio_descriptor *pgio) +{ + if (fatal_signal_pending(current) || nfs_current_task_exiting()) { + pgio->pg_error = -ERESTARTSYS; + return false; + } + ssleep(1); + return true; +} + static void ff_layout_pg_get_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req, @@ -1059,7 +1073,8 @@ retry: goto out_mds; pnfs_generic_pg_cleanup(pgio); /* Sleep for 1 second before retrying */ - ssleep(1); + if (!ff_layout_pg_retry_wait(pgio)) + return; goto retry; } @@ -1098,7 +1113,8 @@ retry_nolseg: } pgio->pg_error = 0; /* Sleep for 1 second before retrying */ - ssleep(1); + if (!ff_layout_pg_retry_wait(pgio)) + return; goto retry; out_mds: trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode, @@ -1156,7 +1172,8 @@ retry: goto out_mds; pnfs_generic_pg_cleanup(pgio); /* Sleep for 1 second before retrying */ - ssleep(1); + if (!ff_layout_pg_retry_wait(pgio)) + return; goto retry; } pgm = &pgio->pg_mirrors[i]; |
