Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

libfs: massage path_from_stashed() to allow custom stashing behavior

* 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.

Link: https://lore.kernel.org/20250618-work-pidfs-persistent-v2-2-98f3456fd552@kernel.org
Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

+23 -7
+3
fs/internal.h
··· 322 322 struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap); 323 323 void mnt_idmap_put(struct mnt_idmap *idmap); 324 324 struct stashed_operations { 325 + struct dentry *(*stash_dentry)(struct dentry **stashed, 326 + struct dentry *dentry); 325 327 void (*put_data)(void *data); 326 328 int (*init_inode)(struct inode *inode, void *data); 327 329 }; 328 330 int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, 329 331 struct path *path); 330 332 void stashed_dentry_prune(struct dentry *dentry); 333 + struct dentry *stash_dentry(struct dentry **stashed, struct dentry *dentry); 331 334 struct dentry *stashed_dentry_get(struct dentry **stashed); 332 335 /** 333 336 * path_mounted - check whether path is mounted
+20 -7
fs/libfs.c
··· 2128 2128 dentry = rcu_dereference(*stashed); 2129 2129 if (!dentry) 2130 2130 return NULL; 2131 + if (IS_ERR(dentry)) 2132 + return dentry; 2131 2133 if (!lockref_get_not_dead(&dentry->d_lockref)) 2132 2134 return NULL; 2133 2135 return dentry; ··· 2178 2176 return dentry; 2179 2177 } 2180 2178 2181 - static struct dentry *stash_dentry(struct dentry **stashed, 2182 - struct dentry *dentry) 2179 + struct dentry *stash_dentry(struct dentry **stashed, struct dentry *dentry) 2183 2180 { 2184 2181 guard(rcu)(); 2185 2182 for (;;) { ··· 2219 2218 int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, 2220 2219 struct path *path) 2221 2220 { 2222 - struct dentry *dentry; 2221 + struct dentry *dentry, *res; 2223 2222 const struct stashed_operations *sops = mnt->mnt_sb->s_fs_info; 2224 2223 2225 2224 /* See if dentry can be reused. */ 2226 - path->dentry = stashed_dentry_get(stashed); 2227 - if (path->dentry) { 2225 + res = stashed_dentry_get(stashed); 2226 + if (IS_ERR(res)) 2227 + return PTR_ERR(res); 2228 + if (res) { 2229 + path->dentry = res; 2228 2230 sops->put_data(data); 2229 2231 goto out_path; 2230 2232 } ··· 2238 2234 return PTR_ERR(dentry); 2239 2235 2240 2236 /* Added a new dentry. @data is now owned by the filesystem. */ 2241 - path->dentry = stash_dentry(stashed, dentry); 2242 - if (path->dentry != dentry) 2237 + if (sops->stash_dentry) 2238 + res = sops->stash_dentry(stashed, dentry); 2239 + else 2240 + res = stash_dentry(stashed, dentry); 2241 + if (IS_ERR(res)) { 2242 + dput(dentry); 2243 + return PTR_ERR(res); 2244 + } 2245 + path->dentry = res; 2246 + /* A dentry was reused. */ 2247 + if (res != dentry) 2243 2248 dput(dentry); 2244 2249 2245 2250 out_path: