^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * V9FS FID Management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/9p/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/9p/client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "v9fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "v9fs_vfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "fid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * v9fs_fid_add - add a fid to a dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @dentry: dentry that the fid is being added to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * @fid: fid to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) __add_fid(dentry, fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * v9fs_fid_find - retrieve a fid that belongs to the specified uid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @dentry: dentry to look for fid in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @uid: return fid that belongs to the specified user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @any: if non-zero, return any fid associated with the dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct p9_fid *fid, *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p) uid %d any %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) dentry, dentry, from_kuid(&init_user_ns, uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* we'll recheck under lock if there's anything to look in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (dentry->d_fsdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) hlist_for_each_entry(fid, h, dlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (any || uid_eq(fid->uid, uid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ret = fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * We need to hold v9ses->rename_sem as long as we hold references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * to returned path array. Array element contain pointers to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * dentry names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int build_path_from_dentry(struct v9fs_session_info *v9ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct dentry *dentry, const unsigned char ***names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int n = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) const unsigned char **wnames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct dentry *ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) wnames = kmalloc_array(n, sizeof(char *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!wnames)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) for (ds = dentry, i = (n-1); i >= 0; i--, ds = ds->d_parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) wnames[i] = ds->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *names = wnames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) kuid_t uid, int any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct dentry *ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const unsigned char **wnames, *uname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int i, n, l, clone, access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct v9fs_session_info *v9ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct p9_fid *fid, *old_fid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) v9ses = v9fs_dentry2v9ses(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) access = v9ses->flags & V9FS_ACCESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) fid = v9fs_fid_find(dentry, uid, any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * we don't have a matching fid. To do a TWALK we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * parent fid. We need to prevent rename when we want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * look at the parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) down_read(&v9ses->rename_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ds = dentry->d_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) fid = v9fs_fid_find(ds, uid, any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Found the parent fid do a lookup with that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) fid = p9_client_walk(fid, 1, &dentry->d_name.name, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) goto fid_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) up_read(&v9ses->rename_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* start from the root and try to do a lookup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* the user is not attached to the fs yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (access == V9FS_ACCESS_SINGLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return ERR_PTR(-EPERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) uname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) uname = v9ses->uname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) fid = p9_client_attach(v9ses->clnt, NULL, uname, uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) v9ses->aname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (IS_ERR(fid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) v9fs_fid_add(dentry->d_sb->s_root, fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* If we are root ourself just return that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (dentry->d_sb->s_root == dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * Do a multipath walk with attached root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * When walking parent we need to make sure we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * don't have a parallel rename happening
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) down_read(&v9ses->rename_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) n = build_path_from_dentry(v9ses, dentry, &wnames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (n < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) fid = ERR_PTR(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) clone = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) while (i < n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) l = min(n - i, P9_MAXWELEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * We need to hold rename lock when doing a multipath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * walk to ensure none of the patch component change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) fid = p9_client_walk(fid, l, &wnames[i], clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (IS_ERR(fid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (old_fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * If we fail, clunk fid which are mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * to path component and not the last component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * of the path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) p9_client_clunk(old_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) kfree(wnames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) old_fid = fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) i += l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) clone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) kfree(wnames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) fid_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!IS_ERR(fid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (d_unhashed(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) p9_client_clunk(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) fid = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) __add_fid(dentry, fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) up_read(&v9ses->rename_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * v9fs_fid_lookup - lookup for a fid, try to walk if not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * @dentry: dentry to look for fid in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Look for a fid in the specified dentry for the current user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * If no fid is found, try to create one walking from a fid from the parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * dentry (if it has one), or the root dentry. If the user haven't accessed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * the fs yet, attach now and walk from the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int any, access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct v9fs_session_info *v9ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) v9ses = v9fs_dentry2v9ses(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) access = v9ses->flags & V9FS_ACCESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) switch (access) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case V9FS_ACCESS_SINGLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case V9FS_ACCESS_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case V9FS_ACCESS_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) uid = current_fsuid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) any = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case V9FS_ACCESS_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) uid = v9ses->uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) any = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) uid = INVALID_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) any = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return v9fs_fid_lookup_with_uid(dentry, uid, any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct p9_fid *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) fid = clone_fid(v9fs_fid_lookup_with_uid(dentry, GLOBAL_ROOT_UID, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (IS_ERR(fid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * writeback fid will only be used to write back the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * dirty pages. We always request for the open fid in read-write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * mode so that a partial page write which result in page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * read can work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) err = p9_client_open(fid, O_RDWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) p9_client_clunk(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) fid = ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) error_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }