[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250822000818.1086550-10-neil@brown.name>
Date: Fri, 22 Aug 2025 10:00:27 +1000
From: NeilBrown <neil@...wn.name>
To: Alexander Viro <viro@...iv.linux.org.uk>,
Christian Brauner <brauner@...nel.org>
Cc: Jan Kara <jack@...e.cz>,
linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH v2 09/16] VFS: introduce simple_end_creating() and simple_failed_creating()
These are partners of simple_start_creating().
On failure we don't keep a reference. On success we do.
Use these where simple_start_creating() is used, in debugfs, tracefs,
and rpcpipefs.
Also rename start_creating, end_creating, failed_creating in debugfs to
free up these generic names for more generic use.
I put the declarations in namei.h to have access to end_dirop() but they
really below with the other simple_ function declaration. Possibly
these should be moved out of fs.h into a separate libfs.h which could
include namei.h
Signed-off-by: NeilBrown <neil@...wn.name>
---
fs/debugfs/inode.c | 43 +++++++++++++++++++++----------------------
fs/tracefs/inode.c | 6 ++----
include/linux/namei.h | 16 ++++++++++++++++
net/sunrpc/rpc_pipe.c | 11 ++++-------
4 files changed, 43 insertions(+), 33 deletions(-)
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index a0357b0cf362..9525618ccad1 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -353,7 +353,8 @@ struct dentry *debugfs_lookup(const char *name, struct dentry *parent)
}
EXPORT_SYMBOL_GPL(debugfs_lookup);
-static struct dentry *start_creating(const char *name, struct dentry *parent)
+static struct dentry *debugfs_start_creating(const char *name,
+ struct dentry *parent)
{
struct dentry *dentry;
int error;
@@ -393,18 +394,16 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
return dentry;
}
-static struct dentry *failed_creating(struct dentry *dentry)
+static struct dentry *debugfs_failed_creating(struct dentry *dentry)
{
- inode_unlock(d_inode(dentry->d_parent));
- dput(dentry);
+ simple_failed_creating(dentry);
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
return ERR_PTR(-ENOMEM);
}
-static struct dentry *end_creating(struct dentry *dentry)
+static struct dentry *debugfs_end_creating(struct dentry *dentry)
{
- inode_unlock(d_inode(dentry->d_parent));
- return dentry;
+ return simple_end_creating(dentry);
}
static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
@@ -419,13 +418,13 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
if (!(mode & S_IFMT))
mode |= S_IFREG;
BUG_ON(!S_ISREG(mode));
- dentry = start_creating(name, parent);
+ dentry = debugfs_start_creating(name, parent);
if (IS_ERR(dentry))
return dentry;
if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
- failed_creating(dentry);
+ debugfs_failed_creating(dentry);
return ERR_PTR(-EPERM);
}
@@ -433,7 +432,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
if (unlikely(!inode)) {
pr_err("out of free dentries, can not create file '%s'\n",
name);
- return failed_creating(dentry);
+ return debugfs_failed_creating(dentry);
}
inode->i_mode = mode;
@@ -448,7 +447,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
d_instantiate(dentry, inode);
fsnotify_create(d_inode(dentry->d_parent), dentry);
- return end_creating(dentry);
+ return debugfs_end_creating(dentry);
}
struct dentry *debugfs_create_file_full(const char *name, umode_t mode,
@@ -568,14 +567,14 @@ EXPORT_SYMBOL_GPL(debugfs_create_file_size);
*/
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
{
- struct dentry *dentry = start_creating(name, parent);
+ struct dentry *dentry = debugfs_start_creating(name, parent);
struct inode *inode;
if (IS_ERR(dentry))
return dentry;
if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
- failed_creating(dentry);
+ debugfs_failed_creating(dentry);
return ERR_PTR(-EPERM);
}
@@ -583,7 +582,7 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
if (unlikely(!inode)) {
pr_err("out of free dentries, can not create directory '%s'\n",
name);
- return failed_creating(dentry);
+ return debugfs_failed_creating(dentry);
}
inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
@@ -595,7 +594,7 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
d_instantiate(dentry, inode);
inc_nlink(d_inode(dentry->d_parent));
fsnotify_mkdir(d_inode(dentry->d_parent), dentry);
- return end_creating(dentry);
+ return debugfs_end_creating(dentry);
}
EXPORT_SYMBOL_GPL(debugfs_create_dir);
@@ -615,14 +614,14 @@ struct dentry *debugfs_create_automount(const char *name,
debugfs_automount_t f,
void *data)
{
- struct dentry *dentry = start_creating(name, parent);
+ struct dentry *dentry = debugfs_start_creating(name, parent);
struct inode *inode;
if (IS_ERR(dentry))
return dentry;
if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
- failed_creating(dentry);
+ debugfs_failed_creating(dentry);
return ERR_PTR(-EPERM);
}
@@ -630,7 +629,7 @@ struct dentry *debugfs_create_automount(const char *name,
if (unlikely(!inode)) {
pr_err("out of free dentries, can not create automount '%s'\n",
name);
- return failed_creating(dentry);
+ return debugfs_failed_creating(dentry);
}
make_empty_dir_inode(inode);
@@ -642,7 +641,7 @@ struct dentry *debugfs_create_automount(const char *name,
d_instantiate(dentry, inode);
inc_nlink(d_inode(dentry->d_parent));
fsnotify_mkdir(d_inode(dentry->d_parent), dentry);
- return end_creating(dentry);
+ return debugfs_end_creating(dentry);
}
EXPORT_SYMBOL(debugfs_create_automount);
@@ -678,7 +677,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
if (!link)
return ERR_PTR(-ENOMEM);
- dentry = start_creating(name, parent);
+ dentry = debugfs_start_creating(name, parent);
if (IS_ERR(dentry)) {
kfree(link);
return dentry;
@@ -689,13 +688,13 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
pr_err("out of free dentries, can not create symlink '%s'\n",
name);
kfree(link);
- return failed_creating(dentry);
+ return debugfs_failed_creating(dentry);
}
inode->i_mode = S_IFLNK | S_IRWXUGO;
inode->i_op = &debugfs_symlink_inode_operations;
inode->i_link = link;
d_instantiate(dentry, inode);
- return end_creating(dentry);
+ return debugfs_end_creating(dentry);
}
EXPORT_SYMBOL_GPL(debugfs_create_symlink);
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 0c023941a316..320d7f25024b 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -571,16 +571,14 @@ struct dentry *tracefs_start_creating(const char *name, struct dentry *parent)
struct dentry *tracefs_failed_creating(struct dentry *dentry)
{
- inode_unlock(d_inode(dentry->d_parent));
- dput(dentry);
+ simple_failed_creating(dentry);
simple_release_fs(&tracefs_mount, &tracefs_mount_count);
return NULL;
}
struct dentry *tracefs_end_creating(struct dentry *dentry)
{
- inode_unlock(d_inode(dentry->d_parent));
- return dentry;
+ return simple_end_creating(dentry);
}
/* Find the inode that this will use for default */
diff --git a/include/linux/namei.h b/include/linux/namei.h
index bd0cba118540..b1171aa7fb96 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -84,6 +84,22 @@ struct dentry *lookup_one_positive_unlocked(struct mnt_idmap *idmap,
void end_dirop(struct dentry *de);
void end_dirop_mkdir(struct dentry *de, struct dentry *parent);
+/* filesystems which use the dcache as backing store don't
+ * keep a reference after creating an object.
+ */
+static inline struct dentry *simple_end_creating(struct dentry *dentry)
+{
+ dget(dentry);
+ end_dirop(dentry);
+ return dentry;
+}
+
+/* On failure, the don't keep a reference */
+static inline void simple_failed_creating(struct dentry *dentry)
+{
+ end_dirop(dentry);
+}
+
extern int follow_down_one(struct path *);
extern int follow_down(struct path *path, unsigned int flags);
extern int follow_up(struct path *);
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 0bd1df2ebb47..38c26909235d 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -536,8 +536,7 @@ static int rpc_new_file(struct dentry *parent,
inode = rpc_get_inode(dir->i_sb, S_IFREG | mode);
if (unlikely(!inode)) {
- dput(dentry);
- inode_unlock(dir);
+ simple_failed_creating(dentry);
return -ENOMEM;
}
inode->i_ino = iunique(dir->i_sb, 100);
@@ -546,7 +545,7 @@ static int rpc_new_file(struct dentry *parent,
rpc_inode_setowner(inode, private);
d_instantiate(dentry, inode);
fsnotify_create(dir, dentry);
- inode_unlock(dir);
+ simple_end_creating(dentry);
return 0;
}
@@ -572,9 +571,8 @@ static struct dentry *rpc_new_dir(struct dentry *parent,
inc_nlink(dir);
d_instantiate(dentry, inode);
fsnotify_mkdir(dir, dentry);
- inode_unlock(dir);
- return dentry;
+ return simple_end_creating(dentry);
}
static int rpc_populate(struct dentry *parent,
@@ -669,9 +667,8 @@ int rpc_mkpipe_dentry(struct dentry *parent, const char *name,
rpci->pipe = pipe;
rpc_inode_setowner(inode, private);
d_instantiate(dentry, inode);
- pipe->dentry = dentry;
fsnotify_create(dir, dentry);
- inode_unlock(dir);
+ pipe->dentry = simple_end_creating(dentry);
return 0;
failed:
--
2.50.0.107.gf914562f5916.dirty
Powered by blists - more mailing lists