[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <176169811268.1426070.2874269137574030621.stgit@frogsfrogsfrogs>
Date: Tue, 28 Oct 2025 17:53:17 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: djwong@...nel.org, miklos@...redi.hu
Cc: joannelkoong@...il.com, bernd@...ernd.com, neal@...pa.dev,
linux-ext4@...r.kernel.org, linux-fsdevel@...r.kernel.org
Subject: [PATCH 1/3] fuse: make the root nodeid dynamic
From: Darrick J. Wong <djwong@...nel.org>
Change this from a hardcoded constant to a dynamic field so that fuse
servers don't need to translate.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
fs/fuse/fuse_i.h | 7 +++++--
fs/fuse/dir.c | 10 ++++++----
fs/fuse/inode.c | 11 +++++++----
fs/fuse/readdir.c | 10 +++++-----
4 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 9ab1de8063c05e..4157dba6cba27c 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -690,6 +690,9 @@ struct fuse_conn {
struct rcu_head rcu;
+ /* node id of the root directory */
+ u64 root_nodeid;
+
/** The user id for this mount */
kuid_t user_id;
@@ -1118,9 +1121,9 @@ static inline u64 get_node_id(struct inode *inode)
return get_fuse_inode(inode)->nodeid;
}
-static inline int invalid_nodeid(u64 nodeid)
+static inline int invalid_nodeid(const struct fuse_conn *fc, u64 nodeid)
{
- return !nodeid || nodeid == FUSE_ROOT_ID;
+ return !nodeid || nodeid == fc->root_nodeid;
}
static inline u64 fuse_get_attr_version(struct fuse_conn *fc)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c35ddd5070225c..bd0d37a513b42d 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -386,7 +386,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
err = -EIO;
if (fuse_invalid_attr(&outarg->attr))
goto out_put_forget;
- if (outarg->nodeid == FUSE_ROOT_ID && outarg->generation != 0) {
+ if (outarg->nodeid == fm->fc->root_nodeid && outarg->generation != 0) {
pr_warn_once("root generation should be zero\n");
outarg->generation = 0;
}
@@ -436,7 +436,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
goto out_err;
err = -EIO;
- if (inode && get_node_id(inode) == FUSE_ROOT_ID)
+ if (inode && get_node_id(inode) == fc->root_nodeid)
goto out_iput;
newent = d_splice_alias(inode, entry);
@@ -687,7 +687,8 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
goto out_free_ff;
err = -EIO;
- if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
+ if (!S_ISREG(outentry.attr.mode) ||
+ invalid_nodeid(fm->fc, outentry.nodeid) ||
fuse_invalid_attr(&outentry.attr))
goto out_free_ff;
@@ -831,7 +832,8 @@ static struct dentry *create_new_entry(struct mnt_idmap *idmap, struct fuse_moun
goto out_put_forget_req;
err = -EIO;
- if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
+ if (invalid_nodeid(fm->fc, outarg.nodeid) ||
+ fuse_invalid_attr(&outarg.attr))
goto out_put_forget_req;
if ((outarg.attr.mode ^ mode) & S_IFMT)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index d41a6e418537b5..5f0c7032e691a6 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1018,6 +1018,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
fc->max_pages_limit = fuse_max_pages_limit;
fc->name_max = FUSE_NAME_LOW_MAX;
fc->timeout.req_timeout = 0;
+ fc->root_nodeid = FUSE_ROOT_ID;
if (IS_ENABLED(CONFIG_FUSE_BACKING))
fuse_backing_files_init(fc);
@@ -1073,12 +1074,14 @@ EXPORT_SYMBOL_GPL(fuse_conn_get);
static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned int mode)
{
struct fuse_attr attr;
+ struct fuse_conn *fc = get_fuse_conn_super(sb);
+
memset(&attr, 0, sizeof(attr));
attr.mode = mode;
- attr.ino = FUSE_ROOT_ID;
+ attr.ino = fc->root_nodeid;
attr.nlink = 1;
- return fuse_iget(sb, FUSE_ROOT_ID, 0, &attr, 0, 0, 0);
+ return fuse_iget(sb, fc->root_nodeid, 0, &attr, 0, 0, 0);
}
struct fuse_inode_handle {
@@ -1122,7 +1125,7 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
goto out_iput;
entry = d_obtain_alias(inode);
- if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID)
+ if (!IS_ERR(entry) && get_node_id(inode) != fc->root_nodeid)
fuse_invalidate_entry_cache(entry);
return entry;
@@ -1215,7 +1218,7 @@ static struct dentry *fuse_get_parent(struct dentry *child)
}
parent = d_obtain_alias(inode);
- if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID)
+ if (!IS_ERR(parent) && get_node_id(inode) != fc->root_nodeid)
fuse_invalidate_entry_cache(parent);
return parent;
diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c
index c2aae2eef0868b..45dd932eb03a5e 100644
--- a/fs/fuse/readdir.c
+++ b/fs/fuse/readdir.c
@@ -185,12 +185,12 @@ static int fuse_direntplus_link(struct file *file,
return 0;
}
- if (invalid_nodeid(o->nodeid))
- return -EIO;
- if (fuse_invalid_attr(&o->attr))
- return -EIO;
-
fc = get_fuse_conn(dir);
+ if (invalid_nodeid(fc, o->nodeid))
+ return -EIO;
+ if (fuse_invalid_attr(&o->attr))
+ return -EIO;
+
epoch = atomic_read(&fc->epoch);
name.hash = full_name_hash(parent, name.name, name.len);
Powered by blists - more mailing lists