From: Milind Changire Date: Tue, 1 Feb 2022 14:46:44 +0000 (+0530) Subject: client: add new getvxattr rpc X-Git-Tag: v16.2.8~63^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=235b1fbc6478e5c06ca3d9814308f8b63682c118;p=ceph.git client: add new getvxattr rpc 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 (cherry picked from commit 518f714941e0252585d9632668edb14f822f4adf) --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 86936de67bcb..2aef3328ef09 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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, diff --git a/src/client/Client.h b/src/client/Client.h index 4a30c1ba772c..b28df65fb7f3 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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);