temp is not defined outside of the RCU critical section here. Ensure we grab that value before we drop the rcu_read_lock. Cc: stable@xxxxxxxxxxxxxxx Reported-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> --- fs/ceph/mds_client.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 2b102bf5c356..74cb3078ea63 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2087,13 +2087,14 @@ static inline u64 __get_oldest_tid(struct ceph_mds_client *mdsc) * Encode hidden .snap dirs as a double /, i.e. * foo/.snap/bar -> foo//bar */ -char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, +char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, int stop_on_nosnap) { struct dentry *temp; char *path; int len, pos; unsigned seq; + u64 base; if (!dentry) return ERR_PTR(-EINVAL); @@ -2149,6 +2150,7 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, path[--pos] = '/'; temp = temp->d_parent; } + base = ceph_ino(d_inode(temp)); rcu_read_unlock(); if (pos != 0 || read_seqretry(&rename_lock, seq)) { pr_err("build_path did not end path lookup where " @@ -2161,10 +2163,10 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, goto retry; } - *base = ceph_ino(d_inode(temp)); + *pbase = base; *plen = len; dout("build_path on %p %d built %llx '%.*s'\n", - dentry, d_count(dentry), *base, len, path); + dentry, d_count(dentry), base, len, path); return path; } -- 2.20.1