]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
ceph_d_revalidate(): propagate stable name down into request encoding
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 7 Jan 2025 15:04:11 +0000 (10:04 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 28 Jan 2025 00:25:23 +0000 (19:25 -0500)
Currently get_fscrypt_altname() requires ->r_dentry->d_name to be stable
and it gets that in almost all cases.  The only exception is ->d_revalidate(),
where we have a stable name, but it's passed separately - dentry->d_name
is not stable there.

Propagate it down to get_fscrypt_altname() as a new field of struct
ceph_mds_request - ->r_dname, to be used instead ->r_dentry->d_name
when non-NULL.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/ceph/dir.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h

index dc5f55bebad766208de70a5d464fa96da2cba37b..62e99e65250d72c8c5eec6ec751c6488552fbe08 100644 (file)
@@ -1998,6 +1998,8 @@ static int ceph_d_revalidate(struct inode *dir, const struct qstr *name,
                        req->r_parent = dir;
                        ihold(dir);
 
+                       req->r_dname = name;
+
                        mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
                        if (ceph_security_xattr_wanted(dir))
                                mask |= CEPH_CAP_XATTR_SHARED;
index 219a2cc2bf3cc2f22a0d76d822df3aef6de8649f..3b766b9847136baf665709b1abb040d416ed129b 100644 (file)
@@ -2621,6 +2621,7 @@ static u8 *get_fscrypt_altname(const struct ceph_mds_request *req, u32 *plen)
 {
        struct inode *dir = req->r_parent;
        struct dentry *dentry = req->r_dentry;
+       const struct qstr *name = req->r_dname;
        u8 *cryptbuf = NULL;
        u32 len = 0;
        int ret = 0;
@@ -2641,8 +2642,10 @@ static u8 *get_fscrypt_altname(const struct ceph_mds_request *req, u32 *plen)
        if (!fscrypt_has_encryption_key(dir))
                goto success;
 
-       if (!fscrypt_fname_encrypted_size(dir, dentry->d_name.len, NAME_MAX,
-                                         &len)) {
+       if (!name)
+               name = &dentry->d_name;
+
+       if (!fscrypt_fname_encrypted_size(dir, name->len, NAME_MAX, &len)) {
                WARN_ON_ONCE(1);
                return ERR_PTR(-ENAMETOOLONG);
        }
@@ -2657,7 +2660,7 @@ static u8 *get_fscrypt_altname(const struct ceph_mds_request *req, u32 *plen)
        if (!cryptbuf)
                return ERR_PTR(-ENOMEM);
 
-       ret = fscrypt_fname_encrypt(dir, &dentry->d_name, cryptbuf, len);
+       ret = fscrypt_fname_encrypt(dir, name, cryptbuf, len);
        if (ret) {
                kfree(cryptbuf);
                return ERR_PTR(ret);
index 38bb7e0d2d7916b6371574f082de2ab1cd79806b..7c9fee9e80d45f423e264e149484f29752656bae 100644 (file)
@@ -299,6 +299,8 @@ struct ceph_mds_request {
        struct inode *r_target_inode;       /* resulting inode */
        struct inode *r_new_inode;          /* new inode (for creates) */
 
+       const struct qstr *r_dname;         /* stable name (for ->d_revalidate) */
+
 #define CEPH_MDS_R_DIRECT_IS_HASH      (1) /* r_direct_hash is valid */
 #define CEPH_MDS_R_ABORTED             (2) /* call was aborted */
 #define CEPH_MDS_R_GOT_UNSAFE          (3) /* got an unsafe reply */