Skip to content

Commit

Permalink
Revert "fs/9p: search open fids first"
Browse files Browse the repository at this point in the history
commit 22e424f upstream.

This reverts commit 478ba09.

That commit was meant as a fix for setattrs with by fd (e.g. ftruncate)
to use an open fid instead of the first fid it found on lookup.
The proper fix for that is to use the fid associated with the open file
struct, available in iattr->ia_file for such operations, and was
actually done just before in 6624664 ("9p: retrieve fid from file
when file instance exist.")
As such, this commit is no longer required.

Furthermore, changing lookup to return open fids first had unwanted side
effects, as it turns out the protocol forbids the use of open fids for
further walks (e.g. clone_fid) and we broke mounts for some servers
enforcing this rule.

Note this only reverts to the old working behaviour, but it's still
possible for lookup to return open fids if dentry->d_fsdata is not set,
so more work is needed to make sure we respect this rule in the future,
for example by adding a flag to the lookup functions to only match
certain fid open modes depending on caller requirements.

Link: https://lkml.kernel.org/r/20220130130651.712293-1-asmadeus@codewreck.org
Fixes: 478ba09 ("fs/9p: search open fids first")
Cc: stable@vger.kernel.org # v5.11+
Reported-by: ron minnich <rminnich@gmail.com>
Reported-by: ng@0x80.stream
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
martinetd authored and gregkh committed Feb 8, 2022
1 parent a7b717f commit b9e9f84
Showing 1 changed file with 4 additions and 5 deletions.
9 changes: 4 additions & 5 deletions fs/9p/fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,8 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
dentry, dentry, from_kuid(&init_user_ns, uid),
any);
ret = NULL;

if (d_inode(dentry))
ret = v9fs_fid_find_inode(d_inode(dentry), uid);

/* we'll recheck under lock if there's anything to look in */
if (!ret && dentry->d_fsdata) {
if (dentry->d_fsdata) {
struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
spin_lock(&dentry->d_lock);
hlist_for_each_entry(fid, h, dlist) {
Expand All @@ -112,6 +108,9 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
}
}
spin_unlock(&dentry->d_lock);
} else {
if (dentry->d_inode)
ret = v9fs_fid_find_inode(dentry->d_inode, uid);
}

return ret;
Expand Down

0 comments on commit b9e9f84

Please sign in to comment.