]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/inode_backtrace.cc
add subtree-ish sources for 12.0.3
[ceph.git] / 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 }