X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmds%2Finode_backtrace.cc;fp=src%2Fceph%2Fsrc%2Fmds%2Finode_backtrace.cc;h=314f1751b5e0ef7381e888edac1acc9c0f39638d;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/mds/inode_backtrace.cc b/src/ceph/src/mds/inode_backtrace.cc new file mode 100644 index 0000000..314f175 --- /dev/null +++ b/src/ceph/src/mds/inode_backtrace.cc @@ -0,0 +1,162 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "inode_backtrace.h" + +#include "common/Formatter.h" + +/* inode_backpointer_t */ + +void inode_backpointer_t::encode(bufferlist& bl) const +{ + ENCODE_START(2, 2, bl); + ::encode(dirino, bl); + ::encode(dname, bl); + ::encode(version, bl); + ENCODE_FINISH(bl); +} + +void inode_backpointer_t::decode(bufferlist::iterator& bl) +{ + DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl); + ::decode(dirino, bl); + ::decode(dname, bl); + ::decode(version, bl); + DECODE_FINISH(bl); +} + +void inode_backpointer_t::decode_old(bufferlist::iterator& bl) +{ + ::decode(dirino, bl); + ::decode(dname, bl); + ::decode(version, bl); +} + +void inode_backpointer_t::dump(Formatter *f) const +{ + f->dump_unsigned("dirino", dirino); + f->dump_string("dname", dname); + f->dump_unsigned("version", version); +} + +void inode_backpointer_t::generate_test_instances(list& ls) +{ + ls.push_back(new inode_backpointer_t); + ls.push_back(new inode_backpointer_t); + ls.back()->dirino = 1; + ls.back()->dname = "foo"; + ls.back()->version = 123; +} + + +/* + * inode_backtrace_t + */ + +void inode_backtrace_t::encode(bufferlist& bl) const +{ + ENCODE_START(5, 4, bl); + ::encode(ino, bl); + ::encode(ancestors, bl); + ::encode(pool, bl); + ::encode(old_pools, bl); + ENCODE_FINISH(bl); +} + +void inode_backtrace_t::decode(bufferlist::iterator& bl) +{ + DECODE_START_LEGACY_COMPAT_LEN(5, 4, 4, bl); + if (struct_v < 3) + return; // sorry, the old data was crap + ::decode(ino, bl); + if (struct_v >= 4) { + ::decode(ancestors, bl); + } else { + __u32 n; + ::decode(n, bl); + while (n--) { + ancestors.push_back(inode_backpointer_t()); + ancestors.back().decode_old(bl); + } + } + if (struct_v >= 5) { + ::decode(pool, bl); + ::decode(old_pools, bl); + } + DECODE_FINISH(bl); +} + +void inode_backtrace_t::dump(Formatter *f) const +{ + f->dump_unsigned("ino", ino); + f->open_array_section("ancestors"); + for (vector::const_iterator p = ancestors.begin(); p != ancestors.end(); ++p) { + f->open_object_section("backpointer"); + p->dump(f); + f->close_section(); + } + f->close_section(); + f->dump_int("pool", pool); + f->open_array_section("old_pools"); + for (set::iterator p = old_pools.begin(); p != old_pools.end(); ++p) { + f->dump_int("old_pool", *p); + } + f->close_section(); +} + +void inode_backtrace_t::generate_test_instances(list& ls) +{ + ls.push_back(new inode_backtrace_t); + ls.push_back(new inode_backtrace_t); + ls.back()->ino = 1; + ls.back()->ancestors.push_back(inode_backpointer_t()); + ls.back()->ancestors.back().dirino = 123; + ls.back()->ancestors.back().dname = "bar"; + ls.back()->ancestors.back().version = 456; + ls.back()->pool = 0; + ls.back()->old_pools.insert(10); + ls.back()->old_pools.insert(7); +} + +int inode_backtrace_t::compare(const inode_backtrace_t& other, + bool *equivalent, bool *divergent) const +{ + int min_size = MIN(ancestors.size(),other.ancestors.size()); + *equivalent = true; + *divergent = false; + if (min_size == 0) + return 0; + int comparator = 0; + if (ancestors[0].version > other.ancestors[0].version) + comparator = 1; + else if (ancestors[0].version < other.ancestors[0].version) + comparator = -1; + if (ancestors[0].dirino != other.ancestors[0].dirino || + ancestors[0].dname != other.ancestors[0].dname) + *divergent = true; + for (int i = 1; i < min_size; ++i) { + if (*divergent) { + /** + * we already know the dentries and versions are + * incompatible; no point checking farther + */ + break; + } + if (ancestors[i].dirino != other.ancestors[i].dirino || + ancestors[i].dname != other.ancestors[i].dname) { + *equivalent = false; + return comparator; + } else if (ancestors[i].version > other.ancestors[i].version) { + if (comparator < 0) + *divergent = true; + comparator = 1; + } else if (ancestors[i].version < other.ancestors[i].version) { + if (comparator > 0) + *divergent = true; + comparator = -1; + } + } + if (*divergent) + *equivalent = false; + return comparator; +}