mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
NFSv4/flexfiles: honor FF_FLAGS_NO_IO_THRU_MDS in pg_get_mirror_count_write
The FF_FLAGS_NO_IO_THRU_MDS flag lives on each lseg, so any fallback
decision made when there is no current lseg (e.g. between LAYOUTRETURN
and the next LAYOUTGET) cannot run the per-lseg check.
Introduce a sticky hdr-level ditto for FF_FLAGS_NO_IO_THRU_MDS in
struct nfs4_flexfile_layout::flags (NFS4_FF_HDR_NO_IO_THRU_MDS bit),
set whenever ff_layout_alloc_lseg() parses an lseg with the flag. The
bit is never cleared for the lifetime of the layout hdr; the server is
assumed to be consistent in its no-fallback policy per file.
kzalloc() in ff_layout_alloc_layout_hdr() zero-initializes the field.
Use the new ff_layout_hdr_no_fallback_to_mds() helper to gate
ff_layout_pg_get_mirror_count_write(): when pnfs_update_layout() returns
NULL (e.g. NFS_LAYOUT_BULK_RECALL, pnfs_layout_io_test_failed,
pnfs_layoutgets_blocked) the existing code unconditionally calls
nfs_pageio_reset_write_mds(). This is a source of unwanted WRITE to
MDS. Fix it by checking NFS4_FF_HDR_NO_IO_THRU_MDS bit, and if set
surface -EAGAIN instead; the writepage-side caller (nfs_do_writepage()
for buffered, nfs_direct_write_reschedule() for O_DIRECT) then
redirties the request so writeback retries via pNFS.
Fixes: 260074cd84 ("pNFS/flexfiles: Add support for FF_FLAGS_NO_IO_THRU_MDS")
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
This commit is contained in:
committed by
Anna Schumaker
parent
7a375cafc1
commit
1d62e659c0
@@ -636,6 +636,9 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
|
||||
if (!p)
|
||||
goto out_sort_mirrors;
|
||||
fls->flags = be32_to_cpup(p);
|
||||
if (fls->flags & FF_FLAGS_NO_IO_THRU_MDS)
|
||||
set_bit(NFS4_FF_HDR_NO_IO_THRU_MDS,
|
||||
&FF_LAYOUT_FROM_HDR(lh)->flags);
|
||||
|
||||
p = xdr_inline_decode(&stream, 4);
|
||||
if (!p)
|
||||
@@ -1185,6 +1188,16 @@ ff_layout_pg_get_mirror_count_write(struct nfs_pageio_descriptor *pgio,
|
||||
0, NFS4_MAX_UINT64, IOMODE_RW,
|
||||
NFS_I(pgio->pg_inode)->layout,
|
||||
pgio->pg_lseg);
|
||||
if (NFS_I(pgio->pg_inode)->layout &&
|
||||
ff_layout_hdr_no_fallback_to_mds(NFS_I(pgio->pg_inode)->layout)) {
|
||||
/*
|
||||
* FF_FLAGS_NO_IO_THRU_MDS: no current lseg but the server's
|
||||
* policy forbids MDS fallback. Surface -EAGAIN so writeback
|
||||
* retries rather than silently issuing the WRITE via MDS.
|
||||
*/
|
||||
pgio->pg_error = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
/* no lseg means that pnfs is not in use, so no mirroring here */
|
||||
nfs_pageio_reset_write_mds(pgio);
|
||||
out:
|
||||
|
||||
@@ -112,12 +112,16 @@ struct nfs4_ff_layout_segment {
|
||||
struct nfs4_ff_layout_mirror *mirror_array[] __counted_by(mirror_array_cnt);
|
||||
};
|
||||
|
||||
/* nfs4_flexfile_layout::flags bit indices */
|
||||
#define NFS4_FF_HDR_NO_IO_THRU_MDS 0 /* any lseg has had FF_FLAGS_NO_IO_THRU_MDS */
|
||||
|
||||
struct nfs4_flexfile_layout {
|
||||
struct pnfs_layout_hdr generic_hdr;
|
||||
struct pnfs_ds_commit_info commit_info;
|
||||
struct list_head mirrors;
|
||||
struct list_head error_list; /* nfs4_ff_layout_ds_err */
|
||||
ktime_t last_report_time; /* Layoutstat report times */
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
struct nfs4_flexfile_layoutreturn_args {
|
||||
@@ -184,6 +188,18 @@ ff_layout_no_fallback_to_mds(struct pnfs_layout_segment *lseg)
|
||||
return FF_LAYOUT_LSEG(lseg)->flags & FF_FLAGS_NO_IO_THRU_MDS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sticky hdr-level mirror of FF_FLAGS_NO_IO_THRU_MDS so callers that have
|
||||
* no current lseg (e.g. between LAYOUTRETURN and the next LAYOUTGET) can
|
||||
* still honor the no-MDS-fallback policy.
|
||||
*/
|
||||
static inline bool
|
||||
ff_layout_hdr_no_fallback_to_mds(struct pnfs_layout_hdr *lo)
|
||||
{
|
||||
return test_bit(NFS4_FF_HDR_NO_IO_THRU_MDS,
|
||||
&FF_LAYOUT_FROM_HDR(lo)->flags);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ff_layout_no_read_on_rw(struct pnfs_layout_segment *lseg)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user