]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: add new getvxattr rpc
authorMilind Changire <mchangir@redhat.com>
Tue, 1 Feb 2022 14:46:44 +0000 (20:16 +0530)
committerMilind Changire <mchangir@redhat.com>
Thu, 17 Mar 2022 13:13:59 +0000 (18:43 +0530)
This new op fetches ceph namespace specific extended attributes
i.e. attributes
1. ceph.dir.layout.json and ceph.file.layout.json
2. ceph.dir.layout.pool_name and ceph.file.layout.pool_name
3. ceph.dir.layout.pool_id and ceph.file.layout.pool_id
4. ceph.dir.pin, ceph.dir.pin.random and ceph.dir.pin.distributed

Fixes: https://tracker.ceph.com/issues/51062
Signed-off-by: Milind Changire <mchangir@redhat.com>
(cherry picked from commit 518f714941e0252585d9632668edb14f822f4adf)

src/client/Client.cc
src/client/Client.h

index 86936de67bcb0b6915b5bba839786ec801c2d671..2aef3328ef09489f434ea61daf2b74decf1183c9 100644 (file)
@@ -7476,6 +7476,54 @@ int Client::_getattr(Inode *in, int mask, const UserPerm& perms, bool force)
   return res;
 }
 
+int Client::_getvxattr(
+  Inode *in,
+  const UserPerm& perms,
+  const char *xattr_name,
+  ssize_t size,
+  void *value,
+  mds_rank_t rank)
+{
+  if (!xattr_name || strlen(xattr_name) <= 0 || strlen(xattr_name) > 255) {
+    return -CEPHFS_ENODATA;
+  }
+
+  MetaRequest *req = new MetaRequest(CEPH_MDS_OP_GETVXATTR);
+  filepath path;
+  in->make_nosnap_relative_path(path);
+  req->set_filepath(path);
+  req->set_inode(in);
+  req->set_string2(xattr_name);
+
+  bufferlist bl;
+  int res = make_request(req, perms, nullptr, nullptr, rank, &bl);
+  ldout(cct, 10) << __func__ << " result=" << res << dendl;
+
+  if (res < 0) {
+    return res;
+  }
+
+  std::string buf;
+  auto p = bl.cbegin();
+
+  DECODE_START(1, p);
+  decode(buf, p);
+  DECODE_FINISH(p);
+
+  ssize_t len = buf.length();
+
+  res = len; // refer to man getxattr(2) for output buffer size == 0
+
+  if (size > 0) {
+    if (len > size) {
+      res = -CEPHFS_ERANGE; // insufficient output buffer space
+    } else {
+      memcpy(value, buf.c_str(), len);
+    }
+  }
+  return res;
+}
+
 int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask,
                        const UserPerm& perms, InodeRef *inp)
 {
@@ -12231,8 +12279,9 @@ int Client::_getxattr(Inode *in, const char *name, void *value, size_t size,
                      const UserPerm& perms)
 {
   int r;
+  const VXattr *vxattr = nullptr;
 
-  const VXattr *vxattr = _match_vxattr(in, name);
+  vxattr = _match_vxattr(in, name);
   if (vxattr) {
     r = -CEPHFS_ENODATA;
 
@@ -12269,6 +12318,11 @@ int Client::_getxattr(Inode *in, const char *name, void *value, size_t size,
     goto out;
   }
 
+  if (!strncmp(name, "ceph.", 5)) {
+    r = _getvxattr(in, perms, name, size, value, MDS_RANK_NONE);
+    goto out;
+  }
+
   if (acl_type == NO_ACL && !strncmp(name, "system.", 7)) {
     r = -CEPHFS_EOPNOTSUPP;
     goto out;
@@ -12278,7 +12332,7 @@ int Client::_getxattr(Inode *in, const char *name, void *value, size_t size,
   if (r == 0) {
     string n(name);
     r = -CEPHFS_ENODATA;
-   if (in->xattrs.count(n)) {
+    if (in->xattrs.count(n)) {
       r = in->xattrs[n].length();
       if (r > 0 && size != 0) {
        if (size >= (unsigned)r)
@@ -12852,6 +12906,8 @@ const Client::VXattr Client::_dir_vxattrs[] = {
     exists_cb: &Client::_vxattrcb_layout_exists,
     flags: 0,
   },
+  // FIXME
+  // Delete the following dir layout field definitions for release "S"
   XATTR_LAYOUT_FIELD(dir, layout, stripe_unit),
   XATTR_LAYOUT_FIELD(dir, layout, stripe_count),
   XATTR_LAYOUT_FIELD(dir, layout, object_size),
@@ -12875,6 +12931,8 @@ const Client::VXattr Client::_dir_vxattrs[] = {
   },
   XATTR_QUOTA_FIELD(quota, max_bytes),
   XATTR_QUOTA_FIELD(quota, max_files),
+  // FIXME
+  // Delete the following dir pin field definitions for release "S"
   {
     name: "ceph.dir.pin",
     getxattr_cb: &Client::_vxattrcb_dir_pin,
index 4a30c1ba772c8324a6104e67d5b181f806ff0721..b28df65fb7f359fad0af76d46885ee264aad9bd9 100644 (file)
@@ -1338,6 +1338,8 @@ private:
                const UserPerm& perms);
   int _getxattr(InodeRef &in, const char *name, void *value, size_t len,
                const UserPerm& perms);
+  int _getvxattr(Inode *in, const UserPerm& perms, const char *attr_name,
+                 ssize_t size, void *value, mds_rank_t rank);
   int _listxattr(Inode *in, char *names, size_t len, const UserPerm& perms);
   int _do_setxattr(Inode *in, const char *name, const void *value, size_t len,
                   int flags, const UserPerm& perms);