]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cls_cephfs: add PGLSCephFSFilter
authorJohn Spray <john.spray@redhat.com>
Fri, 17 Jul 2015 13:19:57 +0000 (14:19 +0100)
committerYan, Zheng <zyan@redhat.com>
Wed, 2 Dec 2015 07:16:16 +0000 (15:16 +0800)
Special purpose filter for use with CephFS disaster
recovery.

Fixes: #12145
Signed-off-by: John Spray <john.spray@redhat.com>
src/cls/cephfs/cls_cephfs.cc
src/cls/cephfs/cls_cephfs.h
src/cls/cephfs/cls_cephfs_client.cc
src/cls/cephfs/cls_cephfs_client.h

index f58f0de39afa281d1a3d520094f16687cc5827af..8f54e3a69732cd64b4d34135e15cb2f61210825c 100644 (file)
@@ -123,6 +123,72 @@ static int accumulate_inode_metadata(cls_method_context_t hctx,
   return 0;
 }
 
+// I want to select objects that have a name ending 00000000
+// and an xattr (scrub_tag) not equal to a specific value.
+// This is so special case that we can't really pretend it's
+// generic, so just fess up and call this the cephfs filter.
+class PGLSCephFSFilter : public PGLSFilter {
+protected:
+  std::string scrub_tag;
+public:
+  int init(bufferlist::iterator& params) {
+    try {
+      InodeTagFilterArgs args;
+      args.decode(params);
+      scrub_tag = args.scrub_tag;
+    } catch (buffer::error &e) {
+      return -EINVAL;
+    }
+
+    if (scrub_tag.empty()) {
+      xattr = "";
+    } else {
+      xattr = "_scrub_tag";
+    }
+
+    return 0;
+  }
+
+  virtual ~PGLSCephFSFilter() {}
+  virtual bool reject_empty_xattr() { return false; }
+  virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
+                      bufferlist& outdata);
+};
+
+bool PGLSCephFSFilter::filter(const hobject_t &obj,
+                             bufferlist& xattr_data, bufferlist& outdata)
+{
+  const std::string need_ending = ".00000000";
+  const std::string &obj_name = obj.oid.name;
+
+  if (obj_name.length() < need_ending.length()) {
+    return false;
+  }
+
+  const bool match = obj_name.compare (obj_name.length() - need_ending.length(), need_ending.length(), need_ending) == 0;
+  if (!match) {
+    return false;
+  }
+
+  if (!scrub_tag.empty() && xattr_data.length() > 0) {
+    std::string tag_ondisk;
+    bufferlist::iterator q = xattr_data.begin();
+    try {
+      ::decode(tag_ondisk, q);
+      if (tag_ondisk == scrub_tag)
+       return false;
+    } catch (const buffer::error &err) {
+    }
+  }
+
+  return true;
+}
+
+PGLSFilter *inode_tag_filter()
+{
+  return new PGLSCephFSFilter();
+}
+
 /**
  * initialize class
  *
@@ -139,5 +205,8 @@ void __cls_init()
   cls_register_cxx_method(h_class, "accumulate_inode_metadata",
                          CLS_METHOD_WR | CLS_METHOD_RD,
                          accumulate_inode_metadata, &h_accumulate_inode_metadata);
+
+  // A PGLS filter
+  cls_register_cxx_filter(h_class, "inode_tag", inode_tag_filter);
 }
 
index d4a5f23811dfcdeb2de16b5023e8b1ca5d634728..ca631c66d90264a210960c0a1879ee28b9aca52f 100644 (file)
@@ -108,6 +108,26 @@ public:
   }
 };
 
+class InodeTagFilterArgs
+{
+  public:
+    std::string scrub_tag;
+
+  void encode(bufferlist &bl) const
+  {
+    ENCODE_START(1, 1, bl);
+    ::encode(scrub_tag, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator &bl)
+  {
+    DECODE_START(1, bl);
+    ::decode(scrub_tag, bl);
+    DECODE_FINISH(bl);
+  }
+};
+
 class AccumulateResult
 {
 public:
index c471fdeb70a53e6f75945a51a081a5f19f4c510d..dc945282b90740cf0bb6ea1261b87c67fb843b21 100644 (file)
@@ -144,3 +144,18 @@ int ClsCephFSClient::fetch_inode_accumulate_result(
   return 0;
 }
 
+void ClsCephFSClient::build_tag_filter(
+          const std::string &scrub_tag,
+          bufferlist *out_bl)
+{
+  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);
+}
+
index 45d3c4bb6997f6b22d85170d89f8cc69e410f7db..ddd84566d067f307b7a979c7e5920c4e916ccaaf 100644 (file)
@@ -22,5 +22,9 @@ class ClsCephFSClient
       inode_backtrace_t *backtrace,
       ceph_file_layout *layout,
       AccumulateResult *result);
+
+  static void build_tag_filter(
+      const std::string &scrub_tag,
+      bufferlist *out_bl);
 };