]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
ceph_d_revalidate(): use stable parent inode passed by caller
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 3 Jan 2025 05:54:18 +0000 (00:54 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 28 Jan 2025 00:25:23 +0000 (19:25 -0500)
No need to mess with the boilerplate for obtaining what we already
have.  Note that ceph is one of the "will want a path from filesystem
root if we want to talk to server" cases, so the name of the last
component is of little use - it is passed to fscrypt_d_revalidate()
and it's used to deal with (also crypt-related) case in request
marshalling, when encrypted name turns out to be too long.  The former
is not a problem, but the latter is racy; that part will be handled
in the next commit.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/ceph/dir.c

index c4c71c24221b6cc2bd4bca0439e081daae46c9d6..dc5f55bebad766208de70a5d464fa96da2cba37b 100644 (file)
@@ -1940,30 +1940,19 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry,
 /*
  * Check if cached dentry can be trusted.
  */
-static int ceph_d_revalidate(struct inode *parent_dir, const struct qstr *name,
+static int ceph_d_revalidate(struct inode *dir, const struct qstr *name,
                             struct dentry *dentry, unsigned int flags)
 {
        struct ceph_mds_client *mdsc = ceph_sb_to_fs_client(dentry->d_sb)->mdsc;
        struct ceph_client *cl = mdsc->fsc->client;
        int valid = 0;
-       struct dentry *parent;
-       struct inode *dir, *inode;
+       struct inode *inode;
 
-       valid = fscrypt_d_revalidate(parent_dir, name, dentry, flags);
+       valid = fscrypt_d_revalidate(dir, name, dentry, flags);
        if (valid <= 0)
                return valid;
 
-       if (flags & LOOKUP_RCU) {
-               parent = READ_ONCE(dentry->d_parent);
-               dir = d_inode_rcu(parent);
-               if (!dir)
-                       return -ECHILD;
-               inode = d_inode_rcu(dentry);
-       } else {
-               parent = dget_parent(dentry);
-               dir = d_inode(parent);
-               inode = d_inode(dentry);
-       }
+       inode = d_inode_rcu(dentry);
 
        doutc(cl, "%p '%pd' inode %p offset 0x%llx nokey %d\n",
              dentry, dentry, inode, ceph_dentry(dentry)->offset,
@@ -2039,9 +2028,6 @@ static int ceph_d_revalidate(struct inode *parent_dir, const struct qstr *name,
        doutc(cl, "%p '%pd' %s\n", dentry, dentry, valid ? "valid" : "invalid");
        if (!valid)
                ceph_dir_clear_complete(dir);
-
-       if (!(flags & LOOKUP_RCU))
-               dput(parent);
        return valid;
 }