* FAILED: patch "[PATCH] nfsd: don't offer flexfiles layouts when NFSv3 isn't being" failed to apply to 6.18-stable tree
@ 2026-11-04 18:50 gregkh
2026-11-06 1:53 ` [PATCH 6.18.y 1/5] NFSD/blocklayout: Extract extent mapping from proc_layoutget Sasha Levin
0 siblings, 1 reply; 6+ messages in thread
From: gregkh @ 2026-11-04 18:50 UTC (permalink / raw)
To: jlayton, cel, itsme; +Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 5d28b2c920d9d9d3c45b41769342ad785eb372a7
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026110409-glaucoma-strongman-8f52@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 5d28b2c920d9d9d3c45b41769342ad785eb372a7 Mon Sep 17 00:00:00 2001
From: Jeff Layton <jlayton@kernel.org>
Date: Fri, 4 Sep 2026 12:11:37 -0400
Subject: [PATCH] nfsd: don't offer flexfiles layouts when NFSv3 isn't being
served
The flexfiles layout driver hands out a deviceinfo that names this server
as an NFSv3 DS (flexfilelayout.c hardcodes da->version = 3). With v3
disabled, the client can't talk to the DS: it loops on v3 NULL calls that
the server answers with PROG_MISMATCH, and I/O hangs in D state.
Skip LAYOUT_FLEX_FILES in nfsd4_setup_layout_type() unless v3 is enabled.
Reported-by: Benji Wiebe <itsme@benjiwiebe.com>
Closes: https://lore.kernel.org/linux-nfs/c734eeb8-8486-4491-bb4d-b9656cbaffbe@app.fastmail.com/
Fixes: 9b9960a0ca47 ("nfsd: Add a super simple flex file server")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260904-pnfs-ff-v1-1-5f502cf25401@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 4187202f9acc..12acb68cbc3b 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -128,10 +128,12 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
void nfsd4_setup_layout_type(struct svc_export *exp)
{
+ struct nfsd_net *nn = net_generic(exp->cd->net, nfsd_net_id);
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
expfs_block_layouts_t block_supported = exportfs_layouts_supported(sb);
- if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT))
+ if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT) &&
+ nfsd_vers(nn, 3, NFSD_TEST))
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
if (IS_ENABLED(CONFIG_NFSD_BLOCKLAYOUT) &&
(block_supported & EXPFS_BLOCK_IN_BAND_ID))
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.18.y 1/5] NFSD/blocklayout: Extract extent mapping from proc_layoutget
2026-11-04 18:50 FAILED: patch "[PATCH] nfsd: don't offer flexfiles layouts when NFSv3 isn't being" failed to apply to 6.18-stable tree gregkh
@ 2026-11-06 1:53 ` Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 2/5] exportfs: Complete kernel-doc for struct export_operations Sasha Levin
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Sasha Levin @ 2026-11-06 1:53 UTC (permalink / raw)
To: stable; +Cc: Sergey Bashirov, Christoph Hellwig, Chuck Lever, Sasha Levin
From: Sergey Bashirov <sergeybashirov@gmail.com>
[ Upstream commit a1dce715c64d4376321b5534366ae48fd7d14bcc ]
No changes in functionality. Split the proc_layoutget function to
create a helper function that maps single extent to the requested
range. This helper function is then used to implement support for
multiple extents per LAYOUTGET.
Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/blocklayout.c | 115 ++++++++++++++++++++++++------------------
1 file changed, 66 insertions(+), 49 deletions(-)
diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index e9512c34c9dcf..8f6478d88ea22 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -17,68 +17,44 @@
#define NFSDDBG_FACILITY NFSDDBG_PNFS
+/*
+ * Get an extent from the file system that starts at offset or below
+ * and may be shorter than the requested length.
+ */
static __be32
-nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
- const struct svc_fh *fhp, struct nfsd4_layoutget *args)
+nfsd4_block_map_extent(struct inode *inode, const struct svc_fh *fhp,
+ u64 offset, u64 length, u32 iomode, u64 minlength,
+ struct pnfs_block_extent *bex)
{
- struct nfsd4_layout_seg *seg = &args->lg_seg;
struct super_block *sb = inode->i_sb;
- u64 length;
- u32 block_size = i_blocksize(inode);
- struct pnfs_block_extent *bex;
struct iomap iomap;
u32 device_generation = 0;
int error;
- if (locks_in_grace(SVC_NET(rqstp)))
- return nfserr_grace;
-
- if (seg->offset & (block_size - 1)) {
- dprintk("pnfsd: I/O misaligned\n");
- goto out_layoutunavailable;
- }
-
- /*
- * Some clients barf on non-zero block numbers for NONE or INVALID
- * layouts, so make sure to zero the whole structure.
- */
- error = -ENOMEM;
- bex = kzalloc(sizeof(*bex), GFP_KERNEL);
- if (!bex)
- goto out_error;
- args->lg_content = bex;
-
- error = sb->s_export_op->map_blocks(inode, seg->offset, seg->length,
- &iomap, seg->iomode != IOMODE_READ,
- &device_generation);
+ error = sb->s_export_op->map_blocks(inode, offset, length, &iomap,
+ iomode != IOMODE_READ, &device_generation);
if (error) {
if (error == -ENXIO)
- goto out_layoutunavailable;
- goto out_error;
- }
-
- length = iomap.offset + iomap.length - seg->offset;
- if (length < args->lg_minlength) {
- dprintk("pnfsd: extent smaller than minlength\n");
- goto out_layoutunavailable;
+ return nfserr_layoutunavailable;
+ return nfserrno(error);
}
switch (iomap.type) {
case IOMAP_MAPPED:
- if (seg->iomode == IOMODE_READ)
+ if (iomode == IOMODE_READ)
bex->es = PNFS_BLOCK_READ_DATA;
else
bex->es = PNFS_BLOCK_READWRITE_DATA;
bex->soff = iomap.addr;
break;
case IOMAP_UNWRITTEN:
- if (seg->iomode & IOMODE_RW) {
+ if (iomode & IOMODE_RW) {
/*
* Crack monkey special case from section 2.3.1.
*/
- if (args->lg_minlength == 0) {
+ if (minlength == 0) {
dprintk("pnfsd: no soup for you!\n");
- goto out_layoutunavailable;
+ return nfserr_layoutunavailable;
}
bex->es = PNFS_BLOCK_INVALID_DATA;
@@ -87,7 +63,7 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
}
fallthrough;
case IOMAP_HOLE:
- if (seg->iomode == IOMODE_READ) {
+ if (iomode == IOMODE_READ) {
bex->es = PNFS_BLOCK_NONE_DATA;
break;
}
@@ -95,27 +71,68 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
case IOMAP_DELALLOC:
default:
WARN(1, "pnfsd: filesystem returned %d extent\n", iomap.type);
- goto out_layoutunavailable;
+ return nfserr_layoutunavailable;
}
error = nfsd4_set_deviceid(&bex->vol_id, fhp, device_generation);
if (error)
- goto out_error;
+ return nfserrno(error);
+
bex->foff = iomap.offset;
bex->len = iomap.length;
+ return nfs_ok;
+}
+
+static __be32
+nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
+ const struct svc_fh *fhp, struct nfsd4_layoutget *args)
+{
+ struct nfsd4_layout_seg *seg = &args->lg_seg;
+ struct pnfs_block_extent *bex;
+ u64 length;
+ u32 block_size = i_blocksize(inode);
+ __be32 nfserr;
+
+ if (locks_in_grace(SVC_NET(rqstp)))
+ return nfserr_grace;
- seg->offset = iomap.offset;
- seg->length = iomap.length;
+ nfserr = nfserr_layoutunavailable;
+ if (seg->offset & (block_size - 1)) {
+ dprintk("pnfsd: I/O misaligned\n");
+ goto out_error;
+ }
+
+ /*
+ * Some clients barf on non-zero block numbers for NONE or INVALID
+ * layouts, so make sure to zero the whole structure.
+ */
+ nfserr = nfserrno(-ENOMEM);
+ bex = kzalloc(sizeof(*bex), GFP_KERNEL);
+ if (!bex)
+ goto out_error;
+ args->lg_content = bex;
+
+ nfserr = nfsd4_block_map_extent(inode, fhp, seg->offset, seg->length,
+ seg->iomode, args->lg_minlength, bex);
+ if (nfserr != nfs_ok)
+ goto out_error;
+
+ nfserr = nfserr_layoutunavailable;
+ length = bex->foff + bex->len - seg->offset;
+ if (length < args->lg_minlength) {
+ dprintk("pnfsd: extent smaller than minlength\n");
+ goto out_error;
+ }
+
+ seg->offset = bex->foff;
+ seg->length = bex->len;
dprintk("GET: 0x%llx:0x%llx %d\n", bex->foff, bex->len, bex->es);
- return 0;
+ return nfs_ok;
out_error:
seg->length = 0;
- return nfserrno(error);
-out_layoutunavailable:
- seg->length = 0;
- return nfserr_layoutunavailable;
+ return nfserr;
}
static __be32
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.18.y 2/5] exportfs: Complete kernel-doc for struct export_operations
2026-11-06 1:53 ` [PATCH 6.18.y 1/5] NFSD/blocklayout: Extract extent mapping from proc_layoutget Sasha Levin
@ 2026-11-06 1:53 ` Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 3/5] exportfs: split out the ops for layout-based block device access Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-11-06 1:53 UTC (permalink / raw)
To: stable; +Cc: André Almeida, Chuck Lever, Christian Brauner, Sasha Levin
From: André Almeida <andrealmeid@igalia.com>
[ Upstream commit 7a6f811e2c06d656996776771f0498df129a0cc2 ]
Write down the missing members definitions for struct export_operations,
using as a reference the commit messages that created the members.
Signed-off-by: André Almeida <andrealmeid@igalia.com>
Link: https://patch.msgid.link/20260112-tonyk-fs_uuid-v1-3-acc1889de772@igalia.com
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/exportfs.h | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index f0cf2714ec52d..0dc1bae9e1654 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -201,7 +201,7 @@ struct handle_to_path_ctx {
* @commit_metadata: commit metadata changes to stable storage
*
* See Documentation/filesystems/nfs/exporting.rst for details on how to use
- * this interface correctly.
+ * this interface correctly and the definition of the flags.
*
* encode_fh:
* @encode_fh should store in the file handle fragment @fh (using at most
@@ -252,6 +252,19 @@ struct handle_to_path_ctx {
* commit_metadata:
* @commit_metadata should commit metadata changes to stable storage.
*
+ * @get_uuid:
+ * Get a filesystem unique signature exposed to clients.
+ *
+ * @map_blocks:
+ * Map and, if necessary, allocate blocks for a layout.
+ *
+ * @commit_blocks:
+ * Commit blocks in a layout once the client is done with them.
+ *
+ * @flags:
+ * Allows the filesystem to communicate to nfsd that it may want to do things
+ * differently when dealing with it.
+ *
* Locking rules:
* get_parent is called with child->d_inode->i_rwsem down
* get_name is not (which is possibly inconsistent)
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.18.y 3/5] exportfs: split out the ops for layout-based block device access
2026-11-06 1:53 ` [PATCH 6.18.y 1/5] NFSD/blocklayout: Extract extent mapping from proc_layoutget Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 2/5] exportfs: Complete kernel-doc for struct export_operations Sasha Levin
@ 2026-11-06 1:53 ` Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 4/5] exportfs,nfsd: rework checking for layout-based block device access support Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 5/5] nfsd: don't offer flexfiles layouts when NFSv3 isn't being served Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-11-06 1:53 UTC (permalink / raw)
To: stable
Cc: Christoph Hellwig, Jeff Layton, Chuck Lever, Christian Brauner,
Sasha Levin
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit d5758c31a81bcd9d5ac8a7456549b05df3579068 ]
The support to grant layouts for direct block device access works
at a very different layer than the rest of exports. Split the methods
for it into a separate struct, and move that into a separate header
to better split things out. The pointer to the new operation vector
is kept in export_operations to avoid bloating the super_block.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Link: https://patch.msgid.link/20260423181854.743150-3-cel@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
MAINTAINERS | 2 +-
fs/nfsd/blocklayout.c | 14 ++++++------
fs/nfsd/nfs4layouts.c | 9 ++++----
fs/xfs/xfs_export.c | 4 +---
fs/xfs/xfs_pnfs.c | 12 ++++++++---
fs/xfs/xfs_pnfs.h | 11 +++++-----
include/linux/exportfs.h | 25 +++++++---------------
include/linux/exportfs_block.h | 39 ++++++++++++++++++++++++++++++++++
8 files changed, 74 insertions(+), 42 deletions(-)
create mode 100644 include/linux/exportfs_block.h
diff --git a/MAINTAINERS b/MAINTAINERS
index f5ea8588244c9..5821d97ae3304 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9606,7 +9606,7 @@ S: Supported
F: Documentation/filesystems/nfs/exporting.rst
F: fs/exportfs/
F: fs/fhandle.c
-F: include/linux/exportfs.h
+F: include/linux/exportfs*.h
FILESYSTEMS [IDMAPPED MOUNTS]
M: Christian Brauner <brauner@kernel.org>
diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index 8f6478d88ea22..ac1312fd1c457 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -2,7 +2,7 @@
/*
* Copyright (c) 2014-2016 Christoph Hellwig.
*/
-#include <linux/exportfs.h>
+#include <linux/exportfs_block.h>
#include <linux/iomap.h>
#include <linux/slab.h>
#include <linux/pr.h>
@@ -31,8 +31,8 @@ nfsd4_block_map_extent(struct inode *inode, const struct svc_fh *fhp,
u32 device_generation = 0;
int error;
- error = sb->s_export_op->map_blocks(inode, offset, length, &iomap,
- iomode != IOMODE_READ, &device_generation);
+ error = sb->s_export_op->block_ops->map_blocks(inode, offset, length,
+ &iomap, iomode != IOMODE_READ, &device_generation);
if (error) {
if (error == -ENXIO)
return nfserr_layoutunavailable;
@@ -154,8 +154,8 @@ nfsd4_block_commit_blocks(struct inode *inode, struct nfsd4_layoutcommit *lcp,
iattr.ia_size = lcp->lc_newsize;
}
- error = inode->i_sb->s_export_op->commit_blocks(inode, iomaps,
- nr_iomaps, &iattr);
+ error = inode->i_sb->s_export_op->block_ops->commit_blocks(inode,
+ iomaps, nr_iomaps, &iattr);
kfree(iomaps);
return nfserrno(error);
}
@@ -178,8 +178,8 @@ nfsd4_block_get_device_info_simple(struct super_block *sb,
b->type = PNFS_BLOCK_VOLUME_SIMPLE;
b->simple.sig_len = PNFS_BLOCK_UUID_LEN;
- return sb->s_export_op->get_uuid(sb, b->simple.sig, &b->simple.sig_len,
- &b->simple.offset);
+ return sb->s_export_op->block_ops->get_uuid(sb, b->simple.sig,
+ &b->simple.sig_len, &b->simple.offset);
}
static __be32
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 2121ef26e7a98..6b6f55ae0472d 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -3,6 +3,7 @@
* Copyright (c) 2014 Christoph Hellwig.
*/
#include <linux/blkdev.h>
+#include <linux/exportfs_block.h>
#include <linux/kmod.h>
#include <linux/file.h>
#include <linux/jhash.h>
@@ -127,6 +128,7 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
{
#if defined(CONFIG_NFSD_BLOCKLAYOUT) || defined(CONFIG_NFSD_SCSILAYOUT)
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
+ const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
#endif
if (!(exp->ex_flags & NFSEXP_PNFS))
@@ -136,14 +138,11 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
#endif
#ifdef CONFIG_NFSD_BLOCKLAYOUT
- if (sb->s_export_op->get_uuid &&
- sb->s_export_op->map_blocks &&
- sb->s_export_op->commit_blocks)
+ if (bops && bops->get_uuid && bops->map_blocks && bops->commit_blocks)
exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
#endif
#ifdef CONFIG_NFSD_SCSILAYOUT
- if (sb->s_export_op->map_blocks &&
- sb->s_export_op->commit_blocks &&
+ if (bops && bops->map_blocks && bops->commit_blocks &&
sb->s_bdev &&
sb->s_bdev->bd_disk->fops->pr_ops &&
sb->s_bdev->bd_disk->fops->get_unique_id)
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index 201489d3de089..f64e035cacb55 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -244,8 +244,6 @@ const struct export_operations xfs_export_operations = {
.get_parent = xfs_fs_get_parent,
.commit_metadata = xfs_fs_nfs_commit_metadata,
#ifdef CONFIG_EXPORTFS_BLOCK_OPS
- .get_uuid = xfs_fs_get_uuid,
- .map_blocks = xfs_fs_map_blocks,
- .commit_blocks = xfs_fs_commit_blocks,
+ .block_ops = &xfs_export_block_ops,
#endif
};
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index afe7497012d4c..c685995b69d7e 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -49,7 +49,7 @@ xfs_break_leased_layouts(
* Get a unique ID including its location so that the client can identify
* the exported device.
*/
-int
+static int
xfs_fs_get_uuid(
struct super_block *sb,
u8 *buf,
@@ -104,7 +104,7 @@ xfs_fs_map_update_inode(
/*
* Get a layout for the pNFS client.
*/
-int
+static int
xfs_fs_map_blocks(
struct inode *inode,
loff_t offset,
@@ -252,7 +252,7 @@ xfs_pnfs_validate_isize(
* to manually flush the cache here similar to what the fsync code path does
* for datasyncs on files that have no dirty metadata.
*/
-int
+static int
xfs_fs_commit_blocks(
struct inode *inode,
struct iomap *maps,
@@ -332,3 +332,9 @@ xfs_fs_commit_blocks(
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
+
+const struct exportfs_block_ops xfs_export_block_ops = {
+ .get_uuid = xfs_fs_get_uuid,
+ .map_blocks = xfs_fs_map_blocks,
+ .commit_blocks = xfs_fs_commit_blocks,
+};
diff --git a/fs/xfs/xfs_pnfs.h b/fs/xfs/xfs_pnfs.h
index 940c6c2ad88c5..bf43b2009e4cc 100644
--- a/fs/xfs/xfs_pnfs.h
+++ b/fs/xfs/xfs_pnfs.h
@@ -2,13 +2,9 @@
#ifndef _XFS_PNFS_H
#define _XFS_PNFS_H 1
-#ifdef CONFIG_EXPORTFS_BLOCK_OPS
-int xfs_fs_get_uuid(struct super_block *sb, u8 *buf, u32 *len, u64 *offset);
-int xfs_fs_map_blocks(struct inode *inode, loff_t offset, u64 length,
- struct iomap *iomap, bool write, u32 *device_generation);
-int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps,
- struct iattr *iattr);
+#include <linux/exportfs_block.h>
+#ifdef CONFIG_EXPORTFS_BLOCK_OPS
int xfs_break_leased_layouts(struct inode *inode, uint *iolock,
bool *did_unlock);
#else
@@ -18,4 +14,7 @@ xfs_break_leased_layouts(struct inode *inode, uint *iolock, bool *did_unlock)
return 0;
}
#endif /* CONFIG_EXPORTFS_BLOCK_OPS */
+
+extern const struct exportfs_block_ops xfs_export_block_ops;
+
#endif /* _XFS_PNFS_H */
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index 0dc1bae9e1654..dfeadad435a60 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -6,9 +6,8 @@
#include <linux/path.h>
struct dentry;
-struct iattr;
+struct exportfs_block_ops;
struct inode;
-struct iomap;
struct super_block;
struct vfsmount;
@@ -252,19 +251,13 @@ struct handle_to_path_ctx {
* commit_metadata:
* @commit_metadata should commit metadata changes to stable storage.
*
- * @get_uuid:
- * Get a filesystem unique signature exposed to clients.
- *
- * @map_blocks:
- * Map and, if necessary, allocate blocks for a layout.
- *
- * @commit_blocks:
- * Commit blocks in a layout once the client is done with them.
- *
* @flags:
* Allows the filesystem to communicate to nfsd that it may want to do things
* differently when dealing with it.
*
+ * @block_ops:
+ * Operations for layout grants to block on the underlying device.
+ *
* Locking rules:
* get_parent is called with child->d_inode->i_rwsem down
* get_name is not (which is possibly inconsistent)
@@ -282,12 +275,6 @@ struct export_operations {
struct dentry * (*get_parent)(struct dentry *child);
int (*commit_metadata)(struct inode *inode);
- int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset);
- int (*map_blocks)(struct inode *inode, loff_t offset,
- u64 len, struct iomap *iomap,
- bool write, u32 *device_generation);
- int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
- int nr_iomaps, struct iattr *iattr);
int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags);
struct file * (*open)(const struct path *path, unsigned int oflags);
#define EXPORT_OP_NOWCC (0x1) /* don't collect v3 wcc data */
@@ -300,6 +287,10 @@ struct export_operations {
#define EXPORT_OP_FLUSH_ON_CLOSE (0x20) /* fs flushes file data on close */
#define EXPORT_OP_NOLOCKS (0x40) /* no file locking support */
unsigned long flags;
+
+#ifdef CONFIG_EXPORTFS_BLOCK_OPS
+ const struct exportfs_block_ops *block_ops;
+#endif
};
/**
diff --git a/include/linux/exportfs_block.h b/include/linux/exportfs_block.h
new file mode 100644
index 0000000000000..1f52fea8e4dce
--- /dev/null
+++ b/include/linux/exportfs_block.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2014-2026 Christoph Hellwig.
+ *
+ * Support for exportfs-based layout grants for direct block device access.
+ */
+#ifndef LINUX_EXPORTFS_BLOCK_H
+#define LINUX_EXPORTFS_BLOCK_H 1
+
+#include <linux/types.h>
+
+struct iattr;
+struct inode;
+struct iomap;
+struct super_block;
+
+struct exportfs_block_ops {
+ /*
+ * Get the in-band device unique signature exposed to clients.
+ */
+ int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset);
+
+ /*
+ * Map blocks for direct block access.
+ * If @write is %true, also allocate the blocks for the range if needed.
+ */
+ int (*map_blocks)(struct inode *inode, loff_t offset, u64 len,
+ struct iomap *iomap, bool write,
+ u32 *device_generation);
+
+ /*
+ * Commit blocks previously handed out by ->map_blocks and written to by
+ * the client.
+ */
+ int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
+ int nr_iomaps, struct iattr *iattr);
+};
+
+#endif /* LINUX_EXPORTFS_BLOCK_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.18.y 4/5] exportfs,nfsd: rework checking for layout-based block device access support
2026-11-06 1:53 ` [PATCH 6.18.y 1/5] NFSD/blocklayout: Extract extent mapping from proc_layoutget Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 2/5] exportfs: Complete kernel-doc for struct export_operations Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 3/5] exportfs: split out the ops for layout-based block device access Sasha Levin
@ 2026-11-06 1:53 ` Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 5/5] nfsd: don't offer flexfiles layouts when NFSv3 isn't being served Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-11-06 1:53 UTC (permalink / raw)
To: stable
Cc: Christoph Hellwig, Jeff Layton, Chuck Lever, Christian Brauner,
Sasha Levin
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit da9baa5470dcb077a7c9806f0925c60b530c470b ]
Currently NFSD hard codes checking support for block-style layouts.
Lift the checks into a file system-helper and provide a exportfs-level
helper to implement the typical checks.
This prepares for supporting block layout export of multiple devices
per file system.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Link: https://patch.msgid.link/20260423181854.743150-5-cel@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/export.c | 3 +-
fs/nfsd/nfs4layouts.c | 26 +++++------------
fs/xfs/xfs_pnfs.c | 13 +++++++++
include/linux/exportfs_block.h | 52 +++++++++++++++++++++++++++++++++-
4 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 2a1499f2ad196..e33843a937dd6 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -722,7 +722,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
goto out4;
err = 0;
- nfsd4_setup_layout_type(&exp);
+ if (exp.ex_flags & NFSEXP_PNFS)
+ nfsd4_setup_layout_type(&exp);
}
expp = svc_export_lookup(&exp);
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 6b6f55ae0472d..c2d435c99bf5e 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -2,7 +2,6 @@
/*
* Copyright (c) 2014 Christoph Hellwig.
*/
-#include <linux/blkdev.h>
#include <linux/exportfs_block.h>
#include <linux/kmod.h>
#include <linux/file.h>
@@ -126,28 +125,17 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
void nfsd4_setup_layout_type(struct svc_export *exp)
{
-#if defined(CONFIG_NFSD_BLOCKLAYOUT) || defined(CONFIG_NFSD_SCSILAYOUT)
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
- const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
-#endif
-
- if (!(exp->ex_flags & NFSEXP_PNFS))
- return;
+ expfs_block_layouts_t block_supported = exportfs_layouts_supported(sb);
-#ifdef CONFIG_NFSD_FLEXFILELAYOUT
- exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
-#endif
-#ifdef CONFIG_NFSD_BLOCKLAYOUT
- if (bops && bops->get_uuid && bops->map_blocks && bops->commit_blocks)
+ if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT))
+ exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
+ if (IS_ENABLED(CONFIG_NFSD_BLOCKLAYOUT) &&
+ (block_supported & EXPFS_BLOCK_IN_BAND_ID))
exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
-#endif
-#ifdef CONFIG_NFSD_SCSILAYOUT
- if (bops && bops->map_blocks && bops->commit_blocks &&
- sb->s_bdev &&
- sb->s_bdev->bd_disk->fops->pr_ops &&
- sb->s_bdev->bd_disk->fops->get_unique_id)
+ if (IS_ENABLED(CONFIG_NFSD_SCSILAYOUT) &&
+ (block_supported & EXPFS_BLOCK_OUT_OF_BAND_ID))
exp->ex_layout_types |= 1 << LAYOUT_SCSI;
-#endif
}
void nfsd4_close_layout(struct nfs4_layout_stateid *ls)
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index c685995b69d7e..1b0b739571612 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -13,6 +13,7 @@
#include "xfs_bmap.h"
#include "xfs_iomap.h"
#include "xfs_pnfs.h"
+#include <linux/exportfs_block.h>
/*
* Ensure that we do not have any outstanding pNFS layouts that can be used by
@@ -45,6 +46,17 @@ xfs_break_leased_layouts(
return error;
}
+static expfs_block_layouts_t
+xfs_fs_layouts_supported(
+ struct super_block *sb)
+{
+ expfs_block_layouts_t supported = EXPFS_BLOCK_IN_BAND_ID;
+
+ if (exportfs_bdev_supports_out_of_band_id(sb->s_bdev))
+ supported |= EXPFS_BLOCK_OUT_OF_BAND_ID;
+ return supported;
+}
+
/*
* Get a unique ID including its location so that the client can identify
* the exported device.
@@ -334,6 +346,7 @@ xfs_fs_commit_blocks(
}
const struct exportfs_block_ops xfs_export_block_ops = {
+ .layouts_supported = xfs_fs_layouts_supported,
.get_uuid = xfs_fs_get_uuid,
.map_blocks = xfs_fs_map_blocks,
.commit_blocks = xfs_fs_commit_blocks,
diff --git a/include/linux/exportfs_block.h b/include/linux/exportfs_block.h
index 1f52fea8e4dce..92f990d190bba 100644
--- a/include/linux/exportfs_block.h
+++ b/include/linux/exportfs_block.h
@@ -7,14 +7,36 @@
#ifndef LINUX_EXPORTFS_BLOCK_H
#define LINUX_EXPORTFS_BLOCK_H 1
-#include <linux/types.h>
+#include <linux/blkdev.h>
+#include <linux/exportfs.h>
+#include <linux/fs.h>
struct iattr;
struct inode;
struct iomap;
struct super_block;
+/*
+ * There are the two types of block-style layout support:
+ * - In-band implies a device identified by a unique cookie inside the actual
+ * device address space checked by the ->get_uuid method as used by the pNFS
+ * block layout. This is a bit dangerous and deprecated.
+ * - Out of band implies identification by out of band unique identifiers
+ * specified by the storage protocol, which is much safer and used by the
+ * pNFS SCSI/NVMe layouts.
+ */
+typedef unsigned int __bitwise expfs_block_layouts_t;
+#define EXPFS_BLOCK_FLAG(__bit) \
+ ((__force expfs_block_layouts_t)(1u << __bit))
+#define EXPFS_BLOCK_IN_BAND_ID EXPFS_BLOCK_FLAG(0)
+#define EXPFS_BLOCK_OUT_OF_BAND_ID EXPFS_BLOCK_FLAG(1)
+
struct exportfs_block_ops {
+ /*
+ * Returns the EXPFS_BLOCK_* bitmap of supported layout types.
+ */
+ expfs_block_layouts_t (*layouts_supported)(struct super_block *sb);
+
/*
* Get the in-band device unique signature exposed to clients.
*/
@@ -36,4 +58,32 @@ struct exportfs_block_ops {
int nr_iomaps, struct iattr *iattr);
};
+static inline bool
+exportfs_bdev_supports_out_of_band_id(struct block_device *bdev)
+{
+ return bdev->bd_disk->fops->pr_ops &&
+ bdev->bd_disk->fops->get_unique_id;
+}
+
+#ifdef CONFIG_EXPORTFS_BLOCK_OPS
+static inline expfs_block_layouts_t
+exportfs_layouts_supported(struct super_block *sb)
+{
+ const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
+
+ if (!bops ||
+ !bops->layouts_supported ||
+ WARN_ON_ONCE(!bops->map_blocks) ||
+ WARN_ON_ONCE(!bops->commit_blocks))
+ return 0;
+ return bops->layouts_supported(sb);
+}
+#else
+static inline expfs_block_layouts_t
+exportfs_layouts_supported(struct super_block *sb)
+{
+ return 0;
+}
+#endif /* CONFIG_EXPORTFS_BLOCK_OPS */
+
#endif /* LINUX_EXPORTFS_BLOCK_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.18.y 5/5] nfsd: don't offer flexfiles layouts when NFSv3 isn't being served
2026-11-06 1:53 ` [PATCH 6.18.y 1/5] NFSD/blocklayout: Extract extent mapping from proc_layoutget Sasha Levin
` (2 preceding siblings ...)
2026-11-06 1:53 ` [PATCH 6.18.y 4/5] exportfs,nfsd: rework checking for layout-based block device access support Sasha Levin
@ 2026-11-06 1:53 ` Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-11-06 1:53 UTC (permalink / raw)
To: stable; +Cc: Jeff Layton, Benji Wiebe, Chuck Lever, Sasha Levin
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 5d28b2c920d9d9d3c45b41769342ad785eb372a7 ]
The flexfiles layout driver hands out a deviceinfo that names this server
as an NFSv3 DS (flexfilelayout.c hardcodes da->version = 3). With v3
disabled, the client can't talk to the DS: it loops on v3 NULL calls that
the server answers with PROG_MISMATCH, and I/O hangs in D state.
Skip LAYOUT_FLEX_FILES in nfsd4_setup_layout_type() unless v3 is enabled.
Reported-by: Benji Wiebe <itsme@benjiwiebe.com>
Closes: https://lore.kernel.org/linux-nfs/c734eeb8-8486-4491-bb4d-b9656cbaffbe@app.fastmail.com/
Fixes: 9b9960a0ca47 ("nfsd: Add a super simple flex file server")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260904-pnfs-ff-v1-1-5f502cf25401@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4layouts.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index c2d435c99bf5e..8ec980c69bec5 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -125,10 +125,12 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
void nfsd4_setup_layout_type(struct svc_export *exp)
{
+ struct nfsd_net *nn = net_generic(exp->cd->net, nfsd_net_id);
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
expfs_block_layouts_t block_supported = exportfs_layouts_supported(sb);
- if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT))
+ if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT) &&
+ nfsd_vers(nn, 3, NFSD_TEST))
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
if (IS_ENABLED(CONFIG_NFSD_BLOCKLAYOUT) &&
(block_supported & EXPFS_BLOCK_IN_BAND_ID))
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-06 1:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 18:50 FAILED: patch "[PATCH] nfsd: don't offer flexfiles layouts when NFSv3 isn't being" failed to apply to 6.18-stable tree gregkh
2026-11-06 1:53 ` [PATCH 6.18.y 1/5] NFSD/blocklayout: Extract extent mapping from proc_layoutget Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 2/5] exportfs: Complete kernel-doc for struct export_operations Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 3/5] exportfs: split out the ops for layout-based block device access Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 4/5] exportfs,nfsd: rework checking for layout-based block device access support Sasha Levin
2026-11-06 1:53 ` [PATCH 6.18.y 5/5] nfsd: don't offer flexfiles layouts when NFSv3 isn't being served Sasha Levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.