summaryrefslogtreecommitdiffstats
path: root/src/os/bluestore/bluefs_types.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/os/bluestore/bluefs_types.cc285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/os/bluestore/bluefs_types.cc b/src/os/bluestore/bluefs_types.cc
new file mode 100644
index 000000000..3a812cf5f
--- /dev/null
+++ b/src/os/bluestore/bluefs_types.cc
@@ -0,0 +1,285 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <algorithm>
+#include "bluefs_types.h"
+#include "common/Formatter.h"
+#include "include/uuid.h"
+#include "include/stringify.h"
+
+using std::list;
+using std::ostream;
+
+using ceph::bufferlist;
+using ceph::Formatter;
+
+// bluefs_extent_t
+void bluefs_extent_t::dump(Formatter *f) const
+{
+ f->dump_unsigned("offset", offset);
+ f->dump_unsigned("length", length);
+ f->dump_unsigned("bdev", bdev);
+}
+
+void bluefs_extent_t::generate_test_instances(list<bluefs_extent_t*>& ls)
+{
+ ls.push_back(new bluefs_extent_t);
+ ls.push_back(new bluefs_extent_t);
+ ls.back()->offset = 1;
+ ls.back()->length = 2;
+ ls.back()->bdev = 1;
+}
+
+ostream& operator<<(ostream& out, const bluefs_extent_t& e)
+{
+ return out << (int)e.bdev << ":0x" << std::hex << e.offset << "~" << e.length
+ << std::dec;
+}
+
+// bluefs_layout_t
+
+void bluefs_layout_t::encode(bufferlist& bl) const
+{
+ ENCODE_START(1, 1, bl);
+ encode(shared_bdev, bl);
+ encode(dedicated_db, bl);
+ encode(dedicated_wal, bl);
+ ENCODE_FINISH(bl);
+}
+
+void bluefs_layout_t::decode(bufferlist::const_iterator& p)
+{
+ DECODE_START(1, p);
+ decode(shared_bdev, p);
+ decode(dedicated_db, p);
+ decode(dedicated_wal, p);
+ DECODE_FINISH(p);
+}
+
+void bluefs_layout_t::dump(Formatter *f) const
+{
+ f->dump_stream("shared_bdev") << shared_bdev;
+ f->dump_stream("dedicated_db") << dedicated_db;
+ f->dump_stream("dedicated_wal") << dedicated_wal;
+}
+
+// bluefs_super_t
+
+void bluefs_super_t::encode(bufferlist& bl) const
+{
+ ENCODE_START(2, 1, bl);
+ encode(uuid, bl);
+ encode(osd_uuid, bl);
+ encode(version, bl);
+ encode(block_size, bl);
+ encode(log_fnode, bl);
+ encode(memorized_layout, bl);
+ ENCODE_FINISH(bl);
+}
+
+void bluefs_super_t::decode(bufferlist::const_iterator& p)
+{
+ DECODE_START(2, p);
+ decode(uuid, p);
+ decode(osd_uuid, p);
+ decode(version, p);
+ decode(block_size, p);
+ decode(log_fnode, p);
+ if (struct_v >= 2) {
+ decode(memorized_layout, p);
+ }
+ DECODE_FINISH(p);
+}
+
+void bluefs_super_t::dump(Formatter *f) const
+{
+ f->dump_stream("uuid") << uuid;
+ f->dump_stream("osd_uuid") << osd_uuid;
+ f->dump_unsigned("version", version);
+ f->dump_unsigned("block_size", block_size);
+ f->dump_object("log_fnode", log_fnode);
+}
+
+void bluefs_super_t::generate_test_instances(list<bluefs_super_t*>& ls)
+{
+ ls.push_back(new bluefs_super_t);
+ ls.push_back(new bluefs_super_t);
+ ls.back()->version = 1;
+ ls.back()->block_size = 4096;
+}
+
+ostream& operator<<(ostream& out, const bluefs_super_t& s)
+{
+ return out << "super(uuid " << s.uuid
+ << " osd " << s.osd_uuid
+ << " v " << s.version
+ << " block_size 0x" << std::hex << s.block_size
+ << " log_fnode 0x" << s.log_fnode
+ << std::dec << ")";
+}
+
+// bluefs_fnode_t
+
+mempool::bluefs::vector<bluefs_extent_t>::iterator bluefs_fnode_t::seek(
+ uint64_t offset, uint64_t *x_off)
+{
+ auto p = extents.begin();
+
+ if (extents_index.size() > 4) {
+ auto it = std::upper_bound(extents_index.begin(), extents_index.end(),
+ offset);
+ assert(it != extents_index.begin());
+ --it;
+ assert(offset >= *it);
+ p += it - extents_index.begin();
+ offset -= *it;
+ }
+
+ while (p != extents.end()) {
+ if ((int64_t) offset >= p->length) {
+ offset -= p->length;
+ ++p;
+ } else {
+ break;
+ }
+ }
+ *x_off = offset;
+ return p;
+}
+
+bluefs_fnode_delta_t* bluefs_fnode_t::make_delta(bluefs_fnode_delta_t* delta) {
+ ceph_assert(delta);
+ delta->ino = ino;
+ delta->size = size;
+ delta->mtime = mtime;
+ delta->offset = allocated_commited;
+ delta->extents.clear();
+ if (allocated_commited < allocated) {
+ uint64_t x_off = 0;
+ auto p = seek(allocated_commited, &x_off);
+ ceph_assert(p != extents.end());
+ if (x_off > 0) {
+ ceph_assert(x_off < p->length);
+ delta->extents.emplace_back(p->bdev, p->offset + x_off, p->length - x_off);
+ ++p;
+ }
+ while (p != extents.end()) {
+ delta->extents.push_back(*p);
+ ++p;
+ }
+ reset_delta();
+ }
+ return delta;
+}
+
+void bluefs_fnode_t::dump(Formatter *f) const
+{
+ f->dump_unsigned("ino", ino);
+ f->dump_unsigned("size", size);
+ f->dump_stream("mtime") << mtime;
+ f->open_array_section("extents");
+ for (auto& p : extents)
+ f->dump_object("extent", p);
+ f->close_section();
+}
+
+void bluefs_fnode_t::generate_test_instances(list<bluefs_fnode_t*>& ls)
+{
+ ls.push_back(new bluefs_fnode_t);
+ ls.push_back(new bluefs_fnode_t);
+ ls.back()->ino = 123;
+ ls.back()->size = 1048576;
+ ls.back()->mtime = utime_t(123,45);
+ ls.back()->extents.push_back(bluefs_extent_t(0, 1048576, 4096));
+ ls.back()->__unused__ = 1;
+}
+
+ostream& operator<<(ostream& out, const bluefs_fnode_t& file)
+{
+ return out << "file(ino " << file.ino
+ << " size 0x" << std::hex << file.size << std::dec
+ << " mtime " << file.mtime
+ << " allocated " << std::hex << file.allocated << std::dec
+ << " alloc_commit " << std::hex << file.allocated_commited << std::dec
+ << " extents " << file.extents
+ << ")";
+}
+
+// bluefs_fnode_delta_t
+
+std::ostream& operator<<(std::ostream& out, const bluefs_fnode_delta_t& delta)
+{
+ return out << "delta(ino " << delta.ino
+ << " size 0x" << std::hex << delta.size << std::dec
+ << " mtime " << delta.mtime
+ << " offset " << std::hex << delta.offset << std::dec
+ << " extents " << delta.extents
+ << ")";
+}
+
+// bluefs_transaction_t
+
+void bluefs_transaction_t::encode(bufferlist& bl) const
+{
+ uint32_t crc = op_bl.crc32c(-1);
+ ENCODE_START(1, 1, bl);
+ encode(uuid, bl);
+ encode(seq, bl);
+ // not using bufferlist encode method, as it merely copies the bufferptr and not
+ // contents, meaning we're left with fragmented target bl
+ __u32 len = op_bl.length();
+ encode(len, bl);
+ for (auto& it : op_bl.buffers()) {
+ bl.append(it.c_str(), it.length());
+ }
+ encode(crc, bl);
+ ENCODE_FINISH(bl);
+}
+
+void bluefs_transaction_t::decode(bufferlist::const_iterator& p)
+{
+ uint32_t crc;
+ DECODE_START(1, p);
+ decode(uuid, p);
+ decode(seq, p);
+ decode(op_bl, p);
+ decode(crc, p);
+ DECODE_FINISH(p);
+ uint32_t actual = op_bl.crc32c(-1);
+ if (actual != crc)
+ throw ceph::buffer::malformed_input("bad crc " + stringify(actual)
+ + " expected " + stringify(crc));
+}
+
+void bluefs_transaction_t::dump(Formatter *f) const
+{
+ f->dump_stream("uuid") << uuid;
+ f->dump_unsigned("seq", seq);
+ f->dump_unsigned("op_bl_length", op_bl.length());
+ f->dump_unsigned("crc", op_bl.crc32c(-1));
+}
+
+void bluefs_transaction_t::generate_test_instances(
+ list<bluefs_transaction_t*>& ls)
+{
+ ls.push_back(new bluefs_transaction_t);
+ ls.push_back(new bluefs_transaction_t);
+ ls.back()->op_init();
+ ls.back()->op_dir_create("dir");
+ ls.back()->op_dir_create("dir2");
+ bluefs_fnode_t fnode;
+ fnode.ino = 2;
+ ls.back()->op_file_update(fnode);
+ ls.back()->op_dir_link("dir", "file1", 2);
+ ls.back()->op_dir_unlink("dir", "file1");
+ ls.back()->op_file_remove(2);
+ ls.back()->op_dir_remove("dir2");
+}
+
+ostream& operator<<(ostream& out, const bluefs_transaction_t& t)
+{
+ return out << "txn(seq " << t.seq
+ << " len 0x" << std::hex << t.op_bl.length()
+ << " crc 0x" << t.op_bl.crc32c(-1)
+ << std::dec << ")";
+}