Merge tag 'block-6.6-2023-10-12' of git://git.kernel.dk/linux
[platform/kernel/linux-rpi.git] / fs / ceph / export.c
index f780e4e..8559990 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "super.h"
 #include "mds_client.h"
+#include "crypto.h"
 
 /*
  * Basic fh
@@ -535,7 +536,9 @@ static int ceph_get_name(struct dentry *parent, char *name,
 {
        struct ceph_mds_client *mdsc;
        struct ceph_mds_request *req;
+       struct inode *dir = d_inode(parent);
        struct inode *inode = d_inode(child);
+       struct ceph_mds_reply_info_parsed *rinfo;
        int err;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
@@ -547,30 +550,47 @@ static int ceph_get_name(struct dentry *parent, char *name,
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       inode_lock(d_inode(parent));
-
+       inode_lock(dir);
        req->r_inode = inode;
        ihold(inode);
        req->r_ino2 = ceph_vino(d_inode(parent));
-       req->r_parent = d_inode(parent);
-       ihold(req->r_parent);
+       req->r_parent = dir;
+       ihold(dir);
        set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
        req->r_num_caps = 2;
        err = ceph_mdsc_do_request(mdsc, NULL, req);
+       inode_unlock(dir);
 
-       inode_unlock(d_inode(parent));
+       if (err)
+               goto out;
 
-       if (!err) {
-               struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+       rinfo = &req->r_reply_info;
+       if (!IS_ENCRYPTED(dir)) {
                memcpy(name, rinfo->dname, rinfo->dname_len);
                name[rinfo->dname_len] = 0;
-               dout("get_name %p ino %llx.%llx name %s\n",
-                    child, ceph_vinop(inode), name);
        } else {
-               dout("get_name %p ino %llx.%llx err %d\n",
-                    child, ceph_vinop(inode), err);
-       }
+               struct fscrypt_str oname = FSTR_INIT(NULL, 0);
+               struct ceph_fname fname = { .dir        = dir,
+                                           .name       = rinfo->dname,
+                                           .ctext      = rinfo->altname,
+                                           .name_len   = rinfo->dname_len,
+                                           .ctext_len  = rinfo->altname_len };
+
+               err = ceph_fname_alloc_buffer(dir, &oname);
+               if (err < 0)
+                       goto out;
 
+               err = ceph_fname_to_usr(&fname, NULL, &oname, NULL);
+               if (!err) {
+                       memcpy(name, oname.name, oname.len);
+                       name[oname.len] = 0;
+               }
+               ceph_fname_free_buffer(dir, &oname);
+       }
+out:
+       dout("get_name %p ino %llx.%llx err %d %s%s\n",
+                    child, ceph_vinop(inode), err,
+                    err ? "" : "name ", err ? "" : name);
        ceph_mdsc_put_request(req);
        return err;
 }