Re: [PATCH v5 14/14] VFS: introduce end_creating_keep()
Jeff Layton <[email protected]>
| Newsgroups | org.kernel.vger.ecryptfs,dev.linux.lists.netfs,org.kernel.vger.linux-cifs,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-nfs,org.kernel.vger.linux-security-module,org.kernel.vger.linux-unionfs,org.kernel.vger.linux-xfs,org.kernel.vger.selinux |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 2025-11-06 at 11:50 +1100, NeilBrown wrote: > From: NeilBrown <[email protected]> > > Occasionally the caller of end_creating() wants to keep using the dentry. > Rather then requiring them to dget() the dentry (when not an error) > before calling end_creating(), provide end_creating_keep() which does > this. > > cachefiles and overlayfs make use of this. > > Reviewed-by: Amir Goldstein <[email protected]> > Signed-off-by: NeilBrown <[email protected]> > --- > fs/cachefiles/namei.c | 3 +-- > fs/overlayfs/dir.c | 8 ++------ > fs/overlayfs/super.c | 11 +++-------- > include/linux/namei.h | 22 ++++++++++++++++++++++ > 4 files changed, 28 insertions(+), 16 deletions(-) > > diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c > index 59327618ac42..ef22ac19545b 100644 > --- a/fs/cachefiles/namei.c > +++ b/fs/cachefiles/namei.c > @@ -155,8 +155,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, > > /* Tell rmdir() it's not allowed to delete the subdir */ > inode_lock(d_inode(subdir)); > - dget(subdir); > - end_creating(subdir); > + end_creating_keep(subdir); > > if (!__cachefiles_mark_inode_in_use(NULL, d_inode(subdir))) { > pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n", > diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c > index a4a0dc261310..50717ff8cac7 100644 > --- a/fs/overlayfs/dir.c > +++ b/fs/overlayfs/dir.c > @@ -252,10 +252,7 @@ struct dentry *ovl_create_temp(struct ovl_fs *ofs, struct dentry *workdir, > if (IS_ERR(ret)) > return ret; > ret = ovl_create_real(ofs, workdir, ret, attr); > - if (!IS_ERR(ret)) > - dget(ret); > - end_creating(ret); > - return ret; > + return end_creating_keep(ret); > } > > static int ovl_set_opaque_xerr(struct dentry *dentry, struct dentry *upper, > @@ -365,8 +362,7 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, > if (IS_ERR(newdentry)) > return PTR_ERR(newdentry); > > - dget(newdentry); > - end_creating(newdentry); > + end_creating_keep(newdentry); > > if (ovl_type_merge(dentry->d_parent) && d_is_dir(newdentry) && > !ovl_allow_offline_changes(ofs)) { > diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c > index 3acda985c8a3..7b8fc1cab6eb 100644 > --- a/fs/overlayfs/super.c > +++ b/fs/overlayfs/super.c > @@ -319,8 +319,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, > }; > > if (work->d_inode) { > - dget(work); > - end_creating(work); > + end_creating_keep(work); > if (persist) > return work; > err = -EEXIST; > @@ -336,9 +335,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, > } > > work = ovl_do_mkdir(ofs, dir, work, attr.ia_mode); > - if (!IS_ERR(work)) > - dget(work); > - end_creating(work); > + end_creating_keep(work); > err = PTR_ERR(work); > if (IS_ERR(work)) > goto out_err; > @@ -630,9 +627,7 @@ static struct dentry *ovl_lookup_or_create(struct ovl_fs *ofs, > if (!child->d_inode) > child = ovl_create_real(ofs, parent, child, > OVL_CATTR(mode)); > - if (!IS_ERR(child)) > - dget(child); > - end_creating(child); > + end_creating_keep(child); > } > dput(parent); > > diff --git a/include/linux/namei.h b/include/linux/namei.h > index b4d95b79b5a8..58600cf234bc 100644 > --- a/include/linux/namei.h > +++ b/include/linux/namei.h > @@ -126,6 +126,28 @@ static inline void end_creating(struct dentry *child) > end_dirop(child); > } > > +/* end_creating_keep - finish action started with start_creating() and return result > + * @child: dentry returned by start_creating() or vfs_mkdir() > + * > + * Unlock and return the child. This can be called after > + * start_creating() whether that function succeeded or not, > + * but it is not needed on failure. > + * > + * If vfs_mkdir() was called then the value returned from that function > + * should be given for @child rather than the original dentry, as vfs_mkdir() > + * may have provided a new dentry. > + * > + * Returns: @child, which may be a dentry or an error. > + * > + */ > +static inline struct dentry *end_creating_keep(struct dentry *child) > +{ > + if (!IS_ERR(child)) > + dget(child); > + end_dirop(child); > + return child; > +} > + > /** > * end_removing - finish action started with start_removing > * @child: dentry returned by start_removing() Reviewed-by: Jeff Layton <[email protected]>