initial code repo
[stor4nfv.git] / src / ceph / src / osdc / Filer.h
diff --git a/src/ceph/src/osdc/Filer.h b/src/ceph/src/osdc/Filer.h
new file mode 100644 (file)
index 0000000..00b6caa
--- /dev/null
@@ -0,0 +1,302 @@
+// -*- 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) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * 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.
+ *
+ */
+
+
+#ifndef CEPH_FILER_H
+#define CEPH_FILER_H
+
+/*** Filer
+ *
+ * stripe file ranges onto objects.
+ * build list<ObjectExtent> for the objecter or objectcacher.
+ *
+ * also, provide convenience methods that call objecter for you.
+ *
+ * "files" are identified by ino.
+ */
+
+
+#include <mutex>
+
+#include "include/types.h"
+
+#include "common/ceph_time.h"
+
+#include "osd/OSDMap.h"
+#include "Objecter.h"
+#include "Striper.h"
+
+class Context;
+class Messenger;
+class OSDMap;
+class Finisher;
+
+
+/**** Filer interface ***/
+
+class Filer {
+  CephContext *cct;
+  Objecter   *objecter;
+  Finisher   *finisher;
+
+  // probes
+  struct Probe {
+    std::mutex lock;
+    typedef std::lock_guard<std::mutex> lock_guard;
+    typedef std::unique_lock<std::mutex> unique_lock;
+    inodeno_t ino;
+    file_layout_t layout;
+    snapid_t snapid;
+
+    uint64_t *psize;
+    ceph::real_time *pmtime;
+    utime_t *pumtime;
+
+    int flags;
+
+    bool fwd;
+
+    Context *onfinish;
+
+    vector<ObjectExtent> probing;
+    uint64_t probing_off, probing_len;
+
+    map<object_t, uint64_t> known_size;
+    ceph::real_time max_mtime;
+
+    set<object_t> ops;
+
+    int err;
+    bool found_size;
+
+    Probe(inodeno_t i, file_layout_t &l, snapid_t sn,
+         uint64_t f, uint64_t *e, ceph::real_time *m, int fl, bool fw,
+         Context *c) :
+      ino(i), layout(l), snapid(sn),
+      psize(e), pmtime(m), pumtime(nullptr), flags(fl), fwd(fw), onfinish(c),
+      probing_off(f), probing_len(0),
+      err(0), found_size(false) {}
+
+    Probe(inodeno_t i, file_layout_t &l, snapid_t sn,
+         uint64_t f, uint64_t *e, utime_t *m, int fl, bool fw,
+         Context *c) :
+      ino(i), layout(l), snapid(sn),
+      psize(e), pmtime(nullptr), pumtime(m), flags(fl), fwd(fw),
+      onfinish(c), probing_off(f), probing_len(0),
+      err(0), found_size(false) {}
+  };
+
+  class C_Probe;
+
+  void _probe(Probe *p, Probe::unique_lock& pl);
+  bool _probed(Probe *p, const object_t& oid, uint64_t size,
+              ceph::real_time mtime, Probe::unique_lock& pl);
+
+ public:
+  Filer(const Filer& other);
+  const Filer operator=(const Filer& other);
+
+  Filer(Objecter *o, Finisher *f) : cct(o->cct), objecter(o), finisher(f) {}
+  ~Filer() {}
+
+  bool is_active() {
+    return objecter->is_active(); // || (oc && oc->is_active());
+  }
+
+
+  /*** async file interface.  scatter/gather as needed. ***/
+
+  void read(inodeno_t ino,
+          file_layout_t *layout,
+          snapid_t snap,
+          uint64_t offset,
+          uint64_t len,
+          bufferlist *bl,   // ptr to data
+          int flags,
+          Context *onfinish,
+          int op_flags = 0) {
+    assert(snap);  // (until there is a non-NOSNAP write)
+    vector<ObjectExtent> extents;
+    Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents);
+    objecter->sg_read(extents, snap, bl, flags, onfinish, op_flags);
+  }
+
+  void read_trunc(inodeno_t ino,
+                file_layout_t *layout,
+                snapid_t snap,
+                uint64_t offset,
+                uint64_t len,
+                bufferlist *bl, // ptr to data
+                int flags,
+                uint64_t truncate_size,
+                __u32 truncate_seq,
+                Context *onfinish,
+                int op_flags = 0) {
+    assert(snap);  // (until there is a non-NOSNAP write)
+    vector<ObjectExtent> extents;
+    Striper::file_to_extents(cct, ino, layout, offset, len, truncate_size,
+                            extents);
+    objecter->sg_read_trunc(extents, snap, bl, flags,
+                           truncate_size, truncate_seq, onfinish, op_flags);
+  }
+
+  void write(inodeno_t ino,
+           file_layout_t *layout,
+           const SnapContext& snapc,
+           uint64_t offset,
+           uint64_t len,
+           bufferlist& bl,
+           ceph::real_time mtime,
+           int flags,
+           Context *oncommit,
+           int op_flags = 0) {
+    vector<ObjectExtent> extents;
+    Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents);
+    objecter->sg_write(extents, snapc, bl, mtime, flags, oncommit, op_flags);
+  }
+
+  void write_trunc(inodeno_t ino,
+                 file_layout_t *layout,
+                 const SnapContext& snapc,
+                 uint64_t offset,
+                 uint64_t len,
+                 bufferlist& bl,
+                 ceph::real_time mtime,
+                 int flags,
+                 uint64_t truncate_size,
+                 __u32 truncate_seq,
+                 Context *oncommit,
+                 int op_flags = 0) {
+    vector<ObjectExtent> extents;
+    Striper::file_to_extents(cct, ino, layout, offset, len, truncate_size,
+                            extents);
+    objecter->sg_write_trunc(extents, snapc, bl, mtime, flags,
+                      truncate_size, truncate_seq, oncommit, op_flags);
+  }
+
+  void truncate(inodeno_t ino,
+              file_layout_t *layout,
+              const SnapContext& snapc,
+              uint64_t offset,
+              uint64_t len,
+              __u32 truncate_seq,
+              ceph::real_time mtime,
+              int flags,
+              Context *oncommit);
+  void _do_truncate_range(struct TruncRange *pr, int fin);
+
+  void zero(inodeno_t ino,
+          const file_layout_t *layout,
+          const SnapContext& snapc,
+          uint64_t offset,
+          uint64_t len,
+          ceph::real_time mtime,
+          int flags,
+          bool keep_first,
+          Context *oncommit) {
+    vector<ObjectExtent> extents;
+    Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents);
+    if (extents.size() == 1) {
+      if (extents[0].offset == 0 && extents[0].length == layout->object_size
+         && (!keep_first || extents[0].objectno != 0))
+       objecter->remove(extents[0].oid, extents[0].oloc,
+                        snapc, mtime, flags, oncommit);
+      else
+       objecter->zero(extents[0].oid, extents[0].oloc, extents[0].offset,
+                      extents[0].length, snapc, mtime, flags, oncommit);
+    } else {
+      C_GatherBuilder gcom(cct, oncommit);
+      for (vector<ObjectExtent>::iterator p = extents.begin();
+          p != extents.end();
+          ++p) {
+       if (p->offset == 0 && p->length == layout->object_size &&
+           (!keep_first || p->objectno != 0))
+         objecter->remove(p->oid, p->oloc,
+                          snapc, mtime, flags,
+                          oncommit ? gcom.new_sub():0);
+       else
+         objecter->zero(p->oid, p->oloc, p->offset, p->length,
+                        snapc, mtime, flags,
+                        oncommit ? gcom.new_sub():0);
+      }
+      gcom.activate();
+    }
+  }
+
+  void zero(inodeno_t ino,
+          file_layout_t *layout,
+          const SnapContext& snapc,
+          uint64_t offset,
+          uint64_t len,
+          ceph::real_time mtime,
+          int flags,
+          Context *oncommit) {
+    zero(ino, layout,
+         snapc, offset,
+         len, mtime,
+         flags, false,
+         oncommit);
+  }
+  // purge range of ino.### objects
+  int purge_range(inodeno_t ino,
+                 const file_layout_t *layout,
+                 const SnapContext& snapc,
+                 uint64_t first_obj, uint64_t num_obj,
+                 ceph::real_time mtime,
+                 int flags, Context *oncommit);
+  void _do_purge_range(struct PurgeRange *pr, int fin);
+
+  /*
+   * probe
+   *  specify direction,
+   *  and whether we stop when we find data, or hole.
+   */
+  int probe(inodeno_t ino,
+           file_layout_t *layout,
+           snapid_t snapid,
+           uint64_t start_from,
+           uint64_t *end,
+           ceph::real_time *mtime,
+           bool fwd,
+           int flags,
+           Context *onfinish);
+
+  int probe(inodeno_t ino,
+           file_layout_t *layout,
+           snapid_t snapid,
+           uint64_t start_from,
+           uint64_t *end,
+           bool fwd,
+           int flags,
+           Context *onfinish) {
+    return probe(ino, layout, snapid, start_from, end,
+                (ceph::real_time* )0, fwd, flags, onfinish);
+  }
+
+  int probe(inodeno_t ino,
+           file_layout_t *layout,
+           snapid_t snapid,
+           uint64_t start_from,
+           uint64_t *end,
+           utime_t *mtime,
+           bool fwd,
+           int flags,
+           Context *onfinish);
+
+private:
+  int probe_impl(Probe* probe, file_layout_t *layout,
+                uint64_t start_from, uint64_t *end);
+};
+
+#endif // !CEPH_FILER_H