summaryrefslogtreecommitdiff
path: root/fs/nfs/flexfilelayout
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
commit8f9aa2c90530ab92301a82231ae44f3722becd93 (patch)
treefb282e955b0a880b07131a135257fe3ec764e928 /fs/nfs/flexfilelayout
parent93467b31bec6da512b51544e5e4584f2745e995e (diff)
parent155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/nfs/flexfilelayout')
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c29
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.h16
2 files changed, 45 insertions, 0 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index e22a8e0daf2c..2e7f857d5a8c 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -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:
@@ -2204,6 +2217,14 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
out_failed:
if (ff_layout_avoid_mds_available_ds(lseg) && !ds_fatal_error)
return PNFS_TRY_AGAIN;
+ if (ff_layout_no_fallback_to_mds(lseg)) {
+ /*
+ * FF_FLAGS_NO_IO_THRU_MDS: force fresh LAYOUTGET,
+ * never fall through to MDS I/O.
+ */
+ pnfs_error_mark_layout_for_return(hdr->inode, lseg);
+ return PNFS_TRY_AGAIN;
+ }
trace_pnfs_mds_fallback_read_pagelist(hdr->inode,
hdr->args.offset, hdr->args.count,
IOMODE_READ, NFS_I(hdr->inode)->layout, lseg);
@@ -2289,6 +2310,14 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
out_failed:
if (ff_layout_avoid_mds_available_ds(lseg) && !ds_fatal_error)
return PNFS_TRY_AGAIN;
+ if (ff_layout_no_fallback_to_mds(lseg)) {
+ /*
+ * FF_FLAGS_NO_IO_THRU_MDS: force fresh LAYOUTGET,
+ * never fall through to MDS I/O.
+ */
+ pnfs_error_mark_layout_for_return(hdr->inode, lseg);
+ return PNFS_TRY_AGAIN;
+ }
trace_pnfs_mds_fallback_write_pagelist(hdr->inode,
hdr->args.offset, hdr->args.count,
IOMODE_RW, NFS_I(hdr->inode)->layout, lseg);
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h
index 17a008c8e97c..a5bd00f69e82 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.h
+++ b/fs/nfs/flexfilelayout/flexfilelayout.h
@@ -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)
{