[PATCH 1/2] nvmet: avoid recursive configfs open for file-backed namespaces
From: Runyu Xiao
Date: Mon Aug 17 2026 - 10:50:11 EST
nvmet_ns_enable_store() runs as a configfs store callback while configfs
holds the item's frag_sem. For file-backed namespaces, nvmet_ns_enable()
calls nvmet_file_ns_enable(), which uses filp_open() on the
user-supplied device_path.
If device_path points back into configfs, the open path re-enters
__configfs_open_file() and tries to take the same frag_sem again.
Resolve the path with kern_path(), reject configfs paths, and open the
resolved path with dentry_open() instead of filp_open(). This keeps
valid block-device and regular-file backends working without
re-entering configfs.
Fixes: d5eff33ee6f8 ("nvmet: add simple file backed ns support")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
drivers/nvme/target/io-cmd-file.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
index 2d068439b129..6d653519327a 100644
--- a/drivers/nvme/target/io-cmd-file.c
+++ b/drivers/nvme/target/io-cmd-file.c
@@ -9,6 +9,7 @@
#include <linux/falloc.h>
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/namei.h>
#include "nvmet.h"
#define NVMET_MIN_MPOOL_OBJ 16
@@ -33,12 +34,28 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns)
int nvmet_file_ns_enable(struct nvmet_ns *ns)
{
int flags = O_RDWR | O_LARGEFILE;
+ struct path path;
int ret = 0;
if (!ns->buffered_io)
flags |= O_DIRECT;
- ns->file = filp_open(ns->device_path, flags, 0);
+ ret = kern_path(ns->device_path, LOOKUP_FOLLOW, &path);
+ if (ret) {
+ pr_err("failed to open file %s: (%d)\n",
+ ns->device_path, ret);
+ return ret;
+ }
+
+ if (!strcmp(path.dentry->d_sb->s_type->name, "configfs")) {
+ pr_err("configfs paths cannot back namespace %s\n",
+ ns->device_path);
+ path_put(&path);
+ return -EINVAL;
+ }
+
+ ns->file = dentry_open(&path, flags, current_cred());
+ path_put(&path);
if (IS_ERR(ns->file)) {
ret = PTR_ERR(ns->file);
pr_err("failed to open file %s: (%d)\n",
--
2.34.1