summaryrefslogtreecommitdiffstats
path: root/src/cls/cephfs/cls_cephfs_client.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/cls/cephfs/cls_cephfs_client.cc
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cls/cephfs/cls_cephfs_client.cc')
-rw-r--r--src/cls/cephfs/cls_cephfs_client.cc180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/cls/cephfs/cls_cephfs_client.cc b/src/cls/cephfs/cls_cephfs_client.cc
new file mode 100644
index 000000000..d776443fe
--- /dev/null
+++ b/src/cls/cephfs/cls_cephfs_client.cc
@@ -0,0 +1,180 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+
+#include "include/rados/librados.hpp"
+#include "mds/CInode.h"
+
+#include "cls_cephfs_client.h"
+
+using ceph::bufferlist;
+using ceph::decode;
+
+#define XATTR_CEILING "scan_ceiling"
+#define XATTR_MAX_MTIME "scan_max_mtime"
+#define XATTR_MAX_SIZE "scan_max_size"
+
+int ClsCephFSClient::accumulate_inode_metadata(
+ librados::IoCtx &ctx,
+ inodeno_t inode_no,
+ const uint64_t obj_index,
+ const uint64_t obj_size,
+ const time_t mtime)
+{
+ AccumulateArgs args(
+ obj_index,
+ obj_size,
+ mtime,
+ XATTR_CEILING,
+ XATTR_MAX_MTIME,
+ XATTR_MAX_SIZE);
+
+ // Generate 0th object name, where we will accumulate sizes/mtimes
+ object_t zeroth_object = InodeStore::get_object_name(inode_no, frag_t(), "");
+
+ // Construct a librados operation invoking our class method
+ librados::ObjectReadOperation op;
+ bufferlist inbl;
+ args.encode(inbl);
+ op.exec("cephfs", "accumulate_inode_metadata", inbl);
+
+ // Execute op
+ bufferlist outbl;
+ return ctx.operate(zeroth_object.name, &op, &outbl);
+}
+
+int ClsCephFSClient::delete_inode_accumulate_result(
+ librados::IoCtx &ctx,
+ const std::string &oid)
+{
+ librados::ObjectWriteOperation op;
+
+ // Remove xattrs from object
+ //
+ op.rmxattr(XATTR_CEILING);
+ op.rmxattr(XATTR_MAX_SIZE);
+ op.rmxattr(XATTR_MAX_MTIME);
+
+ return (ctx.operate(oid, &op));
+}
+
+int ClsCephFSClient::fetch_inode_accumulate_result(
+ librados::IoCtx &ctx,
+ const std::string &oid,
+ inode_backtrace_t *backtrace,
+ file_layout_t *layout,
+ AccumulateResult *result)
+{
+ ceph_assert(backtrace != NULL);
+ ceph_assert(result != NULL);
+
+ librados::ObjectReadOperation op;
+
+ int scan_ceiling_r = 0;
+ bufferlist scan_ceiling_bl;
+ op.getxattr(XATTR_CEILING, &scan_ceiling_bl, &scan_ceiling_r);
+
+ int scan_max_size_r = 0;
+ bufferlist scan_max_size_bl;
+ op.getxattr(XATTR_MAX_SIZE, &scan_max_size_bl, &scan_max_size_r);
+
+ int scan_max_mtime_r = 0;
+ bufferlist scan_max_mtime_bl;
+ op.getxattr(XATTR_MAX_MTIME, &scan_max_mtime_bl, &scan_max_mtime_r);
+
+ int parent_r = 0;
+ bufferlist parent_bl;
+ op.getxattr("parent", &parent_bl, &parent_r);
+ op.set_op_flags2(librados::OP_FAILOK);
+
+ int layout_r = 0;
+ bufferlist layout_bl;
+ op.getxattr("layout", &layout_bl, &layout_r);
+ op.set_op_flags2(librados::OP_FAILOK);
+
+ bufferlist op_bl;
+ int r = ctx.operate(oid, &op, &op_bl);
+ if (r < 0) {
+ return r;
+ }
+
+ // Load scan_ceiling
+ try {
+ auto scan_ceiling_bl_iter = scan_ceiling_bl.cbegin();
+ ObjCeiling ceiling;
+ ceiling.decode(scan_ceiling_bl_iter);
+ result->ceiling_obj_index = ceiling.id;
+ result->ceiling_obj_size = ceiling.size;
+ } catch (const ceph::buffer::error &err) {
+ //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
+ return -EINVAL;
+ }
+
+ // Load scan_max_size
+ try {
+ auto scan_max_size_bl_iter = scan_max_size_bl.cbegin();
+ decode(result->max_obj_size, scan_max_size_bl_iter);
+ } catch (const ceph::buffer::error &err) {
+ //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
+ return -EINVAL;
+ }
+
+ // Load scan_max_mtime
+ try {
+ auto scan_max_mtime_bl_iter = scan_max_mtime_bl.cbegin();
+ decode(result->max_mtime, scan_max_mtime_bl_iter);
+ } catch (const ceph::buffer::error &err) {
+ //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
+ return -EINVAL;
+ }
+
+ // Deserialize backtrace
+ if (parent_bl.length()) {
+ try {
+ auto q = parent_bl.cbegin();
+ backtrace->decode(q);
+ } catch (ceph::buffer::error &e) {
+ //dout(4) << "Corrupt backtrace on '" << oid << "': " << e << dendl;
+ return -EINVAL;
+ }
+ }
+
+ // Deserialize layout
+ if (layout_bl.length()) {
+ try {
+ auto q = layout_bl.cbegin();
+ decode(*layout, q);
+ } catch (ceph::buffer::error &e) {
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+void ClsCephFSClient::build_tag_filter(
+ const std::string &scrub_tag,
+ bufferlist *out_bl)
+{
+ ceph_assert(out_bl != NULL);
+
+ // Leading part of bl is un-versioned string naming the filter
+ encode(std::string("cephfs.inode_tag"), *out_bl);
+
+ // Filter-specific part of the bl: in our case this is a versioned structure
+ InodeTagFilterArgs args;
+ args.scrub_tag = scrub_tag;
+ args.encode(*out_bl);
+}