Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / osd / Object.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2 #include "include/interval_set.h"
3 #include "include/buffer.h"
4 #include <list>
5 #include <map>
6 #include <set>
7 #include <iostream>
8
9 #include "Object.h"
10
11 void ContDesc::encode(bufferlist &bl) const
12 {
13   ENCODE_START(1, 1, bl);
14   ::encode(objnum, bl);
15   ::encode(cursnap, bl);
16   ::encode(seqnum, bl);
17   ::encode(prefix, bl);
18   ::encode(oid, bl);
19   ENCODE_FINISH(bl);
20 }
21
22 void ContDesc::decode(bufferlist::iterator &bl)
23 {
24   DECODE_START(1, bl);
25   ::decode(objnum, bl);
26   ::decode(cursnap, bl);
27   ::decode(seqnum, bl);
28   ::decode(prefix, bl);
29   ::decode(oid, bl);
30   DECODE_FINISH(bl);
31 }
32
33 std::ostream &operator<<(std::ostream &out, const ContDesc &rhs)
34 {
35   return out << "(ObjNum " << rhs.objnum
36              << " snap " << rhs.cursnap
37              << " seq_num " << rhs.seqnum
38              << ")";
39 }
40
41 void AppendGenerator::get_ranges_map(
42   const ContDesc &cont, std::map<uint64_t, uint64_t> &out) {
43   RandWrap rand(cont.seqnum);
44   uint64_t pos = off;
45   uint64_t limit = off + get_append_size(cont);
46   while (pos < limit) {
47     uint64_t segment_length = round_up(
48       rand() % (max_append_size - min_append_size),
49       alignment) + min_append_size;
50     assert(segment_length >= min_append_size);
51     if (segment_length + pos > limit) {
52       segment_length = limit - pos;
53     }
54     if (alignment)
55       assert(segment_length % alignment == 0);
56     out.insert(std::pair<uint64_t, uint64_t>(pos, segment_length));
57     pos += segment_length;
58   }
59 }
60
61 void VarLenGenerator::get_ranges_map(
62   const ContDesc &cont, std::map<uint64_t, uint64_t> &out) {
63   RandWrap rand(cont.seqnum);
64   uint64_t pos = 0;
65   uint64_t limit = get_length(cont);
66   bool include = false;
67   while (pos < limit) {
68     uint64_t segment_length = (rand() % (max_stride_size - min_stride_size)) + min_stride_size;
69     assert(segment_length < max_stride_size);
70     assert(segment_length >= min_stride_size);
71     if (segment_length + pos > limit) {
72       segment_length = limit - pos;
73     }
74     if (include) {
75       out.insert(std::pair<uint64_t, uint64_t>(pos, segment_length));
76       include = false;
77     } else {
78       include = true;
79     }
80     pos += segment_length;
81   }
82 }
83
84 void ObjectDesc::iterator::adjust_stack() {
85   while (!stack.empty() && pos >= stack.front().second.next) {
86     assert(pos == stack.front().second.next);
87     size = stack.front().second.size;
88     current = stack.front().first;
89     stack.pop_front();
90   }
91
92   if (stack.empty()) {
93     cur_valid_till = std::numeric_limits<uint64_t>::max();
94   } else {
95     cur_valid_till = stack.front().second.next;
96   }
97
98   while (current != layers.end() && !current->covers(pos)) {
99     uint64_t next = current->next(pos);
100     if (next < cur_valid_till) {
101       stack.push_front(
102         make_pair(
103           current,
104           StackState{next, size}
105           )
106         );
107       cur_valid_till = next;
108     }
109
110     ++current;
111   }
112
113   if (current == layers.end()) {
114     size = 0;
115   } else {
116     current->iter.seek(pos);
117     size = std::min(size, current->get_size());
118     cur_valid_till = std::min(
119       current->valid_till(pos),
120       cur_valid_till);
121   }
122 }
123
124 const ContDesc &ObjectDesc::most_recent() {
125   return layers.begin()->second;
126 }
127
128 void ObjectDesc::update(ContentsGenerator *gen, const ContDesc &next) {
129   layers.push_front(std::pair<ceph::shared_ptr<ContentsGenerator>, ContDesc>(ceph::shared_ptr<ContentsGenerator>(gen), next));
130   return;
131 }
132
133 bool ObjectDesc::check(bufferlist &to_check) {
134   iterator objiter = begin();
135   uint64_t error_at = 0;
136   if (!objiter.check_bl_advance(to_check, &error_at)) {
137     std::cout << "incorrect buffer at pos " << error_at << std::endl;
138     return false;
139   }
140
141   uint64_t size = layers.begin()->first->get_length(layers.begin()->second);
142   if (to_check.length() < size) {
143     std::cout << "only read " << to_check.length()
144               << " out of size " << size << std::endl;
145     return false;
146   }
147   return true;
148 }
149
150 bool ObjectDesc::check_sparse(const std::map<uint64_t, uint64_t>& extents,
151                               bufferlist &to_check)
152 {
153   uint64_t off = 0;
154   uint64_t pos = 0;
155   auto objiter = begin();
156   for (auto &&extiter : extents) {
157     // verify hole
158     {
159       bufferlist bl;
160       bl.append_zero(extiter.first - pos);
161       uint64_t error_at = 0;
162       if (!objiter.check_bl_advance(bl, &error_at)) {
163         std::cout << "sparse read omitted non-zero data at "
164                   << error_at << std::endl;
165         return false;
166       }
167     }
168
169     assert(off <= to_check.length());
170     pos = extiter.first;
171     objiter.seek(pos);
172
173     {
174       bufferlist bl;
175       bl.substr_of(
176         to_check,
177         off,
178         std::min(to_check.length() - off, extiter.second));
179       uint64_t error_at = 0;
180       if (!objiter.check_bl_advance(bl, &error_at)) {
181         std::cout << "incorrect buffer at pos " << error_at << std::endl;
182         return false;
183       }
184       off += extiter.second;
185       pos += extiter.second;
186     }
187
188     if (pos < extiter.first + extiter.second) {
189       std::cout << "reached end of iterator first" << std::endl;
190       return false;
191     }
192   }
193
194   // final hole
195   bufferlist bl;
196   uint64_t size = layers.begin()->first->get_length(layers.begin()->second);
197   bl.append_zero(size - pos);
198   uint64_t error_at;
199   if (!objiter.check_bl_advance(bl, &error_at)) {
200     std::cout << "sparse read omitted non-zero data at "
201               << error_at << std::endl;
202     return false;
203   }
204   return true;
205 }