[PATCH v3 2/3] nvmet: avoid recursive configfs open for file-backed namespaces
From: Runyu Xiao
Date: Thu Sep 10 2026 - 00:56:55 EST
nvmet_ns_enable_store() runs as a configfs store callback while configfs
holds the item's frag_sem. A file-backed namespace then opens the
configured device_path with filp_open(). If the path resolves into
configfs, the open path re-enters __configfs_open_file() and attempts to
acquire the same frag_sem again.
Resolve the configured path first, reject paths resolved on configfs, and
open the resolved path with file_open_root(). This preserves the standard
open-time permission checks without performing a second pathname walk. Use
the configfs helper for the filesystem type check so this caller shares the
classification with other configfs users.
Fixes: d5eff33ee6f8 ("nvmet: add simple file backed ns support")
Cc: stable@xxxxxxxxxxxxxxx
Reviewed-by: Sagi Grimberg <sagi@xxxxxxxxxxx>
Assisted-by: LLM Codex
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
drivers/nvme/target/io-cmd-file.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
index 0b22d183f..fbe58aa4a 100644
--- a/drivers/nvme/target/io-cmd-file.c
+++ b/drivers/nvme/target/io-cmd-file.c
@@ -8,7 +8,9 @@
#include <linux/uio.h>
#include <linux/falloc.h>
#include <linux/file.h>
+#include <linux/configfs.h>
#include <linux/fs.h>
+#include <linux/namei.h>
#include "nvmet.h"
#define NVMET_MIN_MPOOL_OBJ 16
@@ -33,12 +35,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 (configfs_path_is_configfs(&path)) {
+ pr_err("configfs paths cannot back namespace %s\n",
+ ns->device_path);
+ path_put(&path);
+ return -EINVAL;
+ }
+
+ ns->file = file_open_root(&path, "", flags, 0);
+ 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