[RFC PATCH 1/6] fs/9p: Add ability to identify inode by path for .L
Tingmao Wang
m at maowtm.org
Fri Jul 11 19:11:54 UTC 2025
On 4/6/25 21:43, Tingmao Wang wrote:
> [...]
>
> +struct iget_data {
> + struct p9_stat_dotl *st;
> + struct dentry *dentry;
> +};
> +
> static int v9fs_test_inode_dotl(struct inode *inode, void *data)
> {
> struct v9fs_inode *v9inode = V9FS_I(inode);
> - struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
> + struct p9_stat_dotl *st = ((struct iget_data *)data)->st;
> + struct dentry *dentry = ((struct iget_data *)data)->dentry;
> + struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
>
> /* don't match inode of different type */
> if (inode_wrong_type(inode, st->st_mode))
> @@ -74,22 +81,74 @@ static int v9fs_test_inode_dotl(struct inode *inode, void *data)
>
> if (v9inode->qid.path != st->qid.path)
> return 0;
> +
> + if (v9fs_inode_ident_path(v9ses)) {
> + if (!ino_path_compare(v9inode->path, dentry)) {
> + p9_debug(P9_DEBUG_VFS, "Refusing to reuse inode %p based on path mismatch",
> + inode);
> + return 0;
> + }
> + }
> return 1;
> }
>
> /* Always get a new inode */> static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
Looking back, this function should probably be renamed to something like
"v9fs_test_inode_uncached" since it now no longer "always get a new
inode".
Actually, maybe this should be merged with v9fs_test_inode_dotl - the
behavior is basically the same when inodeident=path is enabled. Maybe the
approach could be that v9fs always re-use inodes (as long as qid matches,
and when inodeident=path, the path matches as well), but if in uncached
mode, it will also always refresh metadata? (Basically inodes has to be
re-used, even in uncached mode, for Landlock and Fanotify using inode
marks to work)
Doing so does mean that if one sets inodeident=none, in a pathological
9pfs where different file/dirs have same qids, the inode will mistakenly
be re-used (like before be2ca38253 (Revert "fs/9p: simplify iget to remove
unnecessary paths")), but given that the user has specifically set
inodeident=none (i.e. not the default as proposed in this patch), I wonder
if this is acceptable behaviour?
> {
> + struct v9fs_inode *v9inode = V9FS_I(inode);
> + struct p9_stat_dotl *st = ((struct iget_data *)data)->st;
> + struct dentry *dentry = ((struct iget_data *)data)->dentry;
> + struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
> +
> + /*
> + * Don't reuse inode of different type, even if we have
> + * inodeident=path and path matches.
> + */
> + if (inode_wrong_type(inode, st->st_mode))
> + return 0;
> +
> + /*
> + * We're only getting here if QID2INO stays the same anyway, so
> + * mirroring the qid checks in v9fs_test_inode_dotl
> + * (but maybe that check is unnecessary anyway? at least on 64bit)
> + */
> +
> + if (v9inode->qid.type != st->qid.type)
> + return 0;
> +
> + if (v9inode->qid.path != st->qid.path)
> + return 0;
> +
> + if (v9fs_inode_ident_path(v9ses) && dentry && v9inode->path) {
> + if (ino_path_compare(V9FS_I(inode)->path, dentry)) {
> + p9_debug(P9_DEBUG_VFS,
> + "Reusing inode %p based on path match", inode);
> + return 1;
> + }
> + }
> +
> return 0;
> }
>
> static int v9fs_set_inode_dotl(struct inode *inode, void *data)
> {
> struct v9fs_inode *v9inode = V9FS_I(inode);
> - struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
> + struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
> + struct iget_data *idata = data;
> + struct p9_stat_dotl *st = idata->st;
> + struct dentry *dentry = idata->dentry;
>
> memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
> inode->i_generation = st->st_gen;
> + if (v9fs_inode_ident_path(v9ses)) {
> + if (dentry) {
> + v9inode->path = make_ino_path(dentry);
> + if (!v9inode->path)
> + return -ENOMEM;
> + } else {
> + v9inode->path = NULL;
> + }
> + }
I realized that this leaves v9inode->path uninitialized if
inodeident=none. The proper way is
v9inode->path = NULL;
if (v9fs_inode_ident_path(v9ses) && dentry) {
v9inode->path = make_ino_path(dentry);
if (!v9inode->path)
return -ENOMEM;
}
Same change applies for the non-.L version.
> return 0;
> }
>
> [...]
More information about the Linux-security-module-archive
mailing list