Am Mi., 18. Juni 2025 um 22:53 Uhr schrieb Christian Brauner <brauner@xxxxxxxxxx>: > > * Add a callback to struct stashed_operations so it's possible to > implement custom behavior for pidfs and allow for it to return errors. > > * Teach stashed_dentry_get() to handle error pointers. > > Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx> Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@xxxxxxxxxxxxx> > --- > fs/internal.h | 3 +++ > fs/libfs.c | 27 ++++++++++++++++++++------- > 2 files changed, 23 insertions(+), 7 deletions(-) > > diff --git a/fs/internal.h b/fs/internal.h > index 393f6c5c24f6..22ba066d1dba 100644 > --- a/fs/internal.h > +++ b/fs/internal.h > @@ -322,12 +322,15 @@ struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns); > struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap); > void mnt_idmap_put(struct mnt_idmap *idmap); > struct stashed_operations { > + struct dentry *(*stash_dentry)(struct dentry **stashed, > + struct dentry *dentry); > void (*put_data)(void *data); > int (*init_inode)(struct inode *inode, void *data); > }; > int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, > struct path *path); > void stashed_dentry_prune(struct dentry *dentry); > +struct dentry *stash_dentry(struct dentry **stashed, struct dentry *dentry); > struct dentry *stashed_dentry_get(struct dentry **stashed); > /** > * path_mounted - check whether path is mounted > diff --git a/fs/libfs.c b/fs/libfs.c > index 9ea0ecc325a8..3541e22c87b5 100644 > --- a/fs/libfs.c > +++ b/fs/libfs.c > @@ -2128,6 +2128,8 @@ struct dentry *stashed_dentry_get(struct dentry **stashed) > dentry = rcu_dereference(*stashed); > if (!dentry) > return NULL; > + if (IS_ERR(dentry)) > + return dentry; > if (!lockref_get_not_dead(&dentry->d_lockref)) > return NULL; > return dentry; > @@ -2176,8 +2178,7 @@ static struct dentry *prepare_anon_dentry(struct dentry **stashed, > return dentry; > } > > -static struct dentry *stash_dentry(struct dentry **stashed, > - struct dentry *dentry) > +struct dentry *stash_dentry(struct dentry **stashed, struct dentry *dentry) > { > guard(rcu)(); > for (;;) { > @@ -2218,12 +2219,15 @@ static struct dentry *stash_dentry(struct dentry **stashed, > int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, > struct path *path) > { > - struct dentry *dentry; > + struct dentry *dentry, *res; > const struct stashed_operations *sops = mnt->mnt_sb->s_fs_info; > > /* See if dentry can be reused. */ > - path->dentry = stashed_dentry_get(stashed); > - if (path->dentry) { > + res = stashed_dentry_get(stashed); > + if (IS_ERR(res)) > + return PTR_ERR(res); > + if (res) { > + path->dentry = res; > sops->put_data(data); > goto out_path; > } > @@ -2234,8 +2238,17 @@ int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, > return PTR_ERR(dentry); > > /* Added a new dentry. @data is now owned by the filesystem. */ > - path->dentry = stash_dentry(stashed, dentry); > - if (path->dentry != dentry) > + if (sops->stash_dentry) > + res = sops->stash_dentry(stashed, dentry); > + else > + res = stash_dentry(stashed, dentry); > + if (IS_ERR(res)) { > + dput(dentry); > + return PTR_ERR(res); > + } > + path->dentry = res; > + /* A dentry was reused. */ > + if (res != dentry) > dput(dentry); > > out_path: > > -- > 2.47.2 >