Re: [PATCH v2 10/20] ceph_d_revalidate(): propagate stable name down into request enconding

Jeff Layton
2025-01-17T18:35:09Z

On Thu, 2025-01-16 at 05:23 +0000, Al Viro wrote:
> 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.
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
> fs/ceph/dir.c | 2 ++
> fs/ceph/mds_client.c | 9 ++++++---
> fs/ceph/mds_client.h | 2 ++
> 3 files changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
> index dc5f55bebad7..62e99e65250d 100644
> --- a/fs/ceph/dir.c
> +++ b/fs/ceph/dir.c
> @@ -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;
> diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
> index 219a2cc2bf3c..3b766b984713 100644
> --- a/fs/ceph/mds_client.c
> +++ b/fs/ceph/mds_client.c
> @@ -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);
> diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
> index 38bb7e0d2d79..7c9fee9e80d4 100644
> --- a/fs/ceph/mds_client.h
> +++ b/fs/ceph/mds_client.h
> @@ -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 */

Reviewed-by: Jeff Layton <jlayton@kernel.org>