Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / mds / inode_backtrace.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2 // vim: ts=8 sw=2 smarttab
3
4 #include "inode_backtrace.h"
5
6 #include "common/Formatter.h"
7
8 /* inode_backpointer_t */
9
10 void inode_backpointer_t::encode(bufferlist& bl) const
11 {
12   ENCODE_START(2, 2, bl);
13   ::encode(dirino, bl);
14   ::encode(dname, bl);
15   ::encode(version, bl);
16   ENCODE_FINISH(bl);
17 }
18
19 void inode_backpointer_t::decode(bufferlist::iterator& bl)
20 {
21   DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
22   ::decode(dirino, bl);
23   ::decode(dname, bl);
24   ::decode(version, bl);
25   DECODE_FINISH(bl);
26 }
27
28 void inode_backpointer_t::decode_old(bufferlist::iterator& bl)
29 {
30   ::decode(dirino, bl);
31   ::decode(dname, bl);
32   ::decode(version, bl);
33 }
34
35 void inode_backpointer_t::dump(Formatter *f) const
36 {
37   f->dump_unsigned("dirino", dirino);
38   f->dump_string("dname", dname);
39   f->dump_unsigned("version", version);
40 }
41
42 void inode_backpointer_t::generate_test_instances(list<inode_backpointer_t*>& ls)
43 {
44   ls.push_back(new inode_backpointer_t);
45   ls.push_back(new inode_backpointer_t);
46   ls.back()->dirino = 1;
47   ls.back()->dname = "foo";
48   ls.back()->version = 123;
49 }
50
51
52 /*
53  * inode_backtrace_t
54  */
55
56 void inode_backtrace_t::encode(bufferlist& bl) const
57 {
58   ENCODE_START(5, 4, bl);
59   ::encode(ino, bl);
60   ::encode(ancestors, bl);
61   ::encode(pool, bl);
62   ::encode(old_pools, bl);
63   ENCODE_FINISH(bl);
64 }
65
66 void inode_backtrace_t::decode(bufferlist::iterator& bl)
67 {
68   DECODE_START_LEGACY_COMPAT_LEN(5, 4, 4, bl);
69   if (struct_v < 3)
70     return;  // sorry, the old data was crap
71   ::decode(ino, bl);
72   if (struct_v >= 4) {
73     ::decode(ancestors, bl);
74   } else {
75     __u32 n;
76     ::decode(n, bl);
77     while (n--) {
78       ancestors.push_back(inode_backpointer_t());
79       ancestors.back().decode_old(bl);
80     }
81   }
82   if (struct_v >= 5) {
83     ::decode(pool, bl);
84     ::decode(old_pools, bl);
85   }
86   DECODE_FINISH(bl);
87 }
88
89 void inode_backtrace_t::dump(Formatter *f) const
90 {
91   f->dump_unsigned("ino", ino);
92   f->open_array_section("ancestors");
93   for (vector<inode_backpointer_t>::const_iterator p = ancestors.begin(); p != ancestors.end(); ++p) {
94     f->open_object_section("backpointer");
95     p->dump(f);
96     f->close_section();
97   }
98   f->close_section();
99   f->dump_int("pool", pool);
100   f->open_array_section("old_pools");
101   for (set<int64_t>::iterator p = old_pools.begin(); p != old_pools.end(); ++p) {
102     f->dump_int("old_pool", *p);
103   }
104   f->close_section();
105 }
106
107 void inode_backtrace_t::generate_test_instances(list<inode_backtrace_t*>& ls)
108 {
109   ls.push_back(new inode_backtrace_t);
110   ls.push_back(new inode_backtrace_t);
111   ls.back()->ino = 1;
112   ls.back()->ancestors.push_back(inode_backpointer_t());
113   ls.back()->ancestors.back().dirino = 123;
114   ls.back()->ancestors.back().dname = "bar";
115   ls.back()->ancestors.back().version = 456;
116   ls.back()->pool = 0;
117   ls.back()->old_pools.insert(10);
118   ls.back()->old_pools.insert(7);
119 }
120
121 int inode_backtrace_t::compare(const inode_backtrace_t& other,
122                                bool *equivalent, bool *divergent) const
123 {
124   int min_size = MIN(ancestors.size(),other.ancestors.size());
125   *equivalent = true;
126   *divergent = false;
127   if (min_size == 0)
128     return 0;
129   int comparator = 0;
130   if (ancestors[0].version > other.ancestors[0].version)
131     comparator = 1;
132   else if (ancestors[0].version < other.ancestors[0].version)
133     comparator = -1;
134   if (ancestors[0].dirino != other.ancestors[0].dirino ||
135       ancestors[0].dname != other.ancestors[0].dname)
136     *divergent = true;
137   for (int i = 1; i < min_size; ++i) {
138     if (*divergent) {
139       /**
140        * we already know the dentries and versions are
141        * incompatible; no point checking farther
142        */
143       break;
144     }
145     if (ancestors[i].dirino != other.ancestors[i].dirino ||
146         ancestors[i].dname != other.ancestors[i].dname) {
147       *equivalent = false;
148       return comparator;
149     } else if (ancestors[i].version > other.ancestors[i].version) {
150       if (comparator < 0)
151         *divergent = true;
152       comparator = 1;
153     } else if (ancestors[i].version < other.ancestors[i].version) {
154       if (comparator > 0)
155         *divergent = true;
156       comparator = -1;
157     }
158   }
159   if (*divergent)
160     *equivalent = false;
161   return comparator;
162 }