Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / os / bluestore / BlueStore.cc
1 // vim: ts=8 sw=2 smarttab
2 /*
3  * Ceph - scalable distributed file system
4  *
5  * Copyright (C) 2014 Red Hat
6  *
7  * This is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License version 2.1, as published by the Free Software
10  * Foundation.  See file COPYING.
11  *
12  */
13
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19
20 #include "include/cpp-btree/btree_set.h"
21
22 #include "BlueStore.h"
23 #include "os/kv.h"
24 #include "include/compat.h"
25 #include "include/intarith.h"
26 #include "include/stringify.h"
27 #include "common/errno.h"
28 #include "common/safe_io.h"
29 #include "Allocator.h"
30 #include "FreelistManager.h"
31 #include "BlueFS.h"
32 #include "BlueRocksEnv.h"
33 #include "auth/Crypto.h"
34 #include "common/EventTrace.h"
35
36 #define dout_context cct
37 #define dout_subsys ceph_subsys_bluestore
38
39 using bid_t = decltype(BlueStore::Blob::id);
40
41 // bluestore_cache_onode
42 MEMPOOL_DEFINE_OBJECT_FACTORY(BlueStore::Onode, bluestore_onode,
43                               bluestore_cache_onode);
44
45 // bluestore_cache_other
46 MEMPOOL_DEFINE_OBJECT_FACTORY(BlueStore::Buffer, bluestore_buffer,
47                               bluestore_cache_other);
48 MEMPOOL_DEFINE_OBJECT_FACTORY(BlueStore::Extent, bluestore_extent,
49                               bluestore_cache_other);
50 MEMPOOL_DEFINE_OBJECT_FACTORY(BlueStore::Blob, bluestore_blob,
51                               bluestore_cache_other);
52 MEMPOOL_DEFINE_OBJECT_FACTORY(BlueStore::SharedBlob, bluestore_shared_blob,
53                               bluestore_cache_other);
54
55 // bluestore_txc
56 MEMPOOL_DEFINE_OBJECT_FACTORY(BlueStore::TransContext, bluestore_transcontext,
57                               bluestore_txc);
58
59
60 // kv store prefixes
61 const string PREFIX_SUPER = "S";   // field -> value
62 const string PREFIX_STAT = "T";    // field -> value(int64 array)
63 const string PREFIX_COLL = "C";    // collection name -> cnode_t
64 const string PREFIX_OBJ = "O";     // object name -> onode_t
65 const string PREFIX_OMAP = "M";    // u64 + keyname -> value
66 const string PREFIX_DEFERRED = "L";  // id -> deferred_transaction_t
67 const string PREFIX_ALLOC = "B";   // u64 offset -> u64 length (freelist)
68 const string PREFIX_SHARED_BLOB = "X"; // u64 offset -> shared_blob_t
69
70 // write a label in the first block.  always use this size.  note that
71 // bluefs makes a matching assumption about the location of its
72 // superblock (always the second block of the device).
73 #define BDEV_LABEL_BLOCK_SIZE  4096
74
75 // reserve: label (4k) + bluefs super (4k), which means we start at 8k.
76 #define SUPER_RESERVED  8192
77
78 #define OBJECT_MAX_SIZE 0xffffffff // 32 bits
79
80
81 /*
82  * extent map blob encoding
83  *
84  * we use the low bits of the blobid field to indicate some common scenarios
85  * and spanning vs local ids.  See ExtentMap::{encode,decode}_some().
86  */
87 #define BLOBID_FLAG_CONTIGUOUS 0x1  // this extent starts at end of previous
88 #define BLOBID_FLAG_ZEROOFFSET 0x2  // blob_offset is 0
89 #define BLOBID_FLAG_SAMELENGTH 0x4  // length matches previous extent
90 #define BLOBID_FLAG_SPANNING   0x8  // has spanning blob id
91 #define BLOBID_SHIFT_BITS        4
92
93 /*
94  * object name key structure
95  *
96  * encoded u8: shard + 2^7 (so that it sorts properly)
97  * encoded u64: poolid + 2^63 (so that it sorts properly)
98  * encoded u32: hash (bit reversed)
99  *
100  * escaped string: namespace
101  *
102  * escaped string: key or object name
103  * 1 char: '<', '=', or '>'.  if =, then object key == object name, and
104  *         we are done.  otherwise, we are followed by the object name.
105  * escaped string: object name (unless '=' above)
106  *
107  * encoded u64: snap
108  * encoded u64: generation
109  * 'o'
110  */
111 #define ONODE_KEY_SUFFIX 'o'
112
113 /*
114  * extent shard key
115  *
116  * object prefix key
117  * u32
118  * 'x'
119  */
120 #define EXTENT_SHARD_KEY_SUFFIX 'x'
121
122 /*
123  * string encoding in the key
124  *
125  * The key string needs to lexicographically sort the same way that
126  * ghobject_t does.  We do this by escaping anything <= to '#' with #
127  * plus a 2 digit hex string, and anything >= '~' with ~ plus the two
128  * hex digits.
129  *
130  * We use ! as a terminator for strings; this works because it is < #
131  * and will get escaped if it is present in the string.
132  *
133  */
134 template<typename S>
135 static void append_escaped(const string &in, S *out)
136 {
137   char hexbyte[in.length() * 3 + 1];
138   char* ptr = &hexbyte[0];
139   for (string::const_iterator i = in.begin(); i != in.end(); ++i) {
140     if (*i <= '#') {
141       *ptr++ = '#';
142       *ptr++ = "0123456789abcdef"[(*i >> 4) & 0x0f];
143       *ptr++ = "0123456789abcdef"[*i & 0x0f];
144     } else if (*i >= '~') {
145       *ptr++ = '~';
146       *ptr++ = "0123456789abcdef"[(*i >> 4) & 0x0f];
147       *ptr++ = "0123456789abcdef"[*i & 0x0f];
148     } else {
149       *ptr++  = *i;
150     }
151   }
152   *ptr++ = '!';
153   out->append(hexbyte, ptr - &hexbyte[0]);
154 }
155
156 inline unsigned h2i(char c)
157 {
158   if ((c >= '0') && (c <= '9')) {
159     return c - 0x30;
160   } else if ((c >= 'a') && (c <= 'f')) {
161     return c - 'a' + 10;
162   } else if ((c >= 'A') && (c <= 'F')) {
163     return c - 'A' + 10;
164   } else {
165     return 256; // make it always larger than 255
166   }
167 }
168
169 static int decode_escaped(const char *p, string *out)
170 {
171   char buff[256];
172   char* ptr = &buff[0];
173   char* max = &buff[252];
174   const char *orig_p = p;
175   while (*p && *p != '!') {
176     if (*p == '#' || *p == '~') {
177       unsigned hex = 0;
178       p++;
179       hex = h2i(*p++) << 4;
180       if (hex > 255) {
181         return -EINVAL;
182       }
183       hex |= h2i(*p++);
184       if (hex > 255) {
185         return -EINVAL;
186       }
187       *ptr++ = hex;
188     } else {
189       *ptr++ = *p++;
190     }
191     if (ptr > max) {
192        out->append(buff, ptr-buff);
193        ptr = &buff[0];
194     }
195   }
196   if (ptr != buff) {
197      out->append(buff, ptr-buff);
198   }
199   return p - orig_p;
200 }
201
202 // some things we encode in binary (as le32 or le64); print the
203 // resulting key strings nicely
204 template<typename S>
205 static string pretty_binary_string(const S& in)
206 {
207   char buf[10];
208   string out;
209   out.reserve(in.length() * 3);
210   enum { NONE, HEX, STRING } mode = NONE;
211   unsigned from = 0, i;
212   for (i=0; i < in.length(); ++i) {
213     if ((in[i] < 32 || (unsigned char)in[i] > 126) ||
214         (mode == HEX && in.length() - i >= 4 &&
215          ((in[i] < 32 || (unsigned char)in[i] > 126) ||
216           (in[i+1] < 32 || (unsigned char)in[i+1] > 126) ||
217           (in[i+2] < 32 || (unsigned char)in[i+2] > 126) ||
218           (in[i+3] < 32 || (unsigned char)in[i+3] > 126)))) {
219       if (mode == STRING) {
220         out.append(in.c_str() + from, i - from);
221         out.push_back('\'');
222       }
223       if (mode != HEX) {
224         out.append("0x");
225         mode = HEX;
226       }
227       if (in.length() - i >= 4) {
228         // print a whole u32 at once
229         snprintf(buf, sizeof(buf), "%08x",
230                  (uint32_t)(((unsigned char)in[i] << 24) |
231                             ((unsigned char)in[i+1] << 16) |
232                             ((unsigned char)in[i+2] << 8) |
233                             ((unsigned char)in[i+3] << 0)));
234         i += 3;
235       } else {
236         snprintf(buf, sizeof(buf), "%02x", (int)(unsigned char)in[i]);
237       }
238       out.append(buf);
239     } else {
240       if (mode != STRING) {
241         out.push_back('\'');
242         mode = STRING;
243         from = i;
244       }
245     }
246   }
247   if (mode == STRING) {
248     out.append(in.c_str() + from, i - from);
249     out.push_back('\'');
250   }
251   return out;
252 }
253
254 template<typename T>
255 static void _key_encode_shard(shard_id_t shard, T *key)
256 {
257   key->push_back((char)((uint8_t)shard.id + (uint8_t)0x80));
258 }
259
260 static const char *_key_decode_shard(const char *key, shard_id_t *pshard)
261 {
262   pshard->id = (uint8_t)*key - (uint8_t)0x80;
263   return key + 1;
264 }
265
266 static void get_coll_key_range(const coll_t& cid, int bits,
267                                string *temp_start, string *temp_end,
268                                string *start, string *end)
269 {
270   temp_start->clear();
271   temp_end->clear();
272   start->clear();
273   end->clear();
274
275   spg_t pgid;
276   if (cid.is_pg(&pgid)) {
277     _key_encode_shard(pgid.shard, start);
278     *temp_start = *start;
279
280     _key_encode_u64(pgid.pool() + 0x8000000000000000ull, start);
281     _key_encode_u64((-2ll - pgid.pool()) + 0x8000000000000000ull, temp_start);
282
283     *end = *start;
284     *temp_end = *temp_start;
285
286     uint32_t reverse_hash = hobject_t::_reverse_bits(pgid.ps());
287     _key_encode_u32(reverse_hash, start);
288     _key_encode_u32(reverse_hash, temp_start);
289
290     uint64_t end_hash = reverse_hash  + (1ull << (32 - bits));
291     if (end_hash > 0xffffffffull)
292       end_hash = 0xffffffffull;
293
294     _key_encode_u32(end_hash, end);
295     _key_encode_u32(end_hash, temp_end);
296   } else {
297     _key_encode_shard(shard_id_t::NO_SHARD, start);
298     _key_encode_u64(-1ull + 0x8000000000000000ull, start);
299     *end = *start;
300     _key_encode_u32(0, start);
301     _key_encode_u32(0xffffffff, end);
302
303     // no separate temp section
304     *temp_start = *end;
305     *temp_end = *end;
306   }
307 }
308
309 static void get_shared_blob_key(uint64_t sbid, string *key)
310 {
311   key->clear();
312   _key_encode_u64(sbid, key);
313 }
314
315 static int get_key_shared_blob(const string& key, uint64_t *sbid)
316 {
317   const char *p = key.c_str();
318   if (key.length() < sizeof(uint64_t))
319     return -1;
320   _key_decode_u64(p, sbid);
321   return 0;
322 }
323
324 template<typename S>
325 static int get_key_object(const S& key, ghobject_t *oid)
326 {
327   int r;
328   const char *p = key.c_str();
329
330   if (key.length() < 1 + 8 + 4)
331     return -1;
332   p = _key_decode_shard(p, &oid->shard_id);
333
334   uint64_t pool;
335   p = _key_decode_u64(p, &pool);
336   oid->hobj.pool = pool - 0x8000000000000000ull;
337
338   unsigned hash;
339   p = _key_decode_u32(p, &hash);
340
341   oid->hobj.set_bitwise_key_u32(hash);
342
343   r = decode_escaped(p, &oid->hobj.nspace);
344   if (r < 0)
345     return -2;
346   p += r + 1;
347
348   string k;
349   r = decode_escaped(p, &k);
350   if (r < 0)
351     return -3;
352   p += r + 1;
353   if (*p == '=') {
354     // no key
355     ++p;
356     oid->hobj.oid.name = k;
357   } else if (*p == '<' || *p == '>') {
358     // key + name
359     ++p;
360     r = decode_escaped(p, &oid->hobj.oid.name);
361     if (r < 0)
362       return -5;
363     p += r + 1;
364     oid->hobj.set_key(k);
365   } else {
366     // malformed
367     return -6;
368   }
369
370   p = _key_decode_u64(p, &oid->hobj.snap.val);
371   p = _key_decode_u64(p, &oid->generation);
372
373   if (*p != ONODE_KEY_SUFFIX) {
374     return -7;
375   }
376   p++;
377   if (*p) {
378     // if we get something other than a null terminator here,
379     // something goes wrong.
380     return -8;
381   }
382
383   return 0;
384 }
385
386 template<typename S>
387 static void get_object_key(CephContext *cct, const ghobject_t& oid, S *key)
388 {
389   key->clear();
390
391   size_t max_len = 1 + 8 + 4 +
392                   (oid.hobj.nspace.length() * 3 + 1) +
393                   (oid.hobj.get_key().length() * 3 + 1) +
394                    1 + // for '<', '=', or '>'
395                   (oid.hobj.oid.name.length() * 3 + 1) +
396                    8 + 8 + 1;
397   key->reserve(max_len);
398
399   _key_encode_shard(oid.shard_id, key);
400   _key_encode_u64(oid.hobj.pool + 0x8000000000000000ull, key);
401   _key_encode_u32(oid.hobj.get_bitwise_key_u32(), key);
402
403   append_escaped(oid.hobj.nspace, key);
404
405   if (oid.hobj.get_key().length()) {
406     // is a key... could be < = or >.
407     append_escaped(oid.hobj.get_key(), key);
408     // (ASCII chars < = and > sort in that order, yay)
409     int r = oid.hobj.get_key().compare(oid.hobj.oid.name);
410     if (r) {
411       key->append(r > 0 ? ">" : "<");
412       append_escaped(oid.hobj.oid.name, key);
413     } else {
414       // same as no key
415       key->append("=");
416     }
417   } else {
418     // no key
419     append_escaped(oid.hobj.oid.name, key);
420     key->append("=");
421   }
422
423   _key_encode_u64(oid.hobj.snap, key);
424   _key_encode_u64(oid.generation, key);
425
426   key->push_back(ONODE_KEY_SUFFIX);
427
428   // sanity check
429   if (true) {
430     ghobject_t t;
431     int r = get_key_object(*key, &t);
432     if (r || t != oid) {
433       derr << "  r " << r << dendl;
434       derr << "key " << pretty_binary_string(*key) << dendl;
435       derr << "oid " << oid << dendl;
436       derr << "  t " << t << dendl;
437       assert(r == 0 && t == oid);
438     }
439   }
440 }
441
442
443 // extent shard keys are the onode key, plus a u32, plus 'x'.  the trailing
444 // char lets us quickly test whether it is a shard key without decoding any
445 // of the prefix bytes.
446 template<typename S>
447 static void get_extent_shard_key(const S& onode_key, uint32_t offset,
448                                  string *key)
449 {
450   key->clear();
451   key->reserve(onode_key.length() + 4 + 1);
452   key->append(onode_key.c_str(), onode_key.size());
453   _key_encode_u32(offset, key);
454   key->push_back(EXTENT_SHARD_KEY_SUFFIX);
455 }
456
457 static void rewrite_extent_shard_key(uint32_t offset, string *key)
458 {
459   assert(key->size() > sizeof(uint32_t) + 1);
460   assert(*key->rbegin() == EXTENT_SHARD_KEY_SUFFIX);
461   _key_encode_u32(offset, key->size() - sizeof(uint32_t) - 1, key);
462 }
463
464 template<typename S>
465 static void generate_extent_shard_key_and_apply(
466   const S& onode_key,
467   uint32_t offset,
468   string *key,
469   std::function<void(const string& final_key)> apply)
470 {
471   if (key->empty()) { // make full key
472     assert(!onode_key.empty());
473     get_extent_shard_key(onode_key, offset, key);
474   } else {
475     rewrite_extent_shard_key(offset, key);
476   }
477   apply(*key);
478 }
479
480 int get_key_extent_shard(const string& key, string *onode_key, uint32_t *offset)
481 {
482   assert(key.size() > sizeof(uint32_t) + 1);
483   assert(*key.rbegin() == EXTENT_SHARD_KEY_SUFFIX);
484   int okey_len = key.size() - sizeof(uint32_t) - 1;
485   *onode_key = key.substr(0, okey_len);
486   const char *p = key.data() + okey_len;
487   _key_decode_u32(p, offset);
488   return 0;
489 }
490
491 static bool is_extent_shard_key(const string& key)
492 {
493   return *key.rbegin() == EXTENT_SHARD_KEY_SUFFIX;
494 }
495
496 // '-' < '.' < '~'
497 static void get_omap_header(uint64_t id, string *out)
498 {
499   _key_encode_u64(id, out);
500   out->push_back('-');
501 }
502
503 // hmm, I don't think there's any need to escape the user key since we
504 // have a clean prefix.
505 static void get_omap_key(uint64_t id, const string& key, string *out)
506 {
507   _key_encode_u64(id, out);
508   out->push_back('.');
509   out->append(key);
510 }
511
512 static void rewrite_omap_key(uint64_t id, string old, string *out)
513 {
514   _key_encode_u64(id, out);
515   out->append(old.c_str() + out->length(), old.size() - out->length());
516 }
517
518 static void decode_omap_key(const string& key, string *user_key)
519 {
520   *user_key = key.substr(sizeof(uint64_t) + 1);
521 }
522
523 static void get_omap_tail(uint64_t id, string *out)
524 {
525   _key_encode_u64(id, out);
526   out->push_back('~');
527 }
528
529 static void get_deferred_key(uint64_t seq, string *out)
530 {
531   _key_encode_u64(seq, out);
532 }
533
534
535 // merge operators
536
537 struct Int64ArrayMergeOperator : public KeyValueDB::MergeOperator {
538   void merge_nonexistent(
539     const char *rdata, size_t rlen, std::string *new_value) override {
540     *new_value = std::string(rdata, rlen);
541   }
542   void merge(
543     const char *ldata, size_t llen,
544     const char *rdata, size_t rlen,
545     std::string *new_value) override {
546     assert(llen == rlen);
547     assert((rlen % 8) == 0);
548     new_value->resize(rlen);
549     const __le64* lv = (const __le64*)ldata;
550     const __le64* rv = (const __le64*)rdata;
551     __le64* nv = &(__le64&)new_value->at(0);
552     for (size_t i = 0; i < rlen >> 3; ++i) {
553       nv[i] = lv[i] + rv[i];
554     }
555   }
556   // We use each operator name and each prefix to construct the
557   // overall RocksDB operator name for consistency check at open time.
558   string name() const override {
559     return "int64_array";
560   }
561 };
562
563
564 // Buffer
565
566 ostream& operator<<(ostream& out, const BlueStore::Buffer& b)
567 {
568   out << "buffer(" << &b << " space " << b.space << " 0x" << std::hex
569       << b.offset << "~" << b.length << std::dec
570       << " " << BlueStore::Buffer::get_state_name(b.state);
571   if (b.flags)
572     out << " " << BlueStore::Buffer::get_flag_name(b.flags);
573   return out << ")";
574 }
575
576 // Garbage Collector
577
578 void BlueStore::GarbageCollector::process_protrusive_extents(
579   const BlueStore::ExtentMap& extent_map, 
580   uint64_t start_offset,
581   uint64_t end_offset,
582   uint64_t start_touch_offset,
583   uint64_t end_touch_offset,
584   uint64_t min_alloc_size)
585 {
586   assert(start_offset <= start_touch_offset && end_offset>= end_touch_offset);
587
588   uint64_t lookup_start_offset = P2ALIGN(start_offset, min_alloc_size);
589   uint64_t lookup_end_offset = ROUND_UP_TO(end_offset, min_alloc_size);
590
591   dout(30) << __func__ << " (hex): [" << std::hex
592            << lookup_start_offset << ", " << lookup_end_offset 
593            << ")" << std::dec << dendl;
594
595   for (auto it = extent_map.seek_lextent(lookup_start_offset);
596        it != extent_map.extent_map.end() &&
597          it->logical_offset < lookup_end_offset;
598        ++it) {
599     uint64_t alloc_unit_start = it->logical_offset / min_alloc_size;
600     uint64_t alloc_unit_end = (it->logical_end() - 1) / min_alloc_size;
601
602     dout(30) << __func__ << " " << *it
603              << "alloc_units: " << alloc_unit_start << ".." << alloc_unit_end
604              << dendl;
605
606     Blob* b = it->blob.get();
607
608     if (it->logical_offset >=start_touch_offset &&
609         it->logical_end() <= end_touch_offset) {
610       // Process extents within the range affected by 
611       // the current write request.
612       // Need to take into account if existing extents
613       // can be merged with them (uncompressed case)
614       if (!b->get_blob().is_compressed()) {
615         if (blob_info_counted && used_alloc_unit == alloc_unit_start) {
616           --blob_info_counted->expected_allocations; // don't need to allocate
617                                                      // new AU for compressed
618                                                      // data since another
619                                                      // collocated uncompressed
620                                                      // blob already exists
621           dout(30) << __func__  << " --expected:"
622                    << alloc_unit_start << dendl;
623         }
624         used_alloc_unit = alloc_unit_end;
625         blob_info_counted =  nullptr;
626       }
627     } else if (b->get_blob().is_compressed()) {
628
629       // additionally we take compressed blobs that were not impacted
630       // by the write into account too
631       BlobInfo& bi =
632         affected_blobs.emplace(
633           b, BlobInfo(b->get_referenced_bytes())).first->second;
634
635       int adjust =
636        (used_alloc_unit && used_alloc_unit == alloc_unit_start) ? 0 : 1;
637       bi.expected_allocations += alloc_unit_end - alloc_unit_start + adjust;
638       dout(30) << __func__  << " expected_allocations=" 
639                << bi.expected_allocations << " end_au:"
640                << alloc_unit_end << dendl;
641
642       blob_info_counted =  &bi;
643       used_alloc_unit = alloc_unit_end;
644
645       assert(it->length <= bi.referenced_bytes);
646        bi.referenced_bytes -= it->length;
647       dout(30) << __func__ << " affected_blob:" << *b
648                << " unref 0x" << std::hex << it->length
649                << " referenced = 0x" << bi.referenced_bytes
650                << std::dec << dendl;
651       // NOTE: we can't move specific blob to resulting GC list here
652       // when reference counter == 0 since subsequent extents might
653       // decrement its expected_allocation. 
654       // Hence need to enumerate all the extents first.
655       if (!bi.collect_candidate) {
656         bi.first_lextent = it;
657         bi.collect_candidate = true;
658       }
659       bi.last_lextent = it;
660     } else {
661       if (blob_info_counted && used_alloc_unit == alloc_unit_start) {
662         // don't need to allocate new AU for compressed data since another
663         // collocated uncompressed blob already exists
664         --blob_info_counted->expected_allocations;
665         dout(30) << __func__  << " --expected_allocations:"
666                  << alloc_unit_start << dendl;
667       }
668       used_alloc_unit = alloc_unit_end;
669       blob_info_counted = nullptr;
670     }
671   }
672
673   for (auto b_it = affected_blobs.begin();
674        b_it != affected_blobs.end();
675        ++b_it) {
676     Blob* b = b_it->first;
677     BlobInfo& bi = b_it->second;
678     if (bi.referenced_bytes == 0) {
679       uint64_t len_on_disk = b_it->first->get_blob().get_ondisk_length();
680       int64_t blob_expected_for_release =
681         ROUND_UP_TO(len_on_disk, min_alloc_size) / min_alloc_size;
682
683       dout(30) << __func__ << " " << *(b_it->first)
684                << " expected4release=" << blob_expected_for_release
685                << " expected_allocations=" << bi.expected_allocations
686                << dendl;
687       int64_t benefit = blob_expected_for_release - bi.expected_allocations;
688       if (benefit >= g_conf->bluestore_gc_enable_blob_threshold) {
689         if (bi.collect_candidate) {
690           auto it = bi.first_lextent;
691           bool bExit = false;
692           do {
693             if (it->blob.get() == b) {
694               extents_to_collect.emplace_back(it->logical_offset, it->length);
695             }
696             bExit = it == bi.last_lextent;
697             ++it;
698           } while (!bExit);
699         }
700         expected_for_release += blob_expected_for_release;
701         expected_allocations += bi.expected_allocations;
702       }
703     }
704   }
705 }
706
707 int64_t BlueStore::GarbageCollector::estimate(
708   uint64_t start_offset,
709   uint64_t length,
710   const BlueStore::ExtentMap& extent_map,
711   const BlueStore::old_extent_map_t& old_extents,
712   uint64_t min_alloc_size)
713 {
714
715   affected_blobs.clear();
716   extents_to_collect.clear();
717   used_alloc_unit = boost::optional<uint64_t >();
718   blob_info_counted = nullptr;
719
720   gc_start_offset = start_offset;
721   gc_end_offset = start_offset + length;
722
723   uint64_t end_offset = start_offset + length;
724
725   for (auto it = old_extents.begin(); it != old_extents.end(); ++it) {
726     Blob* b = it->e.blob.get();
727     if (b->get_blob().is_compressed()) {
728
729       // update gc_start_offset/gc_end_offset if needed
730       gc_start_offset = min(gc_start_offset, (uint64_t)it->e.blob_start());
731       gc_end_offset = max(gc_end_offset, (uint64_t)it->e.blob_end());
732
733       auto o = it->e.logical_offset;
734       auto l = it->e.length;
735
736       uint64_t ref_bytes = b->get_referenced_bytes();
737       // micro optimization to bypass blobs that have no more references
738       if (ref_bytes != 0) {
739         dout(30) << __func__ << " affected_blob:" << *b
740                  << " unref 0x" << std::hex << o << "~" << l
741                  << std::dec << dendl;
742         affected_blobs.emplace(b, BlobInfo(ref_bytes));
743       }
744     }
745   }
746   dout(30) << __func__ << " gc range(hex): [" << std::hex
747            << gc_start_offset << ", " << gc_end_offset 
748            << ")" << std::dec << dendl;
749
750   // enumerate preceeding extents to check if they reference affected blobs
751   if (gc_start_offset < start_offset || gc_end_offset > end_offset) {
752     process_protrusive_extents(extent_map,
753                                gc_start_offset,
754                                gc_end_offset,
755                                start_offset,
756                                end_offset,
757                                min_alloc_size);
758   }
759   return expected_for_release - expected_allocations;
760 }
761
762 // Cache
763
764 BlueStore::Cache *BlueStore::Cache::create(CephContext* cct, string type,
765                                            PerfCounters *logger)
766 {
767   Cache *c = nullptr;
768
769   if (type == "lru")
770     c = new LRUCache(cct);
771   else if (type == "2q")
772     c = new TwoQCache(cct);
773   else
774     assert(0 == "unrecognized cache type");
775
776   c->logger = logger;
777   return c;
778 }
779
780 void BlueStore::Cache::trim_all()
781 {
782   std::lock_guard<std::recursive_mutex> l(lock);
783   _trim(0, 0);
784 }
785
786 void BlueStore::Cache::trim(
787   uint64_t target_bytes,
788   float target_meta_ratio,
789   float target_data_ratio,
790   float bytes_per_onode)
791 {
792   std::lock_guard<std::recursive_mutex> l(lock);
793   uint64_t current_meta = _get_num_onodes() * bytes_per_onode;
794   uint64_t current_buffer = _get_buffer_bytes();
795   uint64_t current = current_meta + current_buffer;
796
797   uint64_t target_meta = target_bytes * target_meta_ratio;
798   uint64_t target_buffer = target_bytes * target_data_ratio;
799
800   // correct for overflow or float imprecision
801   target_meta = min(target_bytes, target_meta);
802   target_buffer = min(target_bytes - target_meta, target_buffer);
803
804   if (current <= target_bytes) {
805     dout(10) << __func__
806              << " shard target " << pretty_si_t(target_bytes)
807              << " meta/data ratios " << target_meta_ratio
808              << " + " << target_data_ratio << " ("
809              << pretty_si_t(target_meta) << " + "
810              << pretty_si_t(target_buffer) << "), "
811              << " current " << pretty_si_t(current) << " ("
812              << pretty_si_t(current_meta) << " + "
813              << pretty_si_t(current_buffer) << ")"
814              << dendl;
815     return;
816   }
817
818   uint64_t need_to_free = current - target_bytes;
819   uint64_t free_buffer = 0;
820   uint64_t free_meta = 0;
821   if (current_buffer > target_buffer) {
822     free_buffer = current_buffer - target_buffer;
823     if (free_buffer > need_to_free) {
824       free_buffer = need_to_free;
825     }
826   }
827   free_meta = need_to_free - free_buffer;
828
829   // start bounds at what we have now
830   uint64_t max_buffer = current_buffer - free_buffer;
831   uint64_t max_meta = current_meta - free_meta;
832   uint64_t max_onodes = max_meta / bytes_per_onode;
833
834   dout(10) << __func__
835            << " shard target " << pretty_si_t(target_bytes)
836            << " ratio " << target_meta_ratio << " ("
837            << pretty_si_t(target_meta) << " + "
838            << pretty_si_t(target_buffer) << "), "
839            << " current " << pretty_si_t(current) << " ("
840            << pretty_si_t(current_meta) << " + "
841            << pretty_si_t(current_buffer) << "),"
842            << " need_to_free " << pretty_si_t(need_to_free) << " ("
843            << pretty_si_t(free_meta) << " + "
844            << pretty_si_t(free_buffer) << ")"
845            << " -> max " << max_onodes << " onodes + "
846            << max_buffer << " buffer"
847            << dendl;
848   _trim(max_onodes, max_buffer);
849 }
850
851
852 // LRUCache
853 #undef dout_prefix
854 #define dout_prefix *_dout << "bluestore.LRUCache(" << this << ") "
855
856 void BlueStore::LRUCache::_touch_onode(OnodeRef& o)
857 {
858   auto p = onode_lru.iterator_to(*o);
859   onode_lru.erase(p);
860   onode_lru.push_front(*o);
861 }
862
863 void BlueStore::LRUCache::_trim(uint64_t onode_max, uint64_t buffer_max)
864 {
865   dout(20) << __func__ << " onodes " << onode_lru.size() << " / " << onode_max
866            << " buffers " << buffer_size << " / " << buffer_max
867            << dendl;
868
869   _audit("trim start");
870
871   // buffers
872   while (buffer_size > buffer_max) {
873     auto i = buffer_lru.rbegin();
874     if (i == buffer_lru.rend()) {
875       // stop if buffer_lru is now empty
876       break;
877     }
878
879     Buffer *b = &*i;
880     assert(b->is_clean());
881     dout(20) << __func__ << " rm " << *b << dendl;
882     b->space->_rm_buffer(this, b);
883   }
884
885   // onodes
886   int num = onode_lru.size() - onode_max;
887   if (num <= 0)
888     return; // don't even try
889
890   auto p = onode_lru.end();
891   assert(p != onode_lru.begin());
892   --p;
893   int skipped = 0;
894   int max_skipped = g_conf->bluestore_cache_trim_max_skip_pinned;
895   while (num > 0) {
896     Onode *o = &*p;
897     int refs = o->nref.load();
898     if (refs > 1) {
899       dout(20) << __func__ << "  " << o->oid << " has " << refs
900                << " refs, skipping" << dendl;
901       if (++skipped >= max_skipped) {
902         dout(20) << __func__ << " maximum skip pinned reached; stopping with "
903                  << num << " left to trim" << dendl;
904         break;
905       }
906
907       if (p == onode_lru.begin()) {
908         break;
909       } else {
910         p--;
911         num--;
912         continue;
913       }
914     }
915     dout(30) << __func__ << "  rm " << o->oid << dendl;
916     if (p != onode_lru.begin()) {
917       onode_lru.erase(p--);
918     } else {
919       onode_lru.erase(p);
920       assert(num == 1);
921     }
922     o->get();  // paranoia
923     o->c->onode_map.remove(o->oid);
924     o->put();
925     --num;
926   }
927 }
928
929 #ifdef DEBUG_CACHE
930 void BlueStore::LRUCache::_audit(const char *when)
931 {
932   dout(10) << __func__ << " " << when << " start" << dendl;
933   uint64_t s = 0;
934   for (auto i = buffer_lru.begin(); i != buffer_lru.end(); ++i) {
935     s += i->length;
936   }
937   if (s != buffer_size) {
938     derr << __func__ << " buffer_size " << buffer_size << " actual " << s
939          << dendl;
940     for (auto i = buffer_lru.begin(); i != buffer_lru.end(); ++i) {
941       derr << __func__ << " " << *i << dendl;
942     }
943     assert(s == buffer_size);
944   }
945   dout(20) << __func__ << " " << when << " buffer_size " << buffer_size
946            << " ok" << dendl;
947 }
948 #endif
949
950 // TwoQCache
951 #undef dout_prefix
952 #define dout_prefix *_dout << "bluestore.2QCache(" << this << ") "
953
954
955 void BlueStore::TwoQCache::_touch_onode(OnodeRef& o)
956 {
957   auto p = onode_lru.iterator_to(*o);
958   onode_lru.erase(p);
959   onode_lru.push_front(*o);
960 }
961
962 void BlueStore::TwoQCache::_add_buffer(Buffer *b, int level, Buffer *near)
963 {
964   dout(20) << __func__ << " level " << level << " near " << near
965            << " on " << *b
966            << " which has cache_private " << b->cache_private << dendl;
967   if (near) {
968     b->cache_private = near->cache_private;
969     switch (b->cache_private) {
970     case BUFFER_WARM_IN:
971       buffer_warm_in.insert(buffer_warm_in.iterator_to(*near), *b);
972       break;
973     case BUFFER_WARM_OUT:
974       assert(b->is_empty());
975       buffer_warm_out.insert(buffer_warm_out.iterator_to(*near), *b);
976       break;
977     case BUFFER_HOT:
978       buffer_hot.insert(buffer_hot.iterator_to(*near), *b);
979       break;
980     default:
981       assert(0 == "bad cache_private");
982     }
983   } else if (b->cache_private == BUFFER_NEW) {
984     b->cache_private = BUFFER_WARM_IN;
985     if (level > 0) {
986       buffer_warm_in.push_front(*b);
987     } else {
988       // take caller hint to start at the back of the warm queue
989       buffer_warm_in.push_back(*b);
990     }
991   } else {
992     // we got a hint from discard
993     switch (b->cache_private) {
994     case BUFFER_WARM_IN:
995       // stay in warm_in.  move to front, even though 2Q doesn't actually
996       // do this.
997       dout(20) << __func__ << " move to front of warm " << *b << dendl;
998       buffer_warm_in.push_front(*b);
999       break;
1000     case BUFFER_WARM_OUT:
1001       b->cache_private = BUFFER_HOT;
1002       // move to hot.  fall-thru
1003     case BUFFER_HOT:
1004       dout(20) << __func__ << " move to front of hot " << *b << dendl;
1005       buffer_hot.push_front(*b);
1006       break;
1007     default:
1008       assert(0 == "bad cache_private");
1009     }
1010   }
1011   if (!b->is_empty()) {
1012     buffer_bytes += b->length;
1013     buffer_list_bytes[b->cache_private] += b->length;
1014   }
1015 }
1016
1017 void BlueStore::TwoQCache::_rm_buffer(Buffer *b)
1018 {
1019   dout(20) << __func__ << " " << *b << dendl;
1020  if (!b->is_empty()) {
1021     assert(buffer_bytes >= b->length);
1022     buffer_bytes -= b->length;
1023     assert(buffer_list_bytes[b->cache_private] >= b->length);
1024     buffer_list_bytes[b->cache_private] -= b->length;
1025   }
1026   switch (b->cache_private) {
1027   case BUFFER_WARM_IN:
1028     buffer_warm_in.erase(buffer_warm_in.iterator_to(*b));
1029     break;
1030   case BUFFER_WARM_OUT:
1031     buffer_warm_out.erase(buffer_warm_out.iterator_to(*b));
1032     break;
1033   case BUFFER_HOT:
1034     buffer_hot.erase(buffer_hot.iterator_to(*b));
1035     break;
1036   default:
1037     assert(0 == "bad cache_private");
1038   }
1039 }
1040
1041 void BlueStore::TwoQCache::_move_buffer(Cache *srcc, Buffer *b)
1042 {
1043   TwoQCache *src = static_cast<TwoQCache*>(srcc);
1044   src->_rm_buffer(b);
1045
1046   // preserve which list we're on (even if we can't preserve the order!)
1047   switch (b->cache_private) {
1048   case BUFFER_WARM_IN:
1049     assert(!b->is_empty());
1050     buffer_warm_in.push_back(*b);
1051     break;
1052   case BUFFER_WARM_OUT:
1053     assert(b->is_empty());
1054     buffer_warm_out.push_back(*b);
1055     break;
1056   case BUFFER_HOT:
1057     assert(!b->is_empty());
1058     buffer_hot.push_back(*b);
1059     break;
1060   default:
1061     assert(0 == "bad cache_private");
1062   }
1063   if (!b->is_empty()) {
1064     buffer_bytes += b->length;
1065     buffer_list_bytes[b->cache_private] += b->length;
1066   }
1067 }
1068
1069 void BlueStore::TwoQCache::_adjust_buffer_size(Buffer *b, int64_t delta)
1070 {
1071   dout(20) << __func__ << " delta " << delta << " on " << *b << dendl;
1072   if (!b->is_empty()) {
1073     assert((int64_t)buffer_bytes + delta >= 0);
1074     buffer_bytes += delta;
1075     assert((int64_t)buffer_list_bytes[b->cache_private] + delta >= 0);
1076     buffer_list_bytes[b->cache_private] += delta;
1077   }
1078 }
1079
1080 void BlueStore::TwoQCache::_trim(uint64_t onode_max, uint64_t buffer_max)
1081 {
1082   dout(20) << __func__ << " onodes " << onode_lru.size() << " / " << onode_max
1083            << " buffers " << buffer_bytes << " / " << buffer_max
1084            << dendl;
1085
1086   _audit("trim start");
1087
1088   // buffers
1089   if (buffer_bytes > buffer_max) {
1090     uint64_t kin = buffer_max * cct->_conf->bluestore_2q_cache_kin_ratio;
1091     uint64_t khot = buffer_max - kin;
1092
1093     // pre-calculate kout based on average buffer size too,
1094     // which is typical(the warm_in and hot lists may change later)
1095     uint64_t kout = 0;
1096     uint64_t buffer_num = buffer_hot.size() + buffer_warm_in.size();
1097     if (buffer_num) {
1098       uint64_t buffer_avg_size = buffer_bytes / buffer_num;
1099       assert(buffer_avg_size);
1100       uint64_t calculated_buffer_num = buffer_max / buffer_avg_size;
1101       kout = calculated_buffer_num * cct->_conf->bluestore_2q_cache_kout_ratio;
1102     }
1103
1104     if (buffer_list_bytes[BUFFER_HOT] < khot) {
1105       // hot is small, give slack to warm_in
1106       kin += khot - buffer_list_bytes[BUFFER_HOT];
1107     } else if (buffer_list_bytes[BUFFER_WARM_IN] < kin) {
1108       // warm_in is small, give slack to hot
1109       khot += kin - buffer_list_bytes[BUFFER_WARM_IN];
1110     }
1111
1112     // adjust warm_in list
1113     int64_t to_evict_bytes = buffer_list_bytes[BUFFER_WARM_IN] - kin;
1114     uint64_t evicted = 0;
1115
1116     while (to_evict_bytes > 0) {
1117       auto p = buffer_warm_in.rbegin();
1118       if (p == buffer_warm_in.rend()) {
1119         // stop if warm_in list is now empty
1120         break;
1121       }
1122
1123       Buffer *b = &*p;
1124       assert(b->is_clean());
1125       dout(20) << __func__ << " buffer_warm_in -> out " << *b << dendl;
1126       assert(buffer_bytes >= b->length);
1127       buffer_bytes -= b->length;
1128       assert(buffer_list_bytes[BUFFER_WARM_IN] >= b->length);
1129       buffer_list_bytes[BUFFER_WARM_IN] -= b->length;
1130       to_evict_bytes -= b->length;
1131       evicted += b->length;
1132       b->state = Buffer::STATE_EMPTY;
1133       b->data.clear();
1134       buffer_warm_in.erase(buffer_warm_in.iterator_to(*b));
1135       buffer_warm_out.push_front(*b);
1136       b->cache_private = BUFFER_WARM_OUT;
1137     }
1138
1139     if (evicted > 0) {
1140       dout(20) << __func__ << " evicted " << prettybyte_t(evicted)
1141                << " from warm_in list, done evicting warm_in buffers"
1142                << dendl;
1143     }
1144
1145     // adjust hot list
1146     to_evict_bytes = buffer_list_bytes[BUFFER_HOT] - khot;
1147     evicted = 0;
1148
1149     while (to_evict_bytes > 0) {
1150       auto p = buffer_hot.rbegin();
1151       if (p == buffer_hot.rend()) {
1152         // stop if hot list is now empty
1153         break;
1154       }
1155
1156       Buffer *b = &*p;
1157       dout(20) << __func__ << " buffer_hot rm " << *b << dendl;
1158       assert(b->is_clean());
1159       // adjust evict size before buffer goes invalid
1160       to_evict_bytes -= b->length;
1161       evicted += b->length;
1162       b->space->_rm_buffer(this, b);
1163     }
1164
1165     if (evicted > 0) {
1166       dout(20) << __func__ << " evicted " << prettybyte_t(evicted)
1167                << " from hot list, done evicting hot buffers"
1168                << dendl;
1169     }
1170
1171     // adjust warm out list too, if necessary
1172     int64_t num = buffer_warm_out.size() - kout;
1173     while (num-- > 0) {
1174       Buffer *b = &*buffer_warm_out.rbegin();
1175       assert(b->is_empty());
1176       dout(20) << __func__ << " buffer_warm_out rm " << *b << dendl;
1177       b->space->_rm_buffer(this, b);
1178     }
1179   }
1180
1181   // onodes
1182   int num = onode_lru.size() - onode_max;
1183   if (num <= 0)
1184     return; // don't even try
1185
1186   auto p = onode_lru.end();
1187   assert(p != onode_lru.begin());
1188   --p;
1189   int skipped = 0;
1190   int max_skipped = g_conf->bluestore_cache_trim_max_skip_pinned;
1191   while (num > 0) {
1192     Onode *o = &*p;
1193     dout(20) << __func__ << " considering " << o << dendl;
1194     int refs = o->nref.load();
1195     if (refs > 1) {
1196       dout(20) << __func__ << "  " << o->oid << " has " << refs
1197                << " refs; skipping" << dendl;
1198       if (++skipped >= max_skipped) {
1199         dout(20) << __func__ << " maximum skip pinned reached; stopping with "
1200                  << num << " left to trim" << dendl;
1201         break;
1202       }
1203
1204       if (p == onode_lru.begin()) {
1205         break;
1206       } else {
1207         p--;
1208         num--;
1209         continue;
1210       }
1211     }
1212     dout(30) << __func__ << " " << o->oid << " num=" << num <<" lru size="<<onode_lru.size()<< dendl;
1213     if (p != onode_lru.begin()) {
1214       onode_lru.erase(p--);
1215     } else {
1216       onode_lru.erase(p);
1217       assert(num == 1);
1218     }
1219     o->get();  // paranoia
1220     o->c->onode_map.remove(o->oid);
1221     o->put();
1222     --num;
1223   }
1224 }
1225
1226 #ifdef DEBUG_CACHE
1227 void BlueStore::TwoQCache::_audit(const char *when)
1228 {
1229   dout(10) << __func__ << " " << when << " start" << dendl;
1230   uint64_t s = 0;
1231   for (auto i = buffer_hot.begin(); i != buffer_hot.end(); ++i) {
1232     s += i->length;
1233   }
1234
1235   uint64_t hot_bytes = s;
1236   if (hot_bytes != buffer_list_bytes[BUFFER_HOT]) {
1237     derr << __func__ << " hot_list_bytes "
1238          << buffer_list_bytes[BUFFER_HOT]
1239          << " != actual " << hot_bytes
1240          << dendl;
1241     assert(hot_bytes == buffer_list_bytes[BUFFER_HOT]);
1242   }
1243
1244   for (auto i = buffer_warm_in.begin(); i != buffer_warm_in.end(); ++i) {
1245     s += i->length;
1246   }
1247
1248   uint64_t warm_in_bytes = s - hot_bytes;
1249   if (warm_in_bytes != buffer_list_bytes[BUFFER_WARM_IN]) {
1250     derr << __func__ << " warm_in_list_bytes "
1251          << buffer_list_bytes[BUFFER_WARM_IN]
1252          << " != actual " << warm_in_bytes
1253          << dendl;
1254     assert(warm_in_bytes == buffer_list_bytes[BUFFER_WARM_IN]);
1255   }
1256
1257   if (s != buffer_bytes) {
1258     derr << __func__ << " buffer_bytes " << buffer_bytes << " actual " << s
1259          << dendl;
1260     assert(s == buffer_bytes);
1261   }
1262
1263   dout(20) << __func__ << " " << when << " buffer_bytes " << buffer_bytes
1264            << " ok" << dendl;
1265 }
1266 #endif
1267
1268
1269 // BufferSpace
1270
1271 #undef dout_prefix
1272 #define dout_prefix *_dout << "bluestore.BufferSpace(" << this << " in " << cache << ") "
1273
1274 void BlueStore::BufferSpace::_clear(Cache* cache)
1275 {
1276   // note: we already hold cache->lock
1277   ldout(cache->cct, 20) << __func__ << dendl;
1278   while (!buffer_map.empty()) {
1279     _rm_buffer(cache, buffer_map.begin());
1280   }
1281 }
1282
1283 int BlueStore::BufferSpace::_discard(Cache* cache, uint32_t offset, uint32_t length)
1284 {
1285   // note: we already hold cache->lock
1286   ldout(cache->cct, 20) << __func__ << std::hex << " 0x" << offset << "~" << length
1287            << std::dec << dendl;
1288   int cache_private = 0;
1289   cache->_audit("discard start");
1290   auto i = _data_lower_bound(offset);
1291   uint32_t end = offset + length;
1292   while (i != buffer_map.end()) {
1293     Buffer *b = i->second.get();
1294     if (b->offset >= end) {
1295       break;
1296     }
1297     if (b->cache_private > cache_private) {
1298       cache_private = b->cache_private;
1299     }
1300     if (b->offset < offset) {
1301       int64_t front = offset - b->offset;
1302       if (b->end() > end) {
1303         // drop middle (split)
1304         uint32_t tail = b->end() - end;
1305         if (b->data.length()) {
1306           bufferlist bl;
1307           bl.substr_of(b->data, b->length - tail, tail);
1308           Buffer *nb = new Buffer(this, b->state, b->seq, end, bl);
1309           nb->maybe_rebuild();
1310           _add_buffer(cache, nb, 0, b);
1311         } else {
1312           _add_buffer(cache, new Buffer(this, b->state, b->seq, end, tail),
1313                       0, b);
1314         }
1315         if (!b->is_writing()) {
1316           cache->_adjust_buffer_size(b, front - (int64_t)b->length);
1317         }
1318         b->truncate(front);
1319         b->maybe_rebuild();
1320         cache->_audit("discard end 1");
1321         break;
1322       } else {
1323         // drop tail
1324         if (!b->is_writing()) {
1325           cache->_adjust_buffer_size(b, front - (int64_t)b->length);
1326         }
1327         b->truncate(front);
1328         b->maybe_rebuild();
1329         ++i;
1330         continue;
1331       }
1332     }
1333     if (b->end() <= end) {
1334       // drop entire buffer
1335       _rm_buffer(cache, i++);
1336       continue;
1337     }
1338     // drop front
1339     uint32_t keep = b->end() - end;
1340     if (b->data.length()) {
1341       bufferlist bl;
1342       bl.substr_of(b->data, b->length - keep, keep);
1343       Buffer *nb = new Buffer(this, b->state, b->seq, end, bl);
1344       nb->maybe_rebuild();
1345       _add_buffer(cache, nb, 0, b);
1346     } else {
1347       _add_buffer(cache, new Buffer(this, b->state, b->seq, end, keep), 0, b);
1348     }
1349     _rm_buffer(cache, i);
1350     cache->_audit("discard end 2");
1351     break;
1352   }
1353   return cache_private;
1354 }
1355
1356 void BlueStore::BufferSpace::read(
1357   Cache* cache, 
1358   uint32_t offset,
1359   uint32_t length,
1360   BlueStore::ready_regions_t& res,
1361   interval_set<uint32_t>& res_intervals)
1362 {
1363   res.clear();
1364   res_intervals.clear();
1365   uint32_t want_bytes = length;
1366   uint32_t end = offset + length;
1367
1368   {
1369     std::lock_guard<std::recursive_mutex> l(cache->lock);
1370     for (auto i = _data_lower_bound(offset);
1371          i != buffer_map.end() && offset < end && i->first < end;
1372          ++i) {
1373       Buffer *b = i->second.get();
1374       assert(b->end() > offset);
1375       if (b->is_writing() || b->is_clean()) {
1376         if (b->offset < offset) {
1377           uint32_t skip = offset - b->offset;
1378           uint32_t l = MIN(length, b->length - skip);
1379           res[offset].substr_of(b->data, skip, l);
1380           res_intervals.insert(offset, l);
1381           offset += l;
1382           length -= l;
1383           if (!b->is_writing()) {
1384             cache->_touch_buffer(b);
1385           }
1386           continue;
1387         }
1388         if (b->offset > offset) {
1389           uint32_t gap = b->offset - offset;
1390           if (length <= gap) {
1391             break;
1392           }
1393           offset += gap;
1394           length -= gap;
1395         }
1396         if (!b->is_writing()) {
1397           cache->_touch_buffer(b);
1398         }
1399         if (b->length > length) {
1400           res[offset].substr_of(b->data, 0, length);
1401           res_intervals.insert(offset, length);
1402           break;
1403         } else {
1404           res[offset].append(b->data);
1405           res_intervals.insert(offset, b->length);
1406           if (b->length == length)
1407             break;
1408           offset += b->length;
1409           length -= b->length;
1410         }
1411       }
1412     }
1413   }
1414
1415   uint64_t hit_bytes = res_intervals.size();
1416   assert(hit_bytes <= want_bytes);
1417   uint64_t miss_bytes = want_bytes - hit_bytes;
1418   cache->logger->inc(l_bluestore_buffer_hit_bytes, hit_bytes);
1419   cache->logger->inc(l_bluestore_buffer_miss_bytes, miss_bytes);
1420 }
1421
1422 void BlueStore::BufferSpace::finish_write(Cache* cache, uint64_t seq)
1423 {
1424   std::lock_guard<std::recursive_mutex> l(cache->lock);
1425
1426   auto i = writing.begin();
1427   while (i != writing.end()) {
1428     if (i->seq > seq) {
1429       break;
1430     }
1431     if (i->seq < seq) {
1432       ++i;
1433       continue;
1434     }
1435
1436     Buffer *b = &*i;
1437     assert(b->is_writing());
1438
1439     if (b->flags & Buffer::FLAG_NOCACHE) {
1440       writing.erase(i++);
1441       ldout(cache->cct, 20) << __func__ << " discard " << *b << dendl;
1442       buffer_map.erase(b->offset);
1443     } else {
1444       b->state = Buffer::STATE_CLEAN;
1445       writing.erase(i++);
1446       b->maybe_rebuild();
1447       b->data.reassign_to_mempool(mempool::mempool_bluestore_cache_data);
1448       cache->_add_buffer(b, 1, nullptr);
1449       ldout(cache->cct, 20) << __func__ << " added " << *b << dendl;
1450     }
1451   }
1452
1453   cache->_audit("finish_write end");
1454 }
1455
1456 void BlueStore::BufferSpace::split(Cache* cache, size_t pos, BlueStore::BufferSpace &r)
1457 {
1458   std::lock_guard<std::recursive_mutex> lk(cache->lock);
1459   if (buffer_map.empty())
1460     return;
1461
1462   auto p = --buffer_map.end();
1463   while (true) {
1464     if (p->second->end() <= pos)
1465       break;
1466
1467     if (p->second->offset < pos) {
1468       ldout(cache->cct, 30) << __func__ << " cut " << *p->second << dendl;
1469       size_t left = pos - p->second->offset;
1470       size_t right = p->second->length - left;
1471       if (p->second->data.length()) {
1472         bufferlist bl;
1473         bl.substr_of(p->second->data, left, right);
1474         r._add_buffer(cache, new Buffer(&r, p->second->state, p->second->seq, 0, bl),
1475                       0, p->second.get());
1476       } else {
1477         r._add_buffer(cache, new Buffer(&r, p->second->state, p->second->seq, 0, right),
1478                       0, p->second.get());
1479       }
1480       cache->_adjust_buffer_size(p->second.get(), -right);
1481       p->second->truncate(left);
1482       break;
1483     }
1484
1485     assert(p->second->end() > pos);
1486     ldout(cache->cct, 30) << __func__ << " move " << *p->second << dendl;
1487     if (p->second->data.length()) {
1488       r._add_buffer(cache, new Buffer(&r, p->second->state, p->second->seq,
1489                                p->second->offset - pos, p->second->data),
1490                     0, p->second.get());
1491     } else {
1492       r._add_buffer(cache, new Buffer(&r, p->second->state, p->second->seq,
1493                                p->second->offset - pos, p->second->length),
1494                     0, p->second.get());
1495     }
1496     if (p == buffer_map.begin()) {
1497       _rm_buffer(cache, p);
1498       break;
1499     } else {
1500       _rm_buffer(cache, p--);
1501     }
1502   }
1503   assert(writing.empty());
1504 }
1505
1506 // OnodeSpace
1507
1508 #undef dout_prefix
1509 #define dout_prefix *_dout << "bluestore.OnodeSpace(" << this << " in " << cache << ") "
1510
1511 BlueStore::OnodeRef BlueStore::OnodeSpace::add(const ghobject_t& oid, OnodeRef o)
1512 {
1513   std::lock_guard<std::recursive_mutex> l(cache->lock);
1514   auto p = onode_map.find(oid);
1515   if (p != onode_map.end()) {
1516     ldout(cache->cct, 30) << __func__ << " " << oid << " " << o
1517                           << " raced, returning existing " << p->second
1518                           << dendl;
1519     return p->second;
1520   }
1521   ldout(cache->cct, 30) << __func__ << " " << oid << " " << o << dendl;
1522   onode_map[oid] = o;
1523   cache->_add_onode(o, 1);
1524   return o;
1525 }
1526
1527 BlueStore::OnodeRef BlueStore::OnodeSpace::lookup(const ghobject_t& oid)
1528 {
1529   ldout(cache->cct, 30) << __func__ << dendl;
1530   OnodeRef o;
1531   bool hit = false;
1532
1533   {
1534     std::lock_guard<std::recursive_mutex> l(cache->lock);
1535     ceph::unordered_map<ghobject_t,OnodeRef>::iterator p = onode_map.find(oid);
1536     if (p == onode_map.end()) {
1537       ldout(cache->cct, 30) << __func__ << " " << oid << " miss" << dendl;
1538     } else {
1539       ldout(cache->cct, 30) << __func__ << " " << oid << " hit " << p->second
1540                             << dendl;
1541       cache->_touch_onode(p->second);
1542       hit = true;
1543       o = p->second;
1544     }
1545   }
1546
1547   if (hit) {
1548     cache->logger->inc(l_bluestore_onode_hits);
1549   } else {
1550     cache->logger->inc(l_bluestore_onode_misses);
1551   }
1552   return o;
1553 }
1554
1555 void BlueStore::OnodeSpace::clear()
1556 {
1557   std::lock_guard<std::recursive_mutex> l(cache->lock);
1558   ldout(cache->cct, 10) << __func__ << dendl;
1559   for (auto &p : onode_map) {
1560     cache->_rm_onode(p.second);
1561   }
1562   onode_map.clear();
1563 }
1564
1565 bool BlueStore::OnodeSpace::empty()
1566 {
1567   std::lock_guard<std::recursive_mutex> l(cache->lock);
1568   return onode_map.empty();
1569 }
1570
1571 void BlueStore::OnodeSpace::rename(
1572   OnodeRef& oldo,
1573   const ghobject_t& old_oid,
1574   const ghobject_t& new_oid,
1575   const mempool::bluestore_cache_other::string& new_okey)
1576 {
1577   std::lock_guard<std::recursive_mutex> l(cache->lock);
1578   ldout(cache->cct, 30) << __func__ << " " << old_oid << " -> " << new_oid
1579                         << dendl;
1580   ceph::unordered_map<ghobject_t,OnodeRef>::iterator po, pn;
1581   po = onode_map.find(old_oid);
1582   pn = onode_map.find(new_oid);
1583   assert(po != pn);
1584
1585   assert(po != onode_map.end());
1586   if (pn != onode_map.end()) {
1587     ldout(cache->cct, 30) << __func__ << "  removing target " << pn->second
1588                           << dendl;
1589     cache->_rm_onode(pn->second);
1590     onode_map.erase(pn);
1591   }
1592   OnodeRef o = po->second;
1593
1594   // install a non-existent onode at old location
1595   oldo.reset(new Onode(o->c, old_oid, o->key));
1596   po->second = oldo;
1597   cache->_add_onode(po->second, 1);
1598
1599   // add at new position and fix oid, key
1600   onode_map.insert(make_pair(new_oid, o));
1601   cache->_touch_onode(o);
1602   o->oid = new_oid;
1603   o->key = new_okey;
1604 }
1605
1606 bool BlueStore::OnodeSpace::map_any(std::function<bool(OnodeRef)> f)
1607 {
1608   std::lock_guard<std::recursive_mutex> l(cache->lock);
1609   ldout(cache->cct, 20) << __func__ << dendl;
1610   for (auto& i : onode_map) {
1611     if (f(i.second)) {
1612       return true;
1613     }
1614   }
1615   return false;
1616 }
1617
1618 void BlueStore::OnodeSpace::dump(CephContext *cct, int lvl)
1619 {
1620   for (auto& i : onode_map) {
1621     ldout(cct, lvl) << i.first << " : " << i.second << dendl;
1622   }
1623 }
1624
1625 // SharedBlob
1626
1627 #undef dout_prefix
1628 #define dout_prefix *_dout << "bluestore.sharedblob(" << this << ") "
1629
1630 ostream& operator<<(ostream& out, const BlueStore::SharedBlob& sb)
1631 {
1632   out << "SharedBlob(" << &sb;
1633   
1634   if (sb.loaded) {
1635     out << " loaded " << *sb.persistent;
1636   } else {
1637     out << " sbid 0x" << std::hex << sb.sbid_unloaded << std::dec;
1638   }
1639   return out << ")";
1640 }
1641
1642 BlueStore::SharedBlob::SharedBlob(uint64_t i, Collection *_coll)
1643   : coll(_coll), sbid_unloaded(i)
1644 {
1645   assert(sbid_unloaded > 0);
1646   if (get_cache()) {
1647     get_cache()->add_blob();
1648   }
1649 }
1650
1651 BlueStore::SharedBlob::~SharedBlob()
1652 {
1653   if (get_cache()) {   // the dummy instances have a nullptr
1654     std::lock_guard<std::recursive_mutex> l(get_cache()->lock);
1655     bc._clear(get_cache());
1656     get_cache()->rm_blob();
1657   }
1658   if (loaded && persistent) {
1659     delete persistent; 
1660   }
1661 }
1662
1663 void BlueStore::SharedBlob::put()
1664 {
1665   if (--nref == 0) {
1666     ldout(coll->store->cct, 20) << __func__ << " " << this
1667                              << " removing self from set " << get_parent()
1668                              << dendl;
1669     if (get_parent()) {
1670       if (get_parent()->try_remove(this)) {
1671         delete this;
1672       } else {
1673         ldout(coll->store->cct, 20)
1674           << __func__ << " " << this << " lost race to remove myself from set"
1675           << dendl;
1676       }
1677     } else {
1678       delete this;
1679     }
1680   }
1681 }
1682
1683 void BlueStore::SharedBlob::get_ref(uint64_t offset, uint32_t length)
1684 {
1685   assert(persistent);
1686   persistent->ref_map.get(offset, length);
1687 }
1688
1689 void BlueStore::SharedBlob::put_ref(uint64_t offset, uint32_t length,
1690                                     PExtentVector *r,
1691                                     set<SharedBlob*> *maybe_unshared)
1692 {
1693   assert(persistent);
1694   bool maybe = false;
1695   persistent->ref_map.put(offset, length, r, maybe_unshared ? &maybe : nullptr);
1696   if (maybe_unshared && maybe) {
1697     maybe_unshared->insert(this);
1698   }
1699 }
1700
1701 // SharedBlobSet
1702
1703 #undef dout_prefix
1704 #define dout_prefix *_dout << "bluestore.sharedblobset(" << this << ") "
1705
1706 void BlueStore::SharedBlobSet::dump(CephContext *cct, int lvl)
1707 {
1708   std::lock_guard<std::mutex> l(lock);
1709   for (auto& i : sb_map) {
1710     ldout(cct, lvl) << i.first << " : " << *i.second << dendl;
1711   }
1712 }
1713
1714 // Blob
1715
1716 #undef dout_prefix
1717 #define dout_prefix *_dout << "bluestore.blob(" << this << ") "
1718
1719 ostream& operator<<(ostream& out, const BlueStore::Blob& b)
1720 {
1721   out << "Blob(" << &b;
1722   if (b.is_spanning()) {
1723     out << " spanning " << b.id;
1724   }
1725   out << " " << b.get_blob() << " " << b.get_blob_use_tracker();
1726   if (b.shared_blob) {
1727     out << " " << *b.shared_blob;
1728   } else {
1729     out << " (shared_blob=NULL)";
1730   }
1731   out << ")";
1732   return out;
1733 }
1734
1735 void BlueStore::Blob::discard_unallocated(Collection *coll)
1736 {
1737   if (get_blob().is_shared()) {
1738     return;
1739   }
1740   if (get_blob().is_compressed()) {
1741     bool discard = false;
1742     bool all_invalid = true;
1743     for (auto e : get_blob().get_extents()) {
1744       if (!e.is_valid()) {
1745         discard = true;
1746       } else {
1747         all_invalid = false;
1748       }
1749     }
1750     assert(discard == all_invalid); // in case of compressed blob all
1751                                     // or none pextents are invalid.
1752     if (discard) {
1753       shared_blob->bc.discard(shared_blob->get_cache(), 0,
1754                               get_blob().get_logical_length());
1755     }
1756   } else {
1757     size_t pos = 0;
1758     for (auto e : get_blob().get_extents()) {
1759       if (!e.is_valid()) {
1760         ldout(coll->store->cct, 20) << __func__ << " 0x" << std::hex << pos
1761                                     << "~" << e.length
1762                                     << std::dec << dendl;
1763         shared_blob->bc.discard(shared_blob->get_cache(), pos, e.length);
1764       }
1765       pos += e.length;
1766     }
1767     if (get_blob().can_prune_tail()) {
1768       dirty_blob().prune_tail();
1769       used_in_blob.prune_tail(get_blob().get_ondisk_length());
1770       auto cct = coll->store->cct; //used by dout
1771       dout(20) << __func__ << " pruned tail, now " << get_blob() << dendl;
1772     }
1773   }
1774 }
1775
1776 void BlueStore::Blob::get_ref(
1777   Collection *coll,
1778   uint32_t offset,
1779   uint32_t length)
1780 {
1781   // Caller has to initialize Blob's logical length prior to increment 
1782   // references.  Otherwise one is neither unable to determine required
1783   // amount of counters in case of per-au tracking nor obtain min_release_size
1784   // for single counter mode.
1785   assert(get_blob().get_logical_length() != 0);
1786   auto cct = coll->store->cct;
1787   dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
1788            << std::dec << " " << *this << dendl;
1789
1790   if (used_in_blob.is_empty()) {
1791     uint32_t min_release_size =
1792       get_blob().get_release_size(coll->store->min_alloc_size);
1793     uint64_t l = get_blob().get_logical_length();
1794     dout(20) << __func__ << " init 0x" << std::hex << l << ", "
1795              << min_release_size << std::dec << dendl;
1796     used_in_blob.init(l, min_release_size);
1797   }
1798   used_in_blob.get(
1799     offset,
1800     length);
1801 }
1802
1803 bool BlueStore::Blob::put_ref(
1804   Collection *coll,
1805   uint32_t offset,
1806   uint32_t length,
1807   PExtentVector *r)
1808 {
1809   PExtentVector logical;
1810
1811   auto cct = coll->store->cct;
1812   dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
1813            << std::dec << " " << *this << dendl;
1814   
1815   bool empty = used_in_blob.put(
1816     offset,
1817     length,
1818     &logical);
1819   r->clear();
1820   // nothing to release
1821   if (!empty && logical.empty()) {
1822     return false;
1823   }
1824
1825   bluestore_blob_t& b = dirty_blob();
1826   return b.release_extents(empty, logical, r);
1827 }
1828
1829 bool BlueStore::Blob::can_reuse_blob(uint32_t min_alloc_size,
1830                                      uint32_t target_blob_size,
1831                                      uint32_t b_offset,
1832                                      uint32_t *length0) {
1833   assert(min_alloc_size);
1834   assert(target_blob_size);
1835   if (!get_blob().is_mutable()) {
1836     return false;
1837   }
1838
1839   uint32_t length = *length0;
1840   uint32_t end = b_offset + length;
1841
1842   // Currently for the sake of simplicity we omit blob reuse if data is
1843   // unaligned with csum chunk. Later we can perform padding if needed.
1844   if (get_blob().has_csum() &&
1845      ((b_offset % get_blob().get_csum_chunk_size()) != 0 ||
1846       (end % get_blob().get_csum_chunk_size()) != 0)) {
1847     return false;
1848   }
1849
1850   auto blen = get_blob().get_logical_length();
1851   uint32_t new_blen = blen;
1852
1853   // make sure target_blob_size isn't less than current blob len
1854   target_blob_size = MAX(blen, target_blob_size);
1855
1856   if (b_offset >= blen) {
1857     // new data totally stands out of the existing blob
1858     new_blen = end;
1859   } else {
1860     // new data overlaps with the existing blob
1861     new_blen = MAX(blen, end);
1862
1863     uint32_t overlap = 0;
1864     if (new_blen > blen) {
1865       overlap = blen - b_offset;
1866     } else {
1867       overlap = length;
1868     }
1869
1870     if (!get_blob().is_unallocated(b_offset, overlap)) {
1871       // abort if any piece of the overlap has already been allocated
1872       return false;
1873     }
1874   }
1875
1876   if (new_blen > blen) {
1877     int64_t overflow = int64_t(new_blen) - target_blob_size;
1878     // Unable to decrease the provided length to fit into max_blob_size
1879     if (overflow >= length) {
1880       return false;
1881     }
1882
1883     // FIXME: in some cases we could reduce unused resolution
1884     if (get_blob().has_unused()) {
1885       return false;
1886     }
1887
1888     if (overflow > 0) {
1889       new_blen -= overflow;
1890       length -= overflow;
1891       *length0 = length;
1892     }
1893
1894     if (new_blen > blen) {
1895       dirty_blob().add_tail(new_blen);
1896       used_in_blob.add_tail(new_blen,
1897                             get_blob().get_release_size(min_alloc_size));
1898     }
1899   }
1900   return true;
1901 }
1902
1903 void BlueStore::Blob::split(Collection *coll, uint32_t blob_offset, Blob *r)
1904 {
1905   auto cct = coll->store->cct; //used by dout
1906   dout(10) << __func__ << " 0x" << std::hex << blob_offset << std::dec
1907            << " start " << *this << dendl;
1908   assert(blob.can_split());
1909   assert(used_in_blob.can_split());
1910   bluestore_blob_t &lb = dirty_blob();
1911   bluestore_blob_t &rb = r->dirty_blob();
1912
1913   used_in_blob.split(
1914     blob_offset,
1915     &(r->used_in_blob));
1916
1917   lb.split(blob_offset, rb);
1918   shared_blob->bc.split(shared_blob->get_cache(), blob_offset, r->shared_blob->bc);
1919
1920   dout(10) << __func__ << " 0x" << std::hex << blob_offset << std::dec
1921            << " finish " << *this << dendl;
1922   dout(10) << __func__ << " 0x" << std::hex << blob_offset << std::dec
1923            << "    and " << *r << dendl;
1924 }
1925
1926 #ifndef CACHE_BLOB_BL
1927 void BlueStore::Blob::decode(
1928   Collection *coll,
1929   bufferptr::iterator& p,
1930   uint64_t struct_v,
1931   uint64_t* sbid,
1932   bool include_ref_map)
1933 {
1934   denc(blob, p, struct_v);
1935   if (blob.is_shared()) {
1936     denc(*sbid, p);
1937   }
1938   if (include_ref_map) {
1939     if (struct_v > 1) {
1940       used_in_blob.decode(p);
1941     } else {
1942       used_in_blob.clear();
1943       bluestore_extent_ref_map_t legacy_ref_map;
1944       legacy_ref_map.decode(p);
1945       for (auto r : legacy_ref_map.ref_map) {
1946         get_ref(
1947           coll,
1948           r.first,
1949           r.second.refs * r.second.length);
1950       }
1951     }
1952   }
1953 }
1954 #endif
1955
1956 // Extent
1957
1958 ostream& operator<<(ostream& out, const BlueStore::Extent& e)
1959 {
1960   return out << std::hex << "0x" << e.logical_offset << "~" << e.length
1961              << ": 0x" << e.blob_offset << "~" << e.length << std::dec
1962              << " " << *e.blob;
1963 }
1964
1965 // OldExtent
1966 BlueStore::OldExtent* BlueStore::OldExtent::create(CollectionRef c,
1967                                                    uint32_t lo,
1968                                                    uint32_t o,
1969                                                    uint32_t l,
1970                                                    BlobRef& b) {
1971   OldExtent* oe = new OldExtent(lo, o, l, b);
1972   b->put_ref(c.get(), o, l, &(oe->r));
1973   oe->blob_empty = b->get_referenced_bytes() == 0;
1974   return oe;
1975 }
1976
1977 // ExtentMap
1978
1979 #undef dout_prefix
1980 #define dout_prefix *_dout << "bluestore.extentmap(" << this << ") "
1981
1982 BlueStore::ExtentMap::ExtentMap(Onode *o)
1983   : onode(o),
1984     inline_bl(
1985       o->c->store->cct->_conf->bluestore_extent_map_inline_shard_prealloc_size) {
1986 }
1987
1988 void BlueStore::ExtentMap::update(KeyValueDB::Transaction t,
1989                                   bool force)
1990 {
1991   auto cct = onode->c->store->cct; //used by dout
1992   dout(20) << __func__ << " " << onode->oid << (force ? " force" : "") << dendl;
1993   if (onode->onode.extent_map_shards.empty()) {
1994     if (inline_bl.length() == 0) {
1995       unsigned n;
1996       // we need to encode inline_bl to measure encoded length
1997       bool never_happen = encode_some(0, OBJECT_MAX_SIZE, inline_bl, &n);
1998       inline_bl.reassign_to_mempool(mempool::mempool_bluestore_cache_other);
1999       assert(!never_happen);
2000       size_t len = inline_bl.length();
2001       dout(20) << __func__ << "  inline shard " << len << " bytes from " << n
2002                << " extents" << dendl;
2003       if (!force && len > cct->_conf->bluestore_extent_map_shard_max_size) {
2004         request_reshard(0, OBJECT_MAX_SIZE);
2005         return;
2006       }
2007     }
2008     // will persist in the onode key.
2009   } else {
2010     // pending shard update
2011     struct dirty_shard_t {
2012       Shard *shard;
2013       bufferlist bl;
2014       dirty_shard_t(Shard *s) : shard(s) {}
2015     };
2016     vector<dirty_shard_t> encoded_shards;
2017     // allocate slots for all shards in a single call instead of
2018     // doing multiple allocations - one per each dirty shard
2019     encoded_shards.reserve(shards.size());
2020
2021     auto p = shards.begin();
2022     auto prev_p = p;
2023     while (p != shards.end()) {
2024       assert(p->shard_info->offset >= prev_p->shard_info->offset);
2025       auto n = p;
2026       ++n;
2027       if (p->dirty) {
2028         uint32_t endoff;
2029         if (n == shards.end()) {
2030           endoff = OBJECT_MAX_SIZE;
2031         } else {
2032           endoff = n->shard_info->offset;
2033         }
2034         encoded_shards.emplace_back(dirty_shard_t(&(*p)));
2035         bufferlist& bl = encoded_shards.back().bl;
2036         if (encode_some(p->shard_info->offset, endoff - p->shard_info->offset,
2037                         bl, &p->extents)) {
2038           if (force) {
2039             derr << __func__ << "  encode_some needs reshard" << dendl;
2040             assert(!force);
2041           }
2042         }
2043         size_t len = bl.length();
2044
2045         dout(20) << __func__ << "  shard 0x" << std::hex
2046                  << p->shard_info->offset << std::dec << " is " << len
2047                  << " bytes (was " << p->shard_info->bytes << ") from "
2048                  << p->extents << " extents" << dendl;
2049
2050         if (!force) {
2051           if (len > cct->_conf->bluestore_extent_map_shard_max_size) {
2052             // we are big; reshard ourselves
2053             request_reshard(p->shard_info->offset, endoff);
2054           }
2055           // avoid resharding the trailing shard, even if it is small
2056           else if (n != shards.end() &&
2057                    len < g_conf->bluestore_extent_map_shard_min_size) {
2058             assert(endoff != OBJECT_MAX_SIZE);
2059             if (p == shards.begin()) {
2060               // we are the first shard, combine with next shard
2061               request_reshard(p->shard_info->offset, endoff + 1);
2062             } else {
2063               // combine either with the previous shard or the next,
2064               // whichever is smaller
2065               if (prev_p->shard_info->bytes > n->shard_info->bytes) {
2066                 request_reshard(p->shard_info->offset, endoff + 1);
2067               } else {
2068                 request_reshard(prev_p->shard_info->offset, endoff);
2069               }
2070             }
2071           }
2072         }
2073       }
2074       prev_p = p;
2075       p = n;
2076     }
2077     if (needs_reshard()) {
2078       return;
2079     }
2080
2081     // schedule DB update for dirty shards
2082     string key;
2083     for (auto& it : encoded_shards) {
2084       it.shard->dirty = false;
2085       it.shard->shard_info->bytes = it.bl.length();
2086       generate_extent_shard_key_and_apply(
2087         onode->key,
2088         it.shard->shard_info->offset,
2089         &key,
2090         [&](const string& final_key) {
2091           t->set(PREFIX_OBJ, final_key, it.bl);
2092         }
2093       );
2094     }
2095   }
2096 }
2097
2098 bid_t BlueStore::ExtentMap::allocate_spanning_blob_id()
2099 {
2100   if (spanning_blob_map.empty())
2101     return 0;
2102   bid_t bid = spanning_blob_map.rbegin()->first + 1;
2103   // bid is valid and available.
2104   if (bid >= 0)
2105     return bid;
2106   // Find next unused bid;
2107   bid = rand() % (numeric_limits<bid_t>::max() + 1);
2108   const auto begin_bid = bid;
2109   do {
2110     if (!spanning_blob_map.count(bid))
2111       return bid;
2112     else {
2113       bid++;
2114       if (bid < 0) bid = 0;
2115     }
2116   } while (bid != begin_bid);
2117   assert(0 == "no available blob id");
2118 }
2119
2120 void BlueStore::ExtentMap::reshard(
2121   KeyValueDB *db,
2122   KeyValueDB::Transaction t)
2123 {
2124   auto cct = onode->c->store->cct; // used by dout
2125
2126   dout(10) << __func__ << " 0x[" << std::hex << needs_reshard_begin << ","
2127            << needs_reshard_end << ")" << std::dec
2128            << " of " << onode->onode.extent_map_shards.size()
2129            << " shards on " << onode->oid << dendl;
2130   for (auto& p : spanning_blob_map) {
2131     dout(20) << __func__ << "   spanning blob " << p.first << " " << *p.second
2132              << dendl;
2133   }
2134   // determine shard index range
2135   unsigned si_begin = 0, si_end = 0;
2136   if (!shards.empty()) {
2137     while (si_begin + 1 < shards.size() &&
2138            shards[si_begin + 1].shard_info->offset <= needs_reshard_begin) {
2139       ++si_begin;
2140     }
2141     needs_reshard_begin = shards[si_begin].shard_info->offset;
2142     for (si_end = si_begin; si_end < shards.size(); ++si_end) {
2143       if (shards[si_end].shard_info->offset >= needs_reshard_end) {
2144         needs_reshard_end = shards[si_end].shard_info->offset;
2145         break;
2146       }
2147     }
2148     if (si_end == shards.size()) {
2149       needs_reshard_end = OBJECT_MAX_SIZE;
2150     }
2151     dout(20) << __func__ << "   shards [" << si_begin << "," << si_end << ")"
2152              << " over 0x[" << std::hex << needs_reshard_begin << ","
2153              << needs_reshard_end << ")" << std::dec << dendl;
2154   }
2155
2156   fault_range(db, needs_reshard_begin, (needs_reshard_end - needs_reshard_begin));
2157
2158   // we may need to fault in a larger interval later must have all
2159   // referring extents for spanning blobs loaded in order to have
2160   // accurate use_tracker values.
2161   uint32_t spanning_scan_begin = needs_reshard_begin;
2162   uint32_t spanning_scan_end = needs_reshard_end;
2163
2164   // remove old keys
2165   string key;
2166   for (unsigned i = si_begin; i < si_end; ++i) {
2167     generate_extent_shard_key_and_apply(
2168       onode->key, shards[i].shard_info->offset, &key,
2169       [&](const string& final_key) {
2170         t->rmkey(PREFIX_OBJ, final_key);
2171       }
2172       );
2173   }
2174
2175   // calculate average extent size
2176   unsigned bytes = 0;
2177   unsigned extents = 0;
2178   if (onode->onode.extent_map_shards.empty()) {
2179     bytes = inline_bl.length();
2180     extents = extent_map.size();
2181   } else {
2182     for (unsigned i = si_begin; i < si_end; ++i) {
2183       bytes += shards[i].shard_info->bytes;
2184       extents += shards[i].extents;
2185     }
2186   }
2187   unsigned target = cct->_conf->bluestore_extent_map_shard_target_size;
2188   unsigned slop = target *
2189     cct->_conf->bluestore_extent_map_shard_target_size_slop;
2190   unsigned extent_avg = bytes / MAX(1, extents);
2191   dout(20) << __func__ << "  extent_avg " << extent_avg << ", target " << target
2192            << ", slop " << slop << dendl;
2193
2194   // reshard
2195   unsigned estimate = 0;
2196   unsigned offset = needs_reshard_begin;
2197   vector<bluestore_onode_t::shard_info> new_shard_info;
2198   unsigned max_blob_end = 0;
2199   Extent dummy(needs_reshard_begin);
2200   for (auto e = extent_map.lower_bound(dummy);
2201        e != extent_map.end();
2202        ++e) {
2203     if (e->logical_offset >= needs_reshard_end) {
2204       break;
2205     }
2206     dout(30) << " extent " << *e << dendl;
2207
2208     // disfavor shard boundaries that span a blob
2209     bool would_span = (e->logical_offset < max_blob_end) || e->blob_offset;
2210     if (estimate &&
2211         estimate + extent_avg > target + (would_span ? slop : 0)) {
2212       // new shard
2213       if (offset == needs_reshard_begin) {
2214         new_shard_info.emplace_back(bluestore_onode_t::shard_info());
2215         new_shard_info.back().offset = offset;
2216         dout(20) << __func__ << "  new shard 0x" << std::hex << offset
2217                  << std::dec << dendl;
2218       }
2219       offset = e->logical_offset;
2220       new_shard_info.emplace_back(bluestore_onode_t::shard_info());
2221       new_shard_info.back().offset = offset;
2222       dout(20) << __func__ << "  new shard 0x" << std::hex << offset
2223                << std::dec << dendl;
2224       estimate = 0;
2225     }
2226     estimate += extent_avg;
2227     unsigned bs = e->blob_start();
2228     if (bs < spanning_scan_begin) {
2229       spanning_scan_begin = bs;
2230     }
2231     uint32_t be = e->blob_end();
2232     if (be > max_blob_end) {
2233       max_blob_end = be;
2234     }
2235     if (be > spanning_scan_end) {
2236       spanning_scan_end = be;
2237     }
2238   }
2239   if (new_shard_info.empty() && (si_begin > 0 ||
2240                                  si_end < shards.size())) {
2241     // we resharded a partial range; we must produce at least one output
2242     // shard
2243     new_shard_info.emplace_back(bluestore_onode_t::shard_info());
2244     new_shard_info.back().offset = needs_reshard_begin;
2245     dout(20) << __func__ << "  new shard 0x" << std::hex << needs_reshard_begin
2246              << std::dec << " (singleton degenerate case)" << dendl;
2247   }
2248
2249   auto& sv = onode->onode.extent_map_shards;
2250   dout(20) << __func__ << "  new " << new_shard_info << dendl;
2251   dout(20) << __func__ << "  old " << sv << dendl;
2252   if (sv.empty()) {
2253     // no old shards to keep
2254     sv.swap(new_shard_info);
2255     init_shards(true, true);
2256   } else {
2257     // splice in new shards
2258     sv.erase(sv.begin() + si_begin, sv.begin() + si_end);
2259     shards.erase(shards.begin() + si_begin, shards.begin() + si_end);
2260     sv.insert(
2261       sv.begin() + si_begin,
2262       new_shard_info.begin(),
2263       new_shard_info.end());
2264     shards.insert(shards.begin() + si_begin, new_shard_info.size(), Shard());
2265     si_end = si_begin + new_shard_info.size();
2266
2267     assert(sv.size() == shards.size());
2268
2269     // note that we need to update every shard_info of shards here,
2270     // as sv might have been totally re-allocated above
2271     for (unsigned i = 0; i < shards.size(); i++) {
2272       shards[i].shard_info = &sv[i];
2273     }
2274
2275     // mark newly added shards as dirty
2276     for (unsigned i = si_begin; i < si_end; ++i) {
2277       shards[i].loaded = true;
2278       shards[i].dirty = true;
2279     }
2280   }
2281   dout(20) << __func__ << "  fin " << sv << dendl;
2282   inline_bl.clear();
2283
2284   if (sv.empty()) {
2285     // no more shards; unspan all previously spanning blobs
2286     auto p = spanning_blob_map.begin();
2287     while (p != spanning_blob_map.end()) {
2288       p->second->id = -1;
2289       dout(30) << __func__ << " un-spanning " << *p->second << dendl;
2290       p = spanning_blob_map.erase(p);
2291     }
2292   } else {
2293     // identify new spanning blobs
2294     dout(20) << __func__ << " checking spanning blobs 0x[" << std::hex
2295              << spanning_scan_begin << "," << spanning_scan_end << ")" << dendl;
2296     if (spanning_scan_begin < needs_reshard_begin) {
2297       fault_range(db, spanning_scan_begin,
2298                   needs_reshard_begin - spanning_scan_begin);
2299     }
2300     if (spanning_scan_end > needs_reshard_end) {
2301       fault_range(db, needs_reshard_end,
2302                   spanning_scan_end - needs_reshard_end);
2303     }
2304     auto sp = sv.begin() + si_begin;
2305     auto esp = sv.end();
2306     unsigned shard_start = sp->offset;
2307     unsigned shard_end;
2308     ++sp;
2309     if (sp == esp) {
2310       shard_end = OBJECT_MAX_SIZE;
2311     } else {
2312       shard_end = sp->offset;
2313     }
2314     Extent dummy(needs_reshard_begin);
2315     for (auto e = extent_map.lower_bound(dummy); e != extent_map.end(); ++e) {
2316       if (e->logical_offset >= needs_reshard_end) {
2317         break;
2318       }
2319       dout(30) << " extent " << *e << dendl;
2320       while (e->logical_offset >= shard_end) {
2321         shard_start = shard_end;
2322         assert(sp != esp);
2323         ++sp;
2324         if (sp == esp) {
2325           shard_end = OBJECT_MAX_SIZE;
2326         } else {
2327           shard_end = sp->offset;
2328         }
2329         dout(30) << __func__ << "  shard 0x" << std::hex << shard_start
2330                  << " to 0x" << shard_end << std::dec << dendl;
2331       }
2332       if (e->blob_escapes_range(shard_start, shard_end - shard_start)) {
2333         if (!e->blob->is_spanning()) {
2334           // We have two options: (1) split the blob into pieces at the
2335           // shard boundaries (and adjust extents accordingly), or (2)
2336           // mark it spanning.  We prefer to cut the blob if we can.  Note that
2337           // we may have to split it multiple times--potentially at every
2338           // shard boundary.
2339           bool must_span = false;
2340           BlobRef b = e->blob;
2341           if (b->can_split()) {
2342             uint32_t bstart = e->blob_start();
2343             uint32_t bend = e->blob_end();
2344             for (const auto& sh : shards) {
2345               if (bstart < sh.shard_info->offset &&
2346                   bend > sh.shard_info->offset) {
2347                 uint32_t blob_offset = sh.shard_info->offset - bstart;
2348                 if (b->can_split_at(blob_offset)) {
2349                   dout(20) << __func__ << "    splitting blob, bstart 0x"
2350                            << std::hex << bstart << " blob_offset 0x"
2351                            << blob_offset << std::dec << " " << *b << dendl;
2352                   b = split_blob(b, blob_offset, sh.shard_info->offset);
2353                   // switch b to the new right-hand side, in case it
2354                   // *also* has to get split.
2355                   bstart += blob_offset;
2356                   onode->c->store->logger->inc(l_bluestore_blob_split);
2357                 } else {
2358                   must_span = true;
2359                   break;
2360                 }
2361               }
2362             }
2363           } else {
2364             must_span = true;
2365           }
2366           if (must_span) {
2367             auto bid = allocate_spanning_blob_id();
2368             b->id = bid;
2369             spanning_blob_map[b->id] = b;
2370             dout(20) << __func__ << "    adding spanning " << *b << dendl;
2371           }
2372         }
2373       } else {
2374         if (e->blob->is_spanning()) {
2375           spanning_blob_map.erase(e->blob->id);
2376           e->blob->id = -1;
2377           dout(30) << __func__ << "    un-spanning " << *e->blob << dendl;
2378         }
2379       }
2380     }
2381   }
2382
2383   clear_needs_reshard();
2384 }
2385
2386 bool BlueStore::ExtentMap::encode_some(
2387   uint32_t offset,
2388   uint32_t length,
2389   bufferlist& bl,
2390   unsigned *pn)
2391 {
2392   auto cct = onode->c->store->cct; //used by dout
2393   Extent dummy(offset);
2394   auto start = extent_map.lower_bound(dummy);
2395   uint32_t end = offset + length;
2396
2397   __u8 struct_v = 2; // Version 2 differs from v1 in blob's ref_map
2398                      // serialization only. Hence there is no specific
2399                      // handling at ExtentMap level.
2400
2401   unsigned n = 0;
2402   size_t bound = 0;
2403   bool must_reshard = false;
2404   for (auto p = start;
2405        p != extent_map.end() && p->logical_offset < end;
2406        ++p, ++n) {
2407     assert(p->logical_offset >= offset);
2408     p->blob->last_encoded_id = -1;
2409     if (!p->blob->is_spanning() && p->blob_escapes_range(offset, length)) {
2410       dout(30) << __func__ << " 0x" << std::hex << offset << "~" << length
2411                << std::dec << " hit new spanning blob " << *p << dendl;
2412       request_reshard(p->blob_start(), p->blob_end());
2413       must_reshard = true;
2414     }
2415     if (!must_reshard) {
2416       denc_varint(0, bound); // blobid
2417       denc_varint(0, bound); // logical_offset
2418       denc_varint(0, bound); // len
2419       denc_varint(0, bound); // blob_offset
2420
2421       p->blob->bound_encode(
2422         bound,
2423         struct_v,
2424         p->blob->shared_blob->get_sbid(),
2425         false);
2426     }
2427   }
2428   if (must_reshard) {
2429     return true;
2430   }
2431
2432   denc(struct_v, bound);
2433   denc_varint(0, bound); // number of extents
2434
2435   {
2436     auto app = bl.get_contiguous_appender(bound);
2437     denc(struct_v, app);
2438     denc_varint(n, app);
2439     if (pn) {
2440       *pn = n;
2441     }
2442
2443     n = 0;
2444     uint64_t pos = 0;
2445     uint64_t prev_len = 0;
2446     for (auto p = start;
2447          p != extent_map.end() && p->logical_offset < end;
2448          ++p, ++n) {
2449       unsigned blobid;
2450       bool include_blob = false;
2451       if (p->blob->is_spanning()) {
2452         blobid = p->blob->id << BLOBID_SHIFT_BITS;
2453         blobid |= BLOBID_FLAG_SPANNING;
2454       } else if (p->blob->last_encoded_id < 0) {
2455         p->blob->last_encoded_id = n + 1;  // so it is always non-zero
2456         include_blob = true;
2457         blobid = 0;  // the decoder will infer the id from n
2458       } else {
2459         blobid = p->blob->last_encoded_id << BLOBID_SHIFT_BITS;
2460       }
2461       if (p->logical_offset == pos) {
2462         blobid |= BLOBID_FLAG_CONTIGUOUS;
2463       }
2464       if (p->blob_offset == 0) {
2465         blobid |= BLOBID_FLAG_ZEROOFFSET;
2466       }
2467       if (p->length == prev_len) {
2468         blobid |= BLOBID_FLAG_SAMELENGTH;
2469       } else {
2470         prev_len = p->length;
2471       }
2472       denc_varint(blobid, app);
2473       if ((blobid & BLOBID_FLAG_CONTIGUOUS) == 0) {
2474         denc_varint_lowz(p->logical_offset - pos, app);
2475       }
2476       if ((blobid & BLOBID_FLAG_ZEROOFFSET) == 0) {
2477         denc_varint_lowz(p->blob_offset, app);
2478       }
2479       if ((blobid & BLOBID_FLAG_SAMELENGTH) == 0) {
2480         denc_varint_lowz(p->length, app);
2481       }
2482       pos = p->logical_end();
2483       if (include_blob) {
2484         p->blob->encode(app, struct_v, p->blob->shared_blob->get_sbid(), false);
2485       }
2486     }
2487   }
2488   /*derr << __func__ << bl << dendl;
2489   derr << __func__ << ":";
2490   bl.hexdump(*_dout);
2491   *_dout << dendl;
2492   */
2493   return false;
2494 }
2495
2496 unsigned BlueStore::ExtentMap::decode_some(bufferlist& bl)
2497 {
2498   auto cct = onode->c->store->cct; //used by dout
2499   /*
2500   derr << __func__ << ":";
2501   bl.hexdump(*_dout);
2502   *_dout << dendl;
2503   */
2504
2505   assert(bl.get_num_buffers() <= 1);
2506   auto p = bl.front().begin_deep();
2507   __u8 struct_v;
2508   denc(struct_v, p);
2509   // Version 2 differs from v1 in blob's ref_map
2510   // serialization only. Hence there is no specific
2511   // handling at ExtentMap level below.
2512   assert(struct_v == 1 || struct_v == 2);
2513
2514   uint32_t num;
2515   denc_varint(num, p);
2516   vector<BlobRef> blobs(num);
2517   uint64_t pos = 0;
2518   uint64_t prev_len = 0;
2519   unsigned n = 0;
2520
2521   while (!p.end()) {
2522     Extent *le = new Extent();
2523     uint64_t blobid;
2524     denc_varint(blobid, p);
2525     if ((blobid & BLOBID_FLAG_CONTIGUOUS) == 0) {
2526       uint64_t gap;
2527       denc_varint_lowz(gap, p);
2528       pos += gap;
2529     }
2530     le->logical_offset = pos;
2531     if ((blobid & BLOBID_FLAG_ZEROOFFSET) == 0) {
2532       denc_varint_lowz(le->blob_offset, p);
2533     } else {
2534       le->blob_offset = 0;
2535     }
2536     if ((blobid & BLOBID_FLAG_SAMELENGTH) == 0) {
2537       denc_varint_lowz(prev_len, p);
2538     }
2539     le->length = prev_len;
2540
2541     if (blobid & BLOBID_FLAG_SPANNING) {
2542       dout(30) << __func__ << "  getting spanning blob "
2543                << (blobid >> BLOBID_SHIFT_BITS) << dendl;
2544       le->assign_blob(get_spanning_blob(blobid >> BLOBID_SHIFT_BITS));
2545     } else {
2546       blobid >>= BLOBID_SHIFT_BITS;
2547       if (blobid) {
2548         le->assign_blob(blobs[blobid - 1]);
2549         assert(le->blob);
2550       } else {
2551         Blob *b = new Blob();
2552         uint64_t sbid = 0;
2553         b->decode(onode->c, p, struct_v, &sbid, false);
2554         blobs[n] = b;
2555         onode->c->open_shared_blob(sbid, b);
2556         le->assign_blob(b);
2557       }
2558       // we build ref_map dynamically for non-spanning blobs
2559       le->blob->get_ref(
2560         onode->c,
2561         le->blob_offset,
2562         le->length);
2563     }
2564     pos += prev_len;
2565     ++n;
2566     extent_map.insert(*le);
2567   }
2568
2569   assert(n == num);
2570   return num;
2571 }
2572
2573 void BlueStore::ExtentMap::bound_encode_spanning_blobs(size_t& p)
2574 {
2575   // Version 2 differs from v1 in blob's ref_map
2576   // serialization only. Hence there is no specific
2577   // handling at ExtentMap level.
2578   __u8 struct_v = 2;
2579
2580   denc(struct_v, p);
2581   denc_varint((uint32_t)0, p);
2582   size_t key_size = 0;
2583   denc_varint((uint32_t)0, key_size);
2584   p += spanning_blob_map.size() * key_size;
2585   for (const auto& i : spanning_blob_map) {
2586     i.second->bound_encode(p, struct_v, i.second->shared_blob->get_sbid(), true);
2587   }
2588 }
2589
2590 void BlueStore::ExtentMap::encode_spanning_blobs(
2591   bufferlist::contiguous_appender& p)
2592 {
2593   // Version 2 differs from v1 in blob's ref_map
2594   // serialization only. Hence there is no specific
2595   // handling at ExtentMap level.
2596   __u8 struct_v = 2;
2597
2598   denc(struct_v, p);
2599   denc_varint(spanning_blob_map.size(), p);
2600   for (auto& i : spanning_blob_map) {
2601     denc_varint(i.second->id, p);
2602     i.second->encode(p, struct_v, i.second->shared_blob->get_sbid(), true);
2603   }
2604 }
2605
2606 void BlueStore::ExtentMap::decode_spanning_blobs(
2607   bufferptr::iterator& p)
2608 {
2609   __u8 struct_v;
2610   denc(struct_v, p);
2611   // Version 2 differs from v1 in blob's ref_map
2612   // serialization only. Hence there is no specific
2613   // handling at ExtentMap level.
2614   assert(struct_v == 1 || struct_v == 2);
2615
2616   unsigned n;
2617   denc_varint(n, p);
2618   while (n--) {
2619     BlobRef b(new Blob());
2620     denc_varint(b->id, p);
2621     spanning_blob_map[b->id] = b;
2622     uint64_t sbid = 0;
2623     b->decode(onode->c, p, struct_v, &sbid, true);
2624     onode->c->open_shared_blob(sbid, b);
2625   }
2626 }
2627
2628 void BlueStore::ExtentMap::init_shards(bool loaded, bool dirty)
2629 {
2630   shards.resize(onode->onode.extent_map_shards.size());
2631   unsigned i = 0;
2632   for (auto &s : onode->onode.extent_map_shards) {
2633     shards[i].shard_info = &s;
2634     shards[i].loaded = loaded;
2635     shards[i].dirty = dirty;
2636     ++i;
2637   }
2638 }
2639
2640 void BlueStore::ExtentMap::fault_range(
2641   KeyValueDB *db,
2642   uint32_t offset,
2643   uint32_t length)
2644 {
2645   auto cct = onode->c->store->cct; //used by dout
2646   dout(30) << __func__ << " 0x" << std::hex << offset << "~" << length
2647            << std::dec << dendl;
2648   auto start = seek_shard(offset);
2649   auto last = seek_shard(offset + length);
2650
2651   if (start < 0)
2652     return;
2653
2654   assert(last >= start);
2655   string key;
2656   while (start <= last) {
2657     assert((size_t)start < shards.size());
2658     auto p = &shards[start];
2659     if (!p->loaded) {
2660       dout(30) << __func__ << " opening shard 0x" << std::hex
2661                << p->shard_info->offset << std::dec << dendl;
2662       bufferlist v;
2663       generate_extent_shard_key_and_apply(
2664         onode->key, p->shard_info->offset, &key,
2665         [&](const string& final_key) {
2666           int r = db->get(PREFIX_OBJ, final_key, &v);
2667           if (r < 0) {
2668             derr << __func__ << " missing shard 0x" << std::hex
2669                  << p->shard_info->offset << std::dec << " for " << onode->oid
2670                  << dendl;
2671             assert(r >= 0);
2672           }
2673         }
2674       );
2675       p->extents = decode_some(v);
2676       p->loaded = true;
2677       dout(20) << __func__ << " open shard 0x" << std::hex
2678                << p->shard_info->offset << std::dec
2679                << " (" << v.length() << " bytes)" << dendl;
2680       assert(p->dirty == false);
2681       assert(v.length() == p->shard_info->bytes);
2682       onode->c->store->logger->inc(l_bluestore_onode_shard_misses);
2683     } else {
2684       onode->c->store->logger->inc(l_bluestore_onode_shard_hits);
2685     }
2686     ++start;
2687   }
2688 }
2689
2690 void BlueStore::ExtentMap::dirty_range(
2691   uint32_t offset,
2692   uint32_t length)
2693 {
2694   auto cct = onode->c->store->cct; //used by dout
2695   dout(30) << __func__ << " 0x" << std::hex << offset << "~" << length
2696            << std::dec << dendl;
2697   if (shards.empty()) {
2698     dout(20) << __func__ << " mark inline shard dirty" << dendl;
2699     inline_bl.clear();
2700     return;
2701   }
2702   auto start = seek_shard(offset);
2703   auto last = seek_shard(offset + length);
2704   if (start < 0)
2705     return;
2706
2707   assert(last >= start);
2708   while (start <= last) {
2709     assert((size_t)start < shards.size());
2710     auto p = &shards[start];
2711     if (!p->loaded) {
2712       dout(20) << __func__ << " shard 0x" << std::hex << p->shard_info->offset
2713                << std::dec << " is not loaded, can't mark dirty" << dendl;
2714       assert(0 == "can't mark unloaded shard dirty");
2715     }
2716     if (!p->dirty) {
2717       dout(20) << __func__ << " mark shard 0x" << std::hex
2718                << p->shard_info->offset << std::dec << " dirty" << dendl;
2719       p->dirty = true;
2720     }
2721     ++start;
2722   }
2723 }
2724
2725 BlueStore::extent_map_t::iterator BlueStore::ExtentMap::find(
2726   uint64_t offset)
2727 {
2728   Extent dummy(offset);
2729   return extent_map.find(dummy);
2730 }
2731
2732 BlueStore::extent_map_t::iterator BlueStore::ExtentMap::seek_lextent(
2733   uint64_t offset)
2734 {
2735   Extent dummy(offset);
2736   auto fp = extent_map.lower_bound(dummy);
2737   if (fp != extent_map.begin()) {
2738     --fp;
2739     if (fp->logical_end() <= offset) {
2740       ++fp;
2741     }
2742   }
2743   return fp;
2744 }
2745
2746 BlueStore::extent_map_t::const_iterator BlueStore::ExtentMap::seek_lextent(
2747   uint64_t offset) const
2748 {
2749   Extent dummy(offset);
2750   auto fp = extent_map.lower_bound(dummy);
2751   if (fp != extent_map.begin()) {
2752     --fp;
2753     if (fp->logical_end() <= offset) {
2754       ++fp;
2755     }
2756   }
2757   return fp;
2758 }
2759
2760 bool BlueStore::ExtentMap::has_any_lextents(uint64_t offset, uint64_t length)
2761 {
2762   auto fp = seek_lextent(offset);
2763   if (fp == extent_map.end() || fp->logical_offset >= offset + length) {
2764     return false;
2765   }
2766   return true;
2767 }
2768
2769 int BlueStore::ExtentMap::compress_extent_map(
2770   uint64_t offset,
2771   uint64_t length)
2772 {
2773   auto cct = onode->c->store->cct; //used by dout
2774   if (extent_map.empty())
2775     return 0;
2776   int removed = 0;
2777   auto p = seek_lextent(offset);
2778   if (p != extent_map.begin()) {
2779     --p;  // start to the left of offset
2780   }
2781   // the caller should have just written to this region
2782   assert(p != extent_map.end());
2783
2784   // identify the *next* shard
2785   auto pshard = shards.begin();
2786   while (pshard != shards.end() &&
2787          p->logical_offset >= pshard->shard_info->offset) {
2788     ++pshard;
2789   }
2790   uint64_t shard_end;
2791   if (pshard != shards.end()) {
2792     shard_end = pshard->shard_info->offset;
2793   } else {
2794     shard_end = OBJECT_MAX_SIZE;
2795   }
2796
2797   auto n = p;
2798   for (++n; n != extent_map.end(); p = n++) {
2799     if (n->logical_offset > offset + length) {
2800       break;  // stop after end
2801     }
2802     while (n != extent_map.end() &&
2803            p->logical_end() == n->logical_offset &&
2804            p->blob == n->blob &&
2805            p->blob_offset + p->length == n->blob_offset &&
2806            n->logical_offset < shard_end) {
2807       dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
2808                << " next shard 0x" << shard_end << std::dec
2809                << " merging " << *p << " and " << *n << dendl;
2810       p->length += n->length;
2811       rm(n++);
2812       ++removed;
2813     }
2814     if (n == extent_map.end()) {
2815       break;
2816     }
2817     if (n->logical_offset >= shard_end) {
2818       assert(pshard != shards.end());
2819       ++pshard;
2820       if (pshard != shards.end()) {
2821         shard_end = pshard->shard_info->offset;
2822       } else {
2823         shard_end = OBJECT_MAX_SIZE;
2824       }
2825     }
2826   }
2827   if (removed && onode) {
2828     onode->c->store->logger->inc(l_bluestore_extent_compress, removed);
2829   }
2830   return removed;
2831 }
2832
2833 void BlueStore::ExtentMap::punch_hole(
2834   CollectionRef &c, 
2835   uint64_t offset,
2836   uint64_t length,
2837   old_extent_map_t *old_extents)
2838 {
2839   auto p = seek_lextent(offset);
2840   uint64_t end = offset + length;
2841   while (p != extent_map.end()) {
2842     if (p->logical_offset >= end) {
2843       break;
2844     }
2845     if (p->logical_offset < offset) {
2846       if (p->logical_end() > end) {
2847         // split and deref middle
2848         uint64_t front = offset - p->logical_offset;
2849         OldExtent* oe = OldExtent::create(c, offset, p->blob_offset + front, 
2850                                           length, p->blob);
2851         old_extents->push_back(*oe);
2852         add(end,
2853             p->blob_offset + front + length,
2854             p->length - front - length,
2855             p->blob);
2856         p->length = front;
2857         break;
2858       } else {
2859         // deref tail
2860         assert(p->logical_end() > offset); // else seek_lextent bug
2861         uint64_t keep = offset - p->logical_offset;
2862         OldExtent* oe = OldExtent::create(c, offset, p->blob_offset + keep,
2863                                           p->length - keep, p->blob);
2864         old_extents->push_back(*oe);
2865         p->length = keep;
2866         ++p;
2867         continue;
2868       }
2869     }
2870     if (p->logical_offset + p->length <= end) {
2871       // deref whole lextent
2872       OldExtent* oe = OldExtent::create(c, p->logical_offset, p->blob_offset,
2873                                         p->length, p->blob);
2874       old_extents->push_back(*oe);
2875       rm(p++);
2876       continue;
2877     }
2878     // deref head
2879     uint64_t keep = p->logical_end() - end;
2880     OldExtent* oe = OldExtent::create(c, p->logical_offset, p->blob_offset,
2881                                       p->length - keep, p->blob);
2882     old_extents->push_back(*oe);
2883
2884     add(end, p->blob_offset + p->length - keep, keep, p->blob);
2885     rm(p);
2886     break;
2887   }
2888 }
2889
2890 BlueStore::Extent *BlueStore::ExtentMap::set_lextent(
2891   CollectionRef &c,
2892   uint64_t logical_offset,
2893   uint64_t blob_offset, uint64_t length, BlobRef b,
2894   old_extent_map_t *old_extents)
2895 {
2896   // We need to have completely initialized Blob to increment its ref counters.
2897   assert(b->get_blob().get_logical_length() != 0);
2898
2899   // Do get_ref prior to punch_hole to prevent from putting reused blob into 
2900   // old_extents list if we overwre the blob totally
2901   // This might happen during WAL overwrite.
2902   b->get_ref(onode->c, blob_offset, length);
2903
2904   if (old_extents) {
2905     punch_hole(c, logical_offset, length, old_extents);
2906   }
2907
2908   Extent *le = new Extent(logical_offset, blob_offset, length, b);
2909   extent_map.insert(*le);
2910   if (spans_shard(logical_offset, length)) {
2911     request_reshard(logical_offset, logical_offset + length);
2912   }
2913   return le;
2914 }
2915
2916 BlueStore::BlobRef BlueStore::ExtentMap::split_blob(
2917   BlobRef lb,
2918   uint32_t blob_offset,
2919   uint32_t pos)
2920 {
2921   auto cct = onode->c->store->cct; //used by dout
2922
2923   uint32_t end_pos = pos + lb->get_blob().get_logical_length() - blob_offset;
2924   dout(20) << __func__ << " 0x" << std::hex << pos << " end 0x" << end_pos
2925            << " blob_offset 0x" << blob_offset << std::dec << " " << *lb
2926            << dendl;
2927   BlobRef rb = onode->c->new_blob();
2928   lb->split(onode->c, blob_offset, rb.get());
2929
2930   for (auto ep = seek_lextent(pos);
2931        ep != extent_map.end() && ep->logical_offset < end_pos;
2932        ++ep) {
2933     if (ep->blob != lb) {
2934       continue;
2935     }
2936     if (ep->logical_offset < pos) {
2937       // split extent
2938       size_t left = pos - ep->logical_offset;
2939       Extent *ne = new Extent(pos, 0, ep->length - left, rb);
2940       extent_map.insert(*ne);
2941       ep->length = left;
2942       dout(30) << __func__ << "  split " << *ep << dendl;
2943       dout(30) << __func__ << "     to " << *ne << dendl;
2944     } else {
2945       // switch blob
2946       assert(ep->blob_offset >= blob_offset);
2947
2948       ep->blob = rb;
2949       ep->blob_offset -= blob_offset;
2950       dout(30) << __func__ << "  adjusted " << *ep << dendl;
2951     }
2952   }
2953   return rb;
2954 }
2955
2956 // Onode
2957
2958 #undef dout_prefix
2959 #define dout_prefix *_dout << "bluestore.onode(" << this << ")." << __func__ << " "
2960
2961 void BlueStore::Onode::flush()
2962 {
2963   if (flushing_count.load()) {
2964     ldout(c->store->cct, 20) << __func__ << " cnt:" << flushing_count << dendl;
2965     std::unique_lock<std::mutex> l(flush_lock);
2966     while (flushing_count.load()) {
2967       flush_cond.wait(l);
2968     }
2969   }
2970   ldout(c->store->cct, 20) << __func__ << " done" << dendl;
2971 }
2972
2973 // =======================================================
2974 // WriteContext
2975  
2976 /// Checks for writes to the same pextent within a blob
2977 bool BlueStore::WriteContext::has_conflict(
2978   BlobRef b,
2979   uint64_t loffs,
2980   uint64_t loffs_end,
2981   uint64_t min_alloc_size)
2982 {
2983   assert((loffs % min_alloc_size) == 0);
2984   assert((loffs_end % min_alloc_size) == 0);
2985   for (auto w : writes) {
2986     if (b == w.b) {
2987       auto loffs2 = P2ALIGN(w.logical_offset, min_alloc_size);
2988       auto loffs2_end = P2ROUNDUP(w.logical_offset + w.length0, min_alloc_size);
2989       if ((loffs <= loffs2 && loffs_end > loffs2) ||
2990           (loffs >= loffs2 && loffs < loffs2_end)) {
2991         return true;
2992       }
2993     }
2994   }
2995   return false;
2996 }
2997  
2998 // =======================================================
2999
3000 // DeferredBatch
3001 #undef dout_prefix
3002 #define dout_prefix *_dout << "bluestore.DeferredBatch(" << this << ") "
3003
3004 void BlueStore::DeferredBatch::prepare_write(
3005   CephContext *cct,
3006   uint64_t seq, uint64_t offset, uint64_t length,
3007   bufferlist::const_iterator& blp)
3008 {
3009   _discard(cct, offset, length);
3010   auto i = iomap.insert(make_pair(offset, deferred_io()));
3011   assert(i.second);  // this should be a new insertion
3012   i.first->second.seq = seq;
3013   blp.copy(length, i.first->second.bl);
3014   i.first->second.bl.reassign_to_mempool(
3015     mempool::mempool_bluestore_writing_deferred);
3016   dout(20) << __func__ << " seq " << seq
3017            << " 0x" << std::hex << offset << "~" << length
3018            << " crc " << i.first->second.bl.crc32c(-1)
3019            << std::dec << dendl;
3020   seq_bytes[seq] += length;
3021 #ifdef DEBUG_DEFERRED
3022   _audit(cct);
3023 #endif
3024 }
3025
3026 void BlueStore::DeferredBatch::_discard(
3027   CephContext *cct, uint64_t offset, uint64_t length)
3028 {
3029   generic_dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
3030                    << std::dec << dendl;
3031   auto p = iomap.lower_bound(offset);
3032   if (p != iomap.begin()) {
3033     --p;
3034     auto end = p->first + p->second.bl.length();
3035     if (end > offset) {
3036       bufferlist head;
3037       head.substr_of(p->second.bl, 0, offset - p->first);
3038       dout(20) << __func__ << "  keep head " << p->second.seq
3039                << " 0x" << std::hex << p->first << "~" << p->second.bl.length()
3040                << " -> 0x" << head.length() << std::dec << dendl;
3041       auto i = seq_bytes.find(p->second.seq);
3042       assert(i != seq_bytes.end());
3043       if (end > offset + length) {
3044         bufferlist tail;
3045         tail.substr_of(p->second.bl, offset + length - p->first,
3046                        end - (offset + length));
3047         dout(20) << __func__ << "  keep tail " << p->second.seq
3048                  << " 0x" << std::hex << p->first << "~" << p->second.bl.length()
3049                  << " -> 0x" << tail.length() << std::dec << dendl;
3050         auto &n = iomap[offset + length];
3051         n.bl.swap(tail);
3052         n.seq = p->second.seq;
3053         i->second -= length;
3054       } else {
3055         i->second -= end - offset;
3056       }
3057       assert(i->second >= 0);
3058       p->second.bl.swap(head);
3059     }
3060     ++p;
3061   }
3062   while (p != iomap.end()) {
3063     if (p->first >= offset + length) {
3064       break;
3065     }
3066     auto i = seq_bytes.find(p->second.seq);
3067     assert(i != seq_bytes.end());
3068     auto end = p->first + p->second.bl.length();
3069     if (end > offset + length) {
3070       unsigned drop_front = offset + length - p->first;
3071       unsigned keep_tail = end - (offset + length);
3072       dout(20) << __func__ << "  truncate front " << p->second.seq
3073                << " 0x" << std::hex << p->first << "~" << p->second.bl.length()
3074                << " drop_front 0x" << drop_front << " keep_tail 0x" << keep_tail
3075                << " to 0x" << (offset + length) << "~" << keep_tail
3076                << std::dec << dendl;
3077       auto &s = iomap[offset + length];
3078       s.seq = p->second.seq;
3079       s.bl.substr_of(p->second.bl, drop_front, keep_tail);
3080       i->second -= drop_front;
3081     } else {
3082       dout(20) << __func__ << "  drop " << p->second.seq
3083                << " 0x" << std::hex << p->first << "~" << p->second.bl.length()
3084                << std::dec << dendl;
3085       i->second -= p->second.bl.length();
3086     }
3087     assert(i->second >= 0);
3088     p = iomap.erase(p);
3089   }
3090 }
3091
3092 void BlueStore::DeferredBatch::_audit(CephContext *cct)
3093 {
3094   map<uint64_t,int> sb;
3095   for (auto p : seq_bytes) {
3096     sb[p.first] = 0;  // make sure we have the same set of keys
3097   }
3098   uint64_t pos = 0;
3099   for (auto& p : iomap) {
3100     assert(p.first >= pos);
3101     sb[p.second.seq] += p.second.bl.length();
3102     pos = p.first + p.second.bl.length();
3103   }
3104   assert(sb == seq_bytes);
3105 }
3106
3107
3108 // Collection
3109
3110 #undef dout_prefix
3111 #define dout_prefix *_dout << "bluestore(" << store->path << ").collection(" << cid << " " << this << ") "
3112
3113 BlueStore::Collection::Collection(BlueStore *ns, Cache *c, coll_t cid)
3114   : store(ns),
3115     cache(c),
3116     cid(cid),
3117     lock("BlueStore::Collection::lock", true, false),
3118     exists(true),
3119     onode_map(c)
3120 {
3121 }
3122
3123 void BlueStore::Collection::open_shared_blob(uint64_t sbid, BlobRef b)
3124 {
3125   assert(!b->shared_blob);
3126   const bluestore_blob_t& blob = b->get_blob();
3127   if (!blob.is_shared()) {
3128     b->shared_blob = new SharedBlob(this);
3129     return;
3130   }
3131
3132   b->shared_blob = shared_blob_set.lookup(sbid);
3133   if (b->shared_blob) {
3134     ldout(store->cct, 10) << __func__ << " sbid 0x" << std::hex << sbid
3135                           << std::dec << " had " << *b->shared_blob << dendl;
3136   } else {
3137     b->shared_blob = new SharedBlob(sbid, this);
3138     shared_blob_set.add(this, b->shared_blob.get());
3139     ldout(store->cct, 10) << __func__ << " sbid 0x" << std::hex << sbid
3140                           << std::dec << " opened " << *b->shared_blob
3141                           << dendl;
3142   }
3143 }
3144
3145 void BlueStore::Collection::load_shared_blob(SharedBlobRef sb)
3146 {
3147   if (!sb->is_loaded()) {
3148
3149     bufferlist v;
3150     string key;
3151     auto sbid = sb->get_sbid();
3152     get_shared_blob_key(sbid, &key);
3153     int r = store->db->get(PREFIX_SHARED_BLOB, key, &v);
3154     if (r < 0) {
3155         lderr(store->cct) << __func__ << " sbid 0x" << std::hex << sbid
3156                           << std::dec << " not found at key "
3157                           << pretty_binary_string(key) << dendl;
3158       assert(0 == "uh oh, missing shared_blob");
3159     }
3160
3161     sb->loaded = true;
3162     sb->persistent = new bluestore_shared_blob_t(sbid);
3163     bufferlist::iterator p = v.begin();
3164     ::decode(*(sb->persistent), p);
3165     ldout(store->cct, 10) << __func__ << " sbid 0x" << std::hex << sbid
3166                           << std::dec << " loaded shared_blob " << *sb << dendl;
3167   }
3168 }
3169
3170 void BlueStore::Collection::make_blob_shared(uint64_t sbid, BlobRef b)
3171 {
3172   ldout(store->cct, 10) << __func__ << " " << *b << dendl;
3173   assert(!b->shared_blob->is_loaded());
3174
3175   // update blob
3176   bluestore_blob_t& blob = b->dirty_blob();
3177   blob.set_flag(bluestore_blob_t::FLAG_SHARED);
3178
3179   // update shared blob
3180   b->shared_blob->loaded = true;
3181   b->shared_blob->persistent = new bluestore_shared_blob_t(sbid);
3182   shared_blob_set.add(this, b->shared_blob.get());
3183   for (auto p : blob.get_extents()) {
3184     if (p.is_valid()) {
3185       b->shared_blob->get_ref(
3186         p.offset,
3187         p.length);
3188     }
3189   }
3190   ldout(store->cct, 20) << __func__ << " now " << *b << dendl;
3191 }
3192
3193 uint64_t BlueStore::Collection::make_blob_unshared(SharedBlob *sb)
3194 {
3195   ldout(store->cct, 10) << __func__ << " " << *sb << dendl;
3196   assert(sb->is_loaded());
3197
3198   uint64_t sbid = sb->get_sbid();
3199   shared_blob_set.remove(sb);
3200   sb->loaded = false;
3201   delete sb->persistent;
3202   sb->sbid_unloaded = 0;
3203   ldout(store->cct, 20) << __func__ << " now " << *sb << dendl;
3204   return sbid;
3205 }
3206
3207 BlueStore::OnodeRef BlueStore::Collection::get_onode(
3208   const ghobject_t& oid,
3209   bool create)
3210 {
3211   assert(create ? lock.is_wlocked() : lock.is_locked());
3212
3213   spg_t pgid;
3214   if (cid.is_pg(&pgid)) {
3215     if (!oid.match(cnode.bits, pgid.ps())) {
3216       lderr(store->cct) << __func__ << " oid " << oid << " not part of "
3217                         << pgid << " bits " << cnode.bits << dendl;
3218       ceph_abort();
3219     }
3220   }
3221
3222   OnodeRef o = onode_map.lookup(oid);
3223   if (o)
3224     return o;
3225
3226   mempool::bluestore_cache_other::string key;
3227   get_object_key(store->cct, oid, &key);
3228
3229   ldout(store->cct, 20) << __func__ << " oid " << oid << " key "
3230                         << pretty_binary_string(key) << dendl;
3231
3232   bufferlist v;
3233   int r = store->db->get(PREFIX_OBJ, key.c_str(), key.size(), &v);
3234   ldout(store->cct, 20) << " r " << r << " v.len " << v.length() << dendl;
3235   Onode *on;
3236   if (v.length() == 0) {
3237     assert(r == -ENOENT);
3238     if (!store->cct->_conf->bluestore_debug_misc &&
3239         !create)
3240       return OnodeRef();
3241
3242     // new object, new onode
3243     on = new Onode(this, oid, key);
3244   } else {
3245     // loaded
3246     assert(r >= 0);
3247     on = new Onode(this, oid, key);
3248     on->exists = true;
3249     bufferptr::iterator p = v.front().begin_deep();
3250     on->onode.decode(p);
3251     for (auto& i : on->onode.attrs) {
3252       i.second.reassign_to_mempool(mempool::mempool_bluestore_cache_other);
3253     }
3254
3255     // initialize extent_map
3256     on->extent_map.decode_spanning_blobs(p);
3257     if (on->onode.extent_map_shards.empty()) {
3258       denc(on->extent_map.inline_bl, p);
3259       on->extent_map.decode_some(on->extent_map.inline_bl);
3260       on->extent_map.inline_bl.reassign_to_mempool(
3261         mempool::mempool_bluestore_cache_other);
3262     } else {
3263       on->extent_map.init_shards(false, false);
3264     }
3265   }
3266   o.reset(on);
3267   return onode_map.add(oid, o);
3268 }
3269
3270 void BlueStore::Collection::split_cache(
3271   Collection *dest)
3272 {
3273   ldout(store->cct, 10) << __func__ << " to " << dest << dendl;
3274
3275   // lock (one or both) cache shards
3276   std::lock(cache->lock, dest->cache->lock);
3277   std::lock_guard<std::recursive_mutex> l(cache->lock, std::adopt_lock);
3278   std::lock_guard<std::recursive_mutex> l2(dest->cache->lock, std::adopt_lock);
3279
3280   int destbits = dest->cnode.bits;
3281   spg_t destpg;
3282   bool is_pg = dest->cid.is_pg(&destpg);
3283   assert(is_pg);
3284
3285   auto p = onode_map.onode_map.begin();
3286   while (p != onode_map.onode_map.end()) {
3287     if (!p->second->oid.match(destbits, destpg.pgid.ps())) {
3288       // onode does not belong to this child
3289       ++p;
3290     } else {
3291       OnodeRef o = p->second;
3292       ldout(store->cct, 20) << __func__ << " moving " << o << " " << o->oid
3293                             << dendl;
3294
3295       cache->_rm_onode(p->second);
3296       p = onode_map.onode_map.erase(p);
3297
3298       o->c = dest;
3299       dest->cache->_add_onode(o, 1);
3300       dest->onode_map.onode_map[o->oid] = o;
3301       dest->onode_map.cache = dest->cache;
3302
3303       // move over shared blobs and buffers.  cover shared blobs from
3304       // both extent map and spanning blob map (the full extent map
3305       // may not be faulted in)
3306       vector<SharedBlob*> sbvec;
3307       for (auto& e : o->extent_map.extent_map) {
3308         sbvec.push_back(e.blob->shared_blob.get());
3309       }
3310       for (auto& b : o->extent_map.spanning_blob_map) {
3311         sbvec.push_back(b.second->shared_blob.get());
3312       }
3313       for (auto sb : sbvec) {
3314         if (sb->coll == dest) {
3315           ldout(store->cct, 20) << __func__ << "  already moved " << *sb
3316                                 << dendl;
3317           continue;
3318         }
3319         ldout(store->cct, 20) << __func__ << "  moving " << *sb << dendl;
3320         if (sb->get_sbid()) {
3321           ldout(store->cct, 20) << __func__
3322                                 << "   moving registration " << *sb << dendl;
3323           shared_blob_set.remove(sb);
3324           dest->shared_blob_set.add(dest, sb);
3325         }
3326         sb->coll = dest;
3327         if (dest->cache != cache) {
3328           for (auto& i : sb->bc.buffer_map) {
3329             if (!i.second->is_writing()) {
3330               ldout(store->cct, 20) << __func__ << "   moving " << *i.second
3331                                     << dendl;
3332               dest->cache->_move_buffer(cache, i.second.get());
3333             }
3334           }
3335         }
3336       }
3337     }
3338   }
3339 }
3340
3341 // =======================================================
3342
3343 void *BlueStore::MempoolThread::entry()
3344 {
3345   Mutex::Locker l(lock);
3346   while (!stop) {
3347     uint64_t meta_bytes =
3348       mempool::bluestore_cache_other::allocated_bytes() +
3349       mempool::bluestore_cache_onode::allocated_bytes();
3350     uint64_t onode_num =
3351       mempool::bluestore_cache_onode::allocated_items();
3352
3353     if (onode_num < 2) {
3354       onode_num = 2;
3355     }
3356
3357     float bytes_per_onode = (float)meta_bytes / (float)onode_num;
3358     size_t num_shards = store->cache_shards.size();
3359     float target_ratio = store->cache_meta_ratio + store->cache_data_ratio;
3360     // A little sloppy but should be close enough
3361     uint64_t shard_target = target_ratio * (store->cache_size / num_shards);
3362
3363     for (auto i : store->cache_shards) {
3364       i->trim(shard_target,
3365               store->cache_meta_ratio,
3366               store->cache_data_ratio,
3367               bytes_per_onode);
3368     }
3369
3370     store->_update_cache_logger();
3371
3372     utime_t wait;
3373     wait += store->cct->_conf->bluestore_cache_trim_interval;
3374     cond.WaitInterval(lock, wait);
3375   }
3376   stop = false;
3377   return NULL;
3378 }
3379
3380 // =======================================================
3381
3382 // OmapIteratorImpl
3383
3384 #undef dout_prefix
3385 #define dout_prefix *_dout << "bluestore.OmapIteratorImpl(" << this << ") "
3386
3387 BlueStore::OmapIteratorImpl::OmapIteratorImpl(
3388   CollectionRef c, OnodeRef o, KeyValueDB::Iterator it)
3389   : c(c), o(o), it(it)
3390 {
3391   RWLock::RLocker l(c->lock);
3392   if (o->onode.has_omap()) {
3393     get_omap_key(o->onode.nid, string(), &head);
3394     get_omap_tail(o->onode.nid, &tail);
3395     it->lower_bound(head);
3396   }
3397 }
3398
3399 int BlueStore::OmapIteratorImpl::seek_to_first()
3400 {
3401   RWLock::RLocker l(c->lock);
3402   if (o->onode.has_omap()) {
3403     it->lower_bound(head);
3404   } else {
3405     it = KeyValueDB::Iterator();
3406   }
3407   return 0;
3408 }
3409
3410 int BlueStore::OmapIteratorImpl::upper_bound(const string& after)
3411 {
3412   RWLock::RLocker l(c->lock);
3413   if (o->onode.has_omap()) {
3414     string key;
3415     get_omap_key(o->onode.nid, after, &key);
3416     ldout(c->store->cct,20) << __func__ << " after " << after << " key "
3417                             << pretty_binary_string(key) << dendl;
3418     it->upper_bound(key);
3419   } else {
3420     it = KeyValueDB::Iterator();
3421   }
3422   return 0;
3423 }
3424
3425 int BlueStore::OmapIteratorImpl::lower_bound(const string& to)
3426 {
3427   RWLock::RLocker l(c->lock);
3428   if (o->onode.has_omap()) {
3429     string key;
3430     get_omap_key(o->onode.nid, to, &key);
3431     ldout(c->store->cct,20) << __func__ << " to " << to << " key "
3432                             << pretty_binary_string(key) << dendl;
3433     it->lower_bound(key);
3434   } else {
3435     it = KeyValueDB::Iterator();
3436   }
3437   return 0;
3438 }
3439
3440 bool BlueStore::OmapIteratorImpl::valid()
3441 {
3442   RWLock::RLocker l(c->lock);
3443   bool r = o->onode.has_omap() && it && it->valid() &&
3444     it->raw_key().second <= tail;
3445   if (it && it->valid()) {
3446     ldout(c->store->cct,20) << __func__ << " is at "
3447                             << pretty_binary_string(it->raw_key().second)
3448                             << dendl;
3449   }
3450   return r;
3451 }
3452
3453 int BlueStore::OmapIteratorImpl::next(bool validate)
3454 {
3455   RWLock::RLocker l(c->lock);
3456   if (o->onode.has_omap()) {
3457     it->next();
3458     return 0;
3459   } else {
3460     return -1;
3461   }
3462 }
3463
3464 string BlueStore::OmapIteratorImpl::key()
3465 {
3466   RWLock::RLocker l(c->lock);
3467   assert(it->valid());
3468   string db_key = it->raw_key().second;
3469   string user_key;
3470   decode_omap_key(db_key, &user_key);
3471   return user_key;
3472 }
3473
3474 bufferlist BlueStore::OmapIteratorImpl::value()
3475 {
3476   RWLock::RLocker l(c->lock);
3477   assert(it->valid());
3478   return it->value();
3479 }
3480
3481
3482 // =====================================
3483
3484 #undef dout_prefix
3485 #define dout_prefix *_dout << "bluestore(" << path << ") "
3486
3487
3488 static void aio_cb(void *priv, void *priv2)
3489 {
3490   BlueStore *store = static_cast<BlueStore*>(priv);
3491   BlueStore::AioContext *c = static_cast<BlueStore::AioContext*>(priv2);
3492   c->aio_finish(store);
3493 }
3494
3495 BlueStore::BlueStore(CephContext *cct, const string& path)
3496   : ObjectStore(cct, path),
3497     throttle_bytes(cct, "bluestore_throttle_bytes",
3498                    cct->_conf->bluestore_throttle_bytes),
3499     throttle_deferred_bytes(cct, "bluestore_throttle_deferred_bytes",
3500                        cct->_conf->bluestore_throttle_bytes +
3501                        cct->_conf->bluestore_throttle_deferred_bytes),
3502     deferred_finisher(cct, "defered_finisher", "dfin"),
3503     kv_sync_thread(this),
3504     kv_finalize_thread(this),
3505     mempool_thread(this)
3506 {
3507   _init_logger();
3508   cct->_conf->add_observer(this);
3509   set_cache_shards(1);
3510 }
3511
3512 BlueStore::BlueStore(CephContext *cct,
3513   const string& path,
3514   uint64_t _min_alloc_size)
3515   : ObjectStore(cct, path),
3516     throttle_bytes(cct, "bluestore_throttle_bytes",
3517                    cct->_conf->bluestore_throttle_bytes),
3518     throttle_deferred_bytes(cct, "bluestore_throttle_deferred_bytes",
3519                        cct->_conf->bluestore_throttle_bytes +
3520                        cct->_conf->bluestore_throttle_deferred_bytes),
3521     deferred_finisher(cct, "defered_finisher", "dfin"),
3522     kv_sync_thread(this),
3523     kv_finalize_thread(this),
3524     min_alloc_size(_min_alloc_size),
3525     min_alloc_size_order(ctz(_min_alloc_size)),
3526     mempool_thread(this)
3527 {
3528   _init_logger();
3529   cct->_conf->add_observer(this);
3530   set_cache_shards(1);
3531 }
3532
3533 BlueStore::~BlueStore()
3534 {
3535   for (auto f : finishers) {
3536     delete f;
3537   }
3538   finishers.clear();
3539
3540   cct->_conf->remove_observer(this);
3541   _shutdown_logger();
3542   assert(!mounted);
3543   assert(db == NULL);
3544   assert(bluefs == NULL);
3545   assert(fsid_fd < 0);
3546   assert(path_fd < 0);
3547   for (auto i : cache_shards) {
3548     delete i;
3549   }
3550   cache_shards.clear();
3551 }
3552
3553 const char **BlueStore::get_tracked_conf_keys() const
3554 {
3555   static const char* KEYS[] = {
3556     "bluestore_csum_type",
3557     "bluestore_compression_mode",
3558     "bluestore_compression_algorithm",
3559     "bluestore_compression_min_blob_size",
3560     "bluestore_compression_min_blob_size_ssd",
3561     "bluestore_compression_min_blob_size_hdd",
3562     "bluestore_compression_max_blob_size",
3563     "bluestore_compression_max_blob_size_ssd",
3564     "bluestore_compression_max_blob_size_hdd",
3565     "bluestore_compression_required_ratio",
3566     "bluestore_max_alloc_size",
3567     "bluestore_prefer_deferred_size",
3568     "bluestore_prefer_deferred_size_hdd",
3569     "bluestore_prefer_deferred_size_ssd",
3570     "bluestore_deferred_batch_ops",
3571     "bluestore_deferred_batch_ops_hdd",
3572     "bluestore_deferred_batch_ops_ssd",
3573     "bluestore_throttle_bytes",
3574     "bluestore_throttle_deferred_bytes",
3575     "bluestore_throttle_cost_per_io_hdd",
3576     "bluestore_throttle_cost_per_io_ssd",
3577     "bluestore_throttle_cost_per_io",
3578     "bluestore_max_blob_size",
3579     "bluestore_max_blob_size_ssd",
3580     "bluestore_max_blob_size_hdd",
3581     NULL
3582   };
3583   return KEYS;
3584 }
3585
3586 void BlueStore::handle_conf_change(const struct md_config_t *conf,
3587                                    const std::set<std::string> &changed)
3588 {
3589   if (changed.count("bluestore_csum_type")) {
3590     _set_csum();
3591   }
3592   if (changed.count("bluestore_compression_mode") ||
3593       changed.count("bluestore_compression_algorithm") ||
3594       changed.count("bluestore_compression_min_blob_size") ||
3595       changed.count("bluestore_compression_max_blob_size")) {
3596     if (bdev) {
3597       _set_compression();
3598     }
3599   }
3600   if (changed.count("bluestore_max_blob_size") ||
3601       changed.count("bluestore_max_blob_size_ssd") ||
3602       changed.count("bluestore_max_blob_size_hdd")) {
3603     if (bdev) {
3604       // only after startup
3605       _set_blob_size();
3606     }
3607   }
3608   if (changed.count("bluestore_prefer_deferred_size") ||
3609       changed.count("bluestore_prefer_deferred_size_hdd") ||
3610       changed.count("bluestore_prefer_deferred_size_ssd") ||
3611       changed.count("bluestore_max_alloc_size") ||
3612       changed.count("bluestore_deferred_batch_ops") ||
3613       changed.count("bluestore_deferred_batch_ops_hdd") ||
3614       changed.count("bluestore_deferred_batch_ops_ssd")) {
3615     if (bdev) {
3616       // only after startup
3617       _set_alloc_sizes();
3618     }
3619   }
3620   if (changed.count("bluestore_throttle_cost_per_io") ||
3621       changed.count("bluestore_throttle_cost_per_io_hdd") ||
3622       changed.count("bluestore_throttle_cost_per_io_ssd")) {
3623     if (bdev) {
3624       _set_throttle_params();
3625     }
3626   }
3627   if (changed.count("bluestore_throttle_bytes")) {
3628     throttle_bytes.reset_max(conf->bluestore_throttle_bytes);
3629     throttle_deferred_bytes.reset_max(
3630       conf->bluestore_throttle_bytes + conf->bluestore_throttle_deferred_bytes);
3631   }
3632   if (changed.count("bluestore_throttle_deferred_bytes")) {
3633     throttle_deferred_bytes.reset_max(
3634       conf->bluestore_throttle_bytes + conf->bluestore_throttle_deferred_bytes);
3635   }
3636 }
3637
3638 void BlueStore::_set_compression()
3639 {
3640   auto m = Compressor::get_comp_mode_type(cct->_conf->bluestore_compression_mode);
3641   if (m) {
3642     comp_mode = *m;
3643   } else {
3644     derr << __func__ << " unrecognized value '"
3645          << cct->_conf->bluestore_compression_mode
3646          << "' for bluestore_compression_mode, reverting to 'none'"
3647          << dendl;
3648     comp_mode = Compressor::COMP_NONE;
3649   }
3650
3651   compressor = nullptr;
3652
3653   if (comp_mode == Compressor::COMP_NONE) {
3654     dout(10) << __func__ << " compression mode set to 'none', "
3655              << "ignore other compression setttings" << dendl;
3656     return;
3657   }
3658
3659   if (cct->_conf->bluestore_compression_min_blob_size) {
3660     comp_min_blob_size = cct->_conf->bluestore_compression_min_blob_size;
3661   } else {
3662     assert(bdev);
3663     if (bdev->is_rotational()) {
3664       comp_min_blob_size = cct->_conf->bluestore_compression_min_blob_size_hdd;
3665     } else {
3666       comp_min_blob_size = cct->_conf->bluestore_compression_min_blob_size_ssd;
3667     }
3668   }
3669
3670   if (cct->_conf->bluestore_compression_max_blob_size) {
3671     comp_max_blob_size = cct->_conf->bluestore_compression_max_blob_size;
3672   } else {
3673     assert(bdev);
3674     if (bdev->is_rotational()) {
3675       comp_max_blob_size = cct->_conf->bluestore_compression_max_blob_size_hdd;
3676     } else {
3677       comp_max_blob_size = cct->_conf->bluestore_compression_max_blob_size_ssd;
3678     }
3679   }
3680
3681   auto& alg_name = cct->_conf->bluestore_compression_algorithm;
3682   if (!alg_name.empty()) {
3683     compressor = Compressor::create(cct, alg_name);
3684     if (!compressor) {
3685       derr << __func__ << " unable to initialize " << alg_name.c_str() << " compressor"
3686            << dendl;
3687     }
3688   }
3689  
3690   dout(10) << __func__ << " mode " << Compressor::get_comp_mode_name(comp_mode)
3691            << " alg " << (compressor ? compressor->get_type_name() : "(none)")
3692            << dendl;
3693 }
3694
3695 void BlueStore::_set_csum()
3696 {
3697   csum_type = Checksummer::CSUM_NONE;
3698   int t = Checksummer::get_csum_string_type(cct->_conf->bluestore_csum_type);
3699   if (t > Checksummer::CSUM_NONE)
3700     csum_type = t;
3701
3702   dout(10) << __func__ << " csum_type "
3703            << Checksummer::get_csum_type_string(csum_type)
3704            << dendl;
3705 }
3706
3707 void BlueStore::_set_throttle_params()
3708 {
3709   if (cct->_conf->bluestore_throttle_cost_per_io) {
3710     throttle_cost_per_io = cct->_conf->bluestore_throttle_cost_per_io;
3711   } else {
3712     assert(bdev);
3713     if (bdev->is_rotational()) {
3714       throttle_cost_per_io = cct->_conf->bluestore_throttle_cost_per_io_hdd;
3715     } else {
3716       throttle_cost_per_io = cct->_conf->bluestore_throttle_cost_per_io_ssd;
3717     }
3718   }
3719
3720   dout(10) << __func__ << " throttle_cost_per_io " << throttle_cost_per_io
3721            << dendl;
3722 }
3723 void BlueStore::_set_blob_size()
3724 {
3725   if (cct->_conf->bluestore_max_blob_size) {
3726     max_blob_size = cct->_conf->bluestore_max_blob_size;
3727   } else {
3728     assert(bdev);
3729     if (bdev->is_rotational()) {
3730       max_blob_size = cct->_conf->bluestore_max_blob_size_hdd;
3731     } else {
3732       max_blob_size = cct->_conf->bluestore_max_blob_size_ssd;
3733     }
3734   }
3735   dout(10) << __func__ << " max_blob_size 0x" << std::hex << max_blob_size
3736            << std::dec << dendl;
3737 }
3738
3739 int BlueStore::_set_cache_sizes()
3740 {
3741   assert(bdev);
3742   if (cct->_conf->bluestore_cache_size) {
3743     cache_size = cct->_conf->bluestore_cache_size;
3744   } else {
3745     // choose global cache size based on backend type
3746     if (bdev->is_rotational()) {
3747       cache_size = cct->_conf->bluestore_cache_size_hdd;
3748     } else {
3749       cache_size = cct->_conf->bluestore_cache_size_ssd;
3750     }
3751   }
3752   cache_meta_ratio = cct->_conf->bluestore_cache_meta_ratio;
3753   cache_kv_ratio = cct->_conf->bluestore_cache_kv_ratio;
3754
3755   double cache_kv_max = cct->_conf->bluestore_cache_kv_max;
3756   double cache_kv_max_ratio = 0;
3757
3758   // if cache_kv_max is negative, disable it
3759   if (cache_size > 0 && cache_kv_max >= 0) {
3760     cache_kv_max_ratio = (double) cache_kv_max / (double) cache_size;
3761     if (cache_kv_max_ratio < 1.0 && cache_kv_max_ratio < cache_kv_ratio) {
3762       dout(1) << __func__ << " max " << cache_kv_max_ratio
3763             << " < ratio " << cache_kv_ratio
3764             << dendl;
3765       cache_meta_ratio = cache_meta_ratio + cache_kv_ratio - cache_kv_max_ratio;
3766       cache_kv_ratio = cache_kv_max_ratio;
3767     }
3768   }  
3769
3770   cache_data_ratio =
3771     (double)1.0 - (double)cache_meta_ratio - (double)cache_kv_ratio;
3772
3773   if (cache_meta_ratio < 0 || cache_meta_ratio > 1.0) {
3774     derr << __func__ << " bluestore_cache_meta_ratio (" << cache_meta_ratio
3775          << ") must be in range [0,1.0]" << dendl;
3776     return -EINVAL;
3777   }
3778   if (cache_kv_ratio < 0 || cache_kv_ratio > 1.0) {
3779     derr << __func__ << " bluestore_cache_kv_ratio (" << cache_kv_ratio
3780          << ") must be in range [0,1.0]" << dendl;
3781     return -EINVAL;
3782   }
3783   if (cache_meta_ratio + cache_kv_ratio > 1.0) {
3784     derr << __func__ << " bluestore_cache_meta_ratio (" << cache_meta_ratio
3785          << ") + bluestore_cache_kv_ratio (" << cache_kv_ratio
3786          << ") = " << cache_meta_ratio + cache_kv_ratio << "; must be <= 1.0"
3787          << dendl;
3788     return -EINVAL;
3789   }
3790   if (cache_data_ratio < 0) {
3791     // deal with floating point imprecision
3792     cache_data_ratio = 0;
3793   }
3794   dout(1) << __func__ << " cache_size " << cache_size
3795           << " meta " << cache_meta_ratio
3796           << " kv " << cache_kv_ratio
3797           << " data " << cache_data_ratio
3798           << dendl;
3799   return 0;
3800 }
3801
3802 int BlueStore::write_meta(const std::string& key, const std::string& value)
3803 {
3804   bluestore_bdev_label_t label;
3805   string p = path + "/block";
3806   int r = _read_bdev_label(cct, p, &label);
3807   if (r < 0) {
3808     return ObjectStore::write_meta(key, value);
3809   }
3810   label.meta[key] = value;
3811   r = _write_bdev_label(cct, p, label);
3812   assert(r == 0);
3813   return ObjectStore::write_meta(key, value);
3814 }
3815
3816 int BlueStore::read_meta(const std::string& key, std::string *value)
3817 {
3818   bluestore_bdev_label_t label;
3819   string p = path + "/block";
3820   int r = _read_bdev_label(cct, p, &label);
3821   if (r < 0) {
3822     return ObjectStore::read_meta(key, value);
3823   }
3824   auto i = label.meta.find(key);
3825   if (i == label.meta.end()) {
3826     return ObjectStore::read_meta(key, value);
3827   }
3828   *value = i->second;
3829   return 0;
3830 }
3831
3832 void BlueStore::_init_logger()
3833 {
3834   PerfCountersBuilder b(cct, "bluestore",
3835                         l_bluestore_first, l_bluestore_last);
3836   b.add_time_avg(l_bluestore_kv_flush_lat, "kv_flush_lat",
3837                  "Average kv_thread flush latency",
3838                  "fl_l", PerfCountersBuilder::PRIO_INTERESTING);
3839   b.add_time_avg(l_bluestore_kv_commit_lat, "kv_commit_lat",
3840                  "Average kv_thread commit latency");
3841   b.add_time_avg(l_bluestore_kv_lat, "kv_lat",
3842                  "Average kv_thread sync latency",
3843                  "k_l", PerfCountersBuilder::PRIO_INTERESTING);
3844   b.add_time_avg(l_bluestore_state_prepare_lat, "state_prepare_lat",
3845     "Average prepare state latency");
3846   b.add_time_avg(l_bluestore_state_aio_wait_lat, "state_aio_wait_lat",
3847                  "Average aio_wait state latency",
3848                  "io_l", PerfCountersBuilder::PRIO_INTERESTING);
3849   b.add_time_avg(l_bluestore_state_io_done_lat, "state_io_done_lat",
3850     "Average io_done state latency");
3851   b.add_time_avg(l_bluestore_state_kv_queued_lat, "state_kv_queued_lat",
3852     "Average kv_queued state latency");
3853   b.add_time_avg(l_bluestore_state_kv_committing_lat, "state_kv_commiting_lat",
3854     "Average kv_commiting state latency");
3855   b.add_time_avg(l_bluestore_state_kv_done_lat, "state_kv_done_lat",
3856     "Average kv_done state latency");
3857   b.add_time_avg(l_bluestore_state_deferred_queued_lat, "state_deferred_queued_lat",
3858     "Average deferred_queued state latency");
3859   b.add_time_avg(l_bluestore_state_deferred_aio_wait_lat, "state_deferred_aio_wait_lat",
3860     "Average aio_wait state latency");
3861   b.add_time_avg(l_bluestore_state_deferred_cleanup_lat, "state_deferred_cleanup_lat",
3862     "Average cleanup state latency");
3863   b.add_time_avg(l_bluestore_state_finishing_lat, "state_finishing_lat",
3864     "Average finishing state latency");
3865   b.add_time_avg(l_bluestore_state_done_lat, "state_done_lat",
3866     "Average done state latency");
3867   b.add_time_avg(l_bluestore_throttle_lat, "throttle_lat",
3868                  "Average submit throttle latency",
3869                  "th_l", PerfCountersBuilder::PRIO_CRITICAL);
3870   b.add_time_avg(l_bluestore_submit_lat, "submit_lat",
3871                  "Average submit latency",
3872                  "s_l", PerfCountersBuilder::PRIO_CRITICAL);
3873   b.add_time_avg(l_bluestore_commit_lat, "commit_lat",
3874                  "Average commit latency",
3875                  "c_l", PerfCountersBuilder::PRIO_CRITICAL);
3876   b.add_time_avg(l_bluestore_read_lat, "read_lat",
3877                  "Average read latency",
3878                  "r_l", PerfCountersBuilder::PRIO_CRITICAL);
3879   b.add_time_avg(l_bluestore_read_onode_meta_lat, "read_onode_meta_lat",
3880     "Average read onode metadata latency");
3881   b.add_time_avg(l_bluestore_read_wait_aio_lat, "read_wait_aio_lat",
3882     "Average read latency");
3883   b.add_time_avg(l_bluestore_compress_lat, "compress_lat",
3884     "Average compress latency");
3885   b.add_time_avg(l_bluestore_decompress_lat, "decompress_lat",
3886     "Average decompress latency");
3887   b.add_time_avg(l_bluestore_csum_lat, "csum_lat",
3888     "Average checksum latency");
3889   b.add_u64_counter(l_bluestore_compress_success_count, "compress_success_count",
3890     "Sum for beneficial compress ops");
3891   b.add_u64_counter(l_bluestore_compress_rejected_count, "compress_rejected_count",
3892     "Sum for compress ops rejected due to low net gain of space");
3893   b.add_u64_counter(l_bluestore_write_pad_bytes, "write_pad_bytes",
3894     "Sum for write-op padded bytes");
3895   b.add_u64_counter(l_bluestore_deferred_write_ops, "deferred_write_ops",
3896                     "Sum for deferred write op");
3897   b.add_u64_counter(l_bluestore_deferred_write_bytes, "deferred_write_bytes",
3898                     "Sum for deferred write bytes", "def");
3899   b.add_u64_counter(l_bluestore_write_penalty_read_ops, "write_penalty_read_ops",
3900                     "Sum for write penalty read ops");
3901   b.add_u64(l_bluestore_allocated, "bluestore_allocated",
3902     "Sum for allocated bytes");
3903   b.add_u64(l_bluestore_stored, "bluestore_stored",
3904     "Sum for stored bytes");
3905   b.add_u64(l_bluestore_compressed, "bluestore_compressed",
3906     "Sum for stored compressed bytes");
3907   b.add_u64(l_bluestore_compressed_allocated, "bluestore_compressed_allocated",
3908     "Sum for bytes allocated for compressed data");
3909   b.add_u64(l_bluestore_compressed_original, "bluestore_compressed_original",
3910     "Sum for original bytes that were compressed");
3911
3912   b.add_u64(l_bluestore_onodes, "bluestore_onodes",
3913             "Number of onodes in cache");
3914   b.add_u64_counter(l_bluestore_onode_hits, "bluestore_onode_hits",
3915                     "Sum for onode-lookups hit in the cache");
3916   b.add_u64_counter(l_bluestore_onode_misses, "bluestore_onode_misses",
3917                     "Sum for onode-lookups missed in the cache");
3918   b.add_u64_counter(l_bluestore_onode_shard_hits, "bluestore_onode_shard_hits",
3919                     "Sum for onode-shard lookups hit in the cache");
3920   b.add_u64_counter(l_bluestore_onode_shard_misses,
3921                     "bluestore_onode_shard_misses",
3922                     "Sum for onode-shard lookups missed in the cache");
3923   b.add_u64(l_bluestore_extents, "bluestore_extents",
3924             "Number of extents in cache");
3925   b.add_u64(l_bluestore_blobs, "bluestore_blobs",
3926             "Number of blobs in cache");
3927   b.add_u64(l_bluestore_buffers, "bluestore_buffers",
3928             "Number of buffers in cache");
3929   b.add_u64(l_bluestore_buffer_bytes, "bluestore_buffer_bytes",
3930             "Number of buffer bytes in cache");
3931   b.add_u64(l_bluestore_buffer_hit_bytes, "bluestore_buffer_hit_bytes",
3932     "Sum for bytes of read hit in the cache");
3933   b.add_u64(l_bluestore_buffer_miss_bytes, "bluestore_buffer_miss_bytes",
3934     "Sum for bytes of read missed in the cache");
3935
3936   b.add_u64_counter(l_bluestore_write_big, "bluestore_write_big",
3937                     "Large aligned writes into fresh blobs");
3938   b.add_u64_counter(l_bluestore_write_big_bytes, "bluestore_write_big_bytes",
3939                     "Large aligned writes into fresh blobs (bytes)");
3940   b.add_u64_counter(l_bluestore_write_big_blobs, "bluestore_write_big_blobs",
3941                     "Large aligned writes into fresh blobs (blobs)");
3942   b.add_u64_counter(l_bluestore_write_small, "bluestore_write_small",
3943                     "Small writes into existing or sparse small blobs");
3944   b.add_u64_counter(l_bluestore_write_small_bytes, "bluestore_write_small_bytes",
3945                     "Small writes into existing or sparse small blobs (bytes)");
3946   b.add_u64_counter(l_bluestore_write_small_unused,
3947                     "bluestore_write_small_unused",
3948                     "Small writes into unused portion of existing blob");
3949   b.add_u64_counter(l_bluestore_write_small_deferred,
3950                     "bluestore_write_small_deferred",
3951                     "Small overwrites using deferred");
3952   b.add_u64_counter(l_bluestore_write_small_pre_read,
3953                     "bluestore_write_small_pre_read",
3954                     "Small writes that required we read some data (possibly "
3955                     "cached) to fill out the block");
3956   b.add_u64_counter(l_bluestore_write_small_new, "bluestore_write_small_new",
3957                     "Small write into new (sparse) blob");
3958
3959   b.add_u64_counter(l_bluestore_txc, "bluestore_txc", "Transactions committed");
3960   b.add_u64_counter(l_bluestore_onode_reshard, "bluestore_onode_reshard",
3961                     "Onode extent map reshard events");
3962   b.add_u64_counter(l_bluestore_blob_split, "bluestore_blob_split",
3963                     "Sum for blob splitting due to resharding");
3964   b.add_u64_counter(l_bluestore_extent_compress, "bluestore_extent_compress",
3965                     "Sum for extents that have been removed due to compression");
3966   b.add_u64_counter(l_bluestore_gc_merged, "bluestore_gc_merged",
3967                     "Sum for extents that have been merged due to garbage "
3968                     "collection");
3969   logger = b.create_perf_counters();
3970   cct->get_perfcounters_collection()->add(logger);
3971 }
3972
3973 int BlueStore::_reload_logger()
3974 {
3975   struct store_statfs_t store_statfs;
3976
3977   int r = statfs(&store_statfs);
3978   if(r >= 0) {
3979     logger->set(l_bluestore_allocated, store_statfs.allocated);
3980     logger->set(l_bluestore_stored, store_statfs.stored);
3981     logger->set(l_bluestore_compressed, store_statfs.compressed);
3982     logger->set(l_bluestore_compressed_allocated, store_statfs.compressed_allocated);
3983     logger->set(l_bluestore_compressed_original, store_statfs.compressed_original);
3984   }
3985   return r;
3986 }
3987
3988 void BlueStore::_shutdown_logger()
3989 {
3990   cct->get_perfcounters_collection()->remove(logger);
3991   delete logger;
3992 }
3993
3994 int BlueStore::get_block_device_fsid(CephContext* cct, const string& path,
3995                                      uuid_d *fsid)
3996 {
3997   bluestore_bdev_label_t label;
3998   int r = _read_bdev_label(cct, path, &label);
3999   if (r < 0)
4000     return r;
4001   *fsid = label.osd_uuid;
4002   return 0;
4003 }
4004
4005 int BlueStore::_open_path()
4006 {
4007   assert(path_fd < 0);
4008   path_fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_DIRECTORY));
4009   if (path_fd < 0) {
4010     int r = -errno;
4011     derr << __func__ << " unable to open " << path << ": " << cpp_strerror(r)
4012          << dendl;
4013     return r;
4014   }
4015   return 0;
4016 }
4017
4018 void BlueStore::_close_path()
4019 {
4020   VOID_TEMP_FAILURE_RETRY(::close(path_fd));
4021   path_fd = -1;
4022 }
4023
4024 int BlueStore::_write_bdev_label(CephContext *cct,
4025                                  string path, bluestore_bdev_label_t label)
4026 {
4027   dout(10) << __func__ << " path " << path << " label " << label << dendl;
4028   bufferlist bl;
4029   ::encode(label, bl);
4030   uint32_t crc = bl.crc32c(-1);
4031   ::encode(crc, bl);
4032   assert(bl.length() <= BDEV_LABEL_BLOCK_SIZE);
4033   bufferptr z(BDEV_LABEL_BLOCK_SIZE - bl.length());
4034   z.zero();
4035   bl.append(std::move(z));
4036
4037   int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_WRONLY));
4038   if (fd < 0) {
4039     fd = -errno;
4040     derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd)
4041          << dendl;
4042     return fd;
4043   }
4044   int r = bl.write_fd(fd);
4045   if (r < 0) {
4046     derr << __func__ << " failed to write to " << path
4047          << ": " << cpp_strerror(r) << dendl;
4048   }
4049   r = ::fsync(fd);
4050   if (r < 0) {
4051     derr << __func__ << " failed to fsync " << path
4052          << ": " << cpp_strerror(r) << dendl;
4053   }
4054   VOID_TEMP_FAILURE_RETRY(::close(fd));
4055   return r;
4056 }
4057
4058 int BlueStore::_read_bdev_label(CephContext* cct, string path,
4059                                 bluestore_bdev_label_t *label)
4060 {
4061   dout(10) << __func__ << dendl;
4062   int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY));
4063   if (fd < 0) {
4064     fd = -errno;
4065     derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd)
4066          << dendl;
4067     return fd;
4068   }
4069   bufferlist bl;
4070   int r = bl.read_fd(fd, BDEV_LABEL_BLOCK_SIZE);
4071   VOID_TEMP_FAILURE_RETRY(::close(fd));
4072   if (r < 0) {
4073     derr << __func__ << " failed to read from " << path
4074          << ": " << cpp_strerror(r) << dendl;
4075     return r;
4076   }
4077
4078   uint32_t crc, expected_crc;
4079   bufferlist::iterator p = bl.begin();
4080   try {
4081     ::decode(*label, p);
4082     bufferlist t;
4083     t.substr_of(bl, 0, p.get_off());
4084     crc = t.crc32c(-1);
4085     ::decode(expected_crc, p);
4086   }
4087   catch (buffer::error& e) {
4088     derr << __func__ << " unable to decode label at offset " << p.get_off()
4089          << ": " << e.what()
4090          << dendl;
4091     return -EINVAL;
4092   }
4093   if (crc != expected_crc) {
4094     derr << __func__ << " bad crc on label, expected " << expected_crc
4095          << " != actual " << crc << dendl;
4096     return -EIO;
4097   }
4098   dout(10) << __func__ << " got " << *label << dendl;
4099   return 0;
4100 }
4101
4102 int BlueStore::_check_or_set_bdev_label(
4103   string path, uint64_t size, string desc, bool create)
4104 {
4105   bluestore_bdev_label_t label;
4106   if (create) {
4107     label.osd_uuid = fsid;
4108     label.size = size;
4109     label.btime = ceph_clock_now();
4110     label.description = desc;
4111     int r = _write_bdev_label(cct, path, label);
4112     if (r < 0)
4113       return r;
4114   } else {
4115     int r = _read_bdev_label(cct, path, &label);
4116     if (r < 0)
4117       return r;
4118     if (cct->_conf->bluestore_debug_permit_any_bdev_label) {
4119       dout(20) << __func__ << " bdev " << path << " fsid " << label.osd_uuid
4120            << " and fsid " << fsid << " check bypassed" << dendl;
4121     }
4122     else if (label.osd_uuid != fsid) {
4123       derr << __func__ << " bdev " << path << " fsid " << label.osd_uuid
4124            << " does not match our fsid " << fsid << dendl;
4125       return -EIO;
4126     }
4127   }
4128   return 0;
4129 }
4130
4131 void BlueStore::_set_alloc_sizes(void)
4132 {
4133   max_alloc_size = cct->_conf->bluestore_max_alloc_size;
4134
4135   if (cct->_conf->bluestore_prefer_deferred_size) {
4136     prefer_deferred_size = cct->_conf->bluestore_prefer_deferred_size;
4137   } else {
4138     assert(bdev);
4139     if (bdev->is_rotational()) {
4140       prefer_deferred_size = cct->_conf->bluestore_prefer_deferred_size_hdd;
4141     } else {
4142       prefer_deferred_size = cct->_conf->bluestore_prefer_deferred_size_ssd;
4143     }
4144   }
4145
4146   if (cct->_conf->bluestore_deferred_batch_ops) {
4147     deferred_batch_ops = cct->_conf->bluestore_deferred_batch_ops;
4148   } else {
4149     assert(bdev);
4150     if (bdev->is_rotational()) {
4151       deferred_batch_ops = cct->_conf->bluestore_deferred_batch_ops_hdd;
4152     } else {
4153       deferred_batch_ops = cct->_conf->bluestore_deferred_batch_ops_ssd;
4154     }
4155   }
4156
4157   dout(10) << __func__ << " min_alloc_size 0x" << std::hex << min_alloc_size
4158            << std::dec << " order " << min_alloc_size_order
4159            << " max_alloc_size 0x" << std::hex << max_alloc_size
4160            << " prefer_deferred_size 0x" << prefer_deferred_size
4161            << std::dec
4162            << " deferred_batch_ops " << deferred_batch_ops
4163            << dendl;
4164 }
4165
4166 int BlueStore::_open_bdev(bool create)
4167 {
4168   assert(bdev == NULL);
4169   string p = path + "/block";
4170   bdev = BlockDevice::create(cct, p, aio_cb, static_cast<void*>(this));
4171   int r = bdev->open(p);
4172   if (r < 0)
4173     goto fail;
4174
4175   if (bdev->supported_bdev_label()) {
4176     r = _check_or_set_bdev_label(p, bdev->get_size(), "main", create);
4177     if (r < 0)
4178       goto fail_close;
4179   }
4180
4181   // initialize global block parameters
4182   block_size = bdev->get_block_size();
4183   block_mask = ~(block_size - 1);
4184   block_size_order = ctz(block_size);
4185   assert(block_size == 1u << block_size_order);
4186   // and set cache_size based on device type
4187   r = _set_cache_sizes();
4188   if (r < 0) {
4189     goto fail_close;
4190   }
4191   return 0;
4192
4193  fail_close:
4194   bdev->close();
4195  fail:
4196   delete bdev;
4197   bdev = NULL;
4198   return r;
4199 }
4200
4201 void BlueStore::_close_bdev()
4202 {
4203   assert(bdev);
4204   bdev->close();
4205   delete bdev;
4206   bdev = NULL;
4207 }
4208
4209 int BlueStore::_open_fm(bool create)
4210 {
4211   assert(fm == NULL);
4212   fm = FreelistManager::create(cct, freelist_type, db, PREFIX_ALLOC);
4213
4214   if (create) {
4215     // initialize freespace
4216     dout(20) << __func__ << " initializing freespace" << dendl;
4217     KeyValueDB::Transaction t = db->get_transaction();
4218     {
4219       bufferlist bl;
4220       bl.append(freelist_type);
4221       t->set(PREFIX_SUPER, "freelist_type", bl);
4222     }
4223     fm->create(bdev->get_size(), min_alloc_size, t);
4224
4225     // allocate superblock reserved space.  note that we do not mark
4226     // bluefs space as allocated in the freelist; we instead rely on
4227     // bluefs_extents.
4228     uint64_t reserved = ROUND_UP_TO(MAX(SUPER_RESERVED, min_alloc_size),
4229                                     min_alloc_size);
4230     fm->allocate(0, reserved, t);
4231
4232     if (cct->_conf->bluestore_bluefs) {
4233       assert(bluefs_extents.num_intervals() == 1);
4234       interval_set<uint64_t>::iterator p = bluefs_extents.begin();
4235       reserved = ROUND_UP_TO(p.get_start() + p.get_len(), min_alloc_size);
4236       dout(20) << __func__ << " reserved 0x" << std::hex << reserved << std::dec
4237                << " for bluefs" << dendl;
4238       bufferlist bl;
4239       ::encode(bluefs_extents, bl);
4240       t->set(PREFIX_SUPER, "bluefs_extents", bl);
4241       dout(20) << __func__ << " bluefs_extents 0x" << std::hex << bluefs_extents
4242                << std::dec << dendl;
4243     }
4244
4245     if (cct->_conf->bluestore_debug_prefill > 0) {
4246       uint64_t end = bdev->get_size() - reserved;
4247       dout(1) << __func__ << " pre-fragmenting freespace, using "
4248               << cct->_conf->bluestore_debug_prefill << " with max free extent "
4249               << cct->_conf->bluestore_debug_prefragment_max << dendl;
4250       uint64_t start = P2ROUNDUP(reserved, min_alloc_size);
4251       uint64_t max_b = cct->_conf->bluestore_debug_prefragment_max / min_alloc_size;
4252       float r = cct->_conf->bluestore_debug_prefill;
4253       r /= 1.0 - r;
4254       bool stop = false;
4255
4256       while (!stop && start < end) {
4257         uint64_t l = (rand() % max_b + 1) * min_alloc_size;
4258         if (start + l > end) {
4259           l = end - start;
4260           l = P2ALIGN(l, min_alloc_size);
4261         }
4262         assert(start + l <= end);
4263
4264         uint64_t u = 1 + (uint64_t)(r * (double)l);
4265         u = P2ROUNDUP(u, min_alloc_size);
4266         if (start + l + u > end) {
4267           u = end - (start + l);
4268           // trim to align so we don't overflow again
4269           u = P2ALIGN(u, min_alloc_size);
4270           stop = true;
4271         }
4272         assert(start + l + u <= end);
4273
4274         dout(20) << "  free 0x" << std::hex << start << "~" << l
4275                  << " use 0x" << u << std::dec << dendl;
4276
4277         if (u == 0) {
4278           // break if u has been trimmed to nothing
4279           break;
4280         }
4281
4282         fm->allocate(start + l, u, t);
4283         start += l + u;
4284       }
4285     }
4286     db->submit_transaction_sync(t);
4287   }
4288
4289   int r = fm->init(bdev->get_size());
4290   if (r < 0) {
4291     derr << __func__ << " freelist init failed: " << cpp_strerror(r) << dendl;
4292     delete fm;
4293     fm = NULL;
4294     return r;
4295   }
4296   return 0;
4297 }
4298
4299 void BlueStore::_close_fm()
4300 {
4301   dout(10) << __func__ << dendl;
4302   assert(fm);
4303   fm->shutdown();
4304   delete fm;
4305   fm = NULL;
4306 }
4307
4308 int BlueStore::_open_alloc()
4309 {
4310   assert(alloc == NULL);
4311   assert(bdev->get_size());
4312   alloc = Allocator::create(cct, cct->_conf->bluestore_allocator,
4313                             bdev->get_size(),
4314                             min_alloc_size);
4315   if (!alloc) {
4316     lderr(cct) << __func__ << " Allocator::unknown alloc type "
4317                << cct->_conf->bluestore_allocator
4318                << dendl;
4319     return -EINVAL;
4320   }
4321
4322   uint64_t num = 0, bytes = 0;
4323
4324   dout(1) << __func__ << " opening allocation metadata" << dendl;
4325   // initialize from freelist
4326   fm->enumerate_reset();
4327   uint64_t offset, length;
4328   while (fm->enumerate_next(&offset, &length)) {
4329     alloc->init_add_free(offset, length);
4330     ++num;
4331     bytes += length;
4332   }
4333   fm->enumerate_reset();
4334   dout(1) << __func__ << " loaded " << pretty_si_t(bytes)
4335           << " in " << num << " extents"
4336           << dendl;
4337
4338   // also mark bluefs space as allocated
4339   for (auto e = bluefs_extents.begin(); e != bluefs_extents.end(); ++e) {
4340     alloc->init_rm_free(e.get_start(), e.get_len());
4341   }
4342   dout(10) << __func__ << " marked bluefs_extents 0x" << std::hex
4343            << bluefs_extents << std::dec << " as allocated" << dendl;
4344
4345   return 0;
4346 }
4347
4348 void BlueStore::_close_alloc()
4349 {
4350   assert(alloc);
4351   alloc->shutdown();
4352   delete alloc;
4353   alloc = NULL;
4354 }
4355
4356 int BlueStore::_open_fsid(bool create)
4357 {
4358   assert(fsid_fd < 0);
4359   int flags = O_RDWR;
4360   if (create)
4361     flags |= O_CREAT;
4362   fsid_fd = ::openat(path_fd, "fsid", flags, 0644);
4363   if (fsid_fd < 0) {
4364     int err = -errno;
4365     derr << __func__ << " " << cpp_strerror(err) << dendl;
4366     return err;
4367   }
4368   return 0;
4369 }
4370
4371 int BlueStore::_read_fsid(uuid_d *uuid)
4372 {
4373   char fsid_str[40];
4374   memset(fsid_str, 0, sizeof(fsid_str));
4375   int ret = safe_read(fsid_fd, fsid_str, sizeof(fsid_str));
4376   if (ret < 0) {
4377     derr << __func__ << " failed: " << cpp_strerror(ret) << dendl;
4378     return ret;
4379   }
4380   if (ret > 36)
4381     fsid_str[36] = 0;
4382   else
4383     fsid_str[ret] = 0;
4384   if (!uuid->parse(fsid_str)) {
4385     derr << __func__ << " unparsable uuid " << fsid_str << dendl;
4386     return -EINVAL;
4387   }
4388   return 0;
4389 }
4390
4391 int BlueStore::_write_fsid()
4392 {
4393   int r = ::ftruncate(fsid_fd, 0);
4394   if (r < 0) {
4395     r = -errno;
4396     derr << __func__ << " fsid truncate failed: " << cpp_strerror(r) << dendl;
4397     return r;
4398   }
4399   string str = stringify(fsid) + "\n";
4400   r = safe_write(fsid_fd, str.c_str(), str.length());
4401   if (r < 0) {
4402     derr << __func__ << " fsid write failed: " << cpp_strerror(r) << dendl;
4403     return r;
4404   }
4405   r = ::fsync(fsid_fd);
4406   if (r < 0) {
4407     r = -errno;
4408     derr << __func__ << " fsid fsync failed: " << cpp_strerror(r) << dendl;
4409     return r;
4410   }
4411   return 0;
4412 }
4413
4414 void BlueStore::_close_fsid()
4415 {
4416   VOID_TEMP_FAILURE_RETRY(::close(fsid_fd));
4417   fsid_fd = -1;
4418 }
4419
4420 int BlueStore::_lock_fsid()
4421 {
4422   struct flock l;
4423   memset(&l, 0, sizeof(l));
4424   l.l_type = F_WRLCK;
4425   l.l_whence = SEEK_SET;
4426   int r = ::fcntl(fsid_fd, F_SETLK, &l);
4427   if (r < 0) {
4428     int err = errno;
4429     derr << __func__ << " failed to lock " << path << "/fsid"
4430          << " (is another ceph-osd still running?)"
4431          << cpp_strerror(err) << dendl;
4432     return -err;
4433   }
4434   return 0;
4435 }
4436
4437 bool BlueStore::is_rotational()
4438 {
4439   if (bdev) {
4440     return bdev->is_rotational();
4441   }
4442
4443   bool rotational = true;
4444   int r = _open_path();
4445   if (r < 0)
4446     goto out;
4447   r = _open_fsid(false);
4448   if (r < 0)
4449     goto out_path;
4450   r = _read_fsid(&fsid);
4451   if (r < 0)
4452     goto out_fsid;
4453   r = _lock_fsid();
4454   if (r < 0)
4455     goto out_fsid;
4456   r = _open_bdev(false);
4457   if (r < 0)
4458     goto out_fsid;
4459   rotational = bdev->is_rotational();
4460   _close_bdev();
4461  out_fsid:
4462   _close_fsid();
4463  out_path:
4464   _close_path();
4465   out:
4466   return rotational;
4467 }
4468
4469 bool BlueStore::is_journal_rotational()
4470 {
4471   if (!bluefs) {
4472     dout(5) << __func__ << " bluefs disabled, default to store media type"
4473             << dendl;
4474     return is_rotational();
4475   }
4476   dout(10) << __func__ << " " << (int)bluefs->wal_is_rotational() << dendl;
4477   return bluefs->wal_is_rotational();
4478 }
4479
4480 bool BlueStore::test_mount_in_use()
4481 {
4482   // most error conditions mean the mount is not in use (e.g., because
4483   // it doesn't exist).  only if we fail to lock do we conclude it is
4484   // in use.
4485   bool ret = false;
4486   int r = _open_path();
4487   if (r < 0)
4488     return false;
4489   r = _open_fsid(false);
4490   if (r < 0)
4491     goto out_path;
4492   r = _lock_fsid();
4493   if (r < 0)
4494     ret = true; // if we can't lock, it is in use
4495   _close_fsid();
4496  out_path:
4497   _close_path();
4498   return ret;
4499 }
4500
4501 int BlueStore::_open_db(bool create)
4502 {
4503   int r;
4504   assert(!db);
4505   string fn = path + "/db";
4506   string options;
4507   stringstream err;
4508   ceph::shared_ptr<Int64ArrayMergeOperator> merge_op(new Int64ArrayMergeOperator);
4509
4510   string kv_backend;
4511   if (create) {
4512     kv_backend = cct->_conf->bluestore_kvbackend;
4513   } else {
4514     r = read_meta("kv_backend", &kv_backend);
4515     if (r < 0) {
4516       derr << __func__ << " unable to read 'kv_backend' meta" << dendl;
4517       return -EIO;
4518     }
4519   }
4520   dout(10) << __func__ << " kv_backend = " << kv_backend << dendl;
4521
4522   bool do_bluefs;
4523   if (create) {
4524     do_bluefs = cct->_conf->bluestore_bluefs;
4525   } else {
4526     string s;
4527     r = read_meta("bluefs", &s);
4528     if (r < 0) {
4529       derr << __func__ << " unable to read 'bluefs' meta" << dendl;
4530       return -EIO;
4531     }
4532     if (s == "1") {
4533       do_bluefs = true;
4534     } else if (s == "0") {
4535       do_bluefs = false;
4536     } else {
4537       derr << __func__ << " bluefs = " << s << " : not 0 or 1, aborting"
4538            << dendl;
4539       return -EIO;
4540     }
4541   }
4542   dout(10) << __func__ << " do_bluefs = " << do_bluefs << dendl;
4543
4544   rocksdb::Env *env = NULL;
4545   if (do_bluefs) {
4546     dout(10) << __func__ << " initializing bluefs" << dendl;
4547     if (kv_backend != "rocksdb") {
4548       derr << " backend must be rocksdb to use bluefs" << dendl;
4549       return -EINVAL;
4550     }
4551     bluefs = new BlueFS(cct);
4552
4553     string bfn;
4554     struct stat st;
4555
4556     if (read_meta("path_block.db", &bfn) < 0) {
4557       bfn = path + "/block.db";
4558     }
4559     if (::stat(bfn.c_str(), &st) == 0) {
4560       r = bluefs->add_block_device(BlueFS::BDEV_DB, bfn);
4561       if (r < 0) {
4562         derr << __func__ << " add block device(" << bfn << ") returned: " 
4563              << cpp_strerror(r) << dendl;
4564         goto free_bluefs;
4565       }
4566
4567       if (bluefs->bdev_support_label(BlueFS::BDEV_DB)) {
4568         r = _check_or_set_bdev_label(
4569           bfn,
4570           bluefs->get_block_device_size(BlueFS::BDEV_DB),
4571           "bluefs db", create);
4572         if (r < 0) {
4573           derr << __func__
4574                << " check block device(" << bfn << ") label returned: "
4575                << cpp_strerror(r) << dendl;
4576           goto free_bluefs;
4577         }
4578       }
4579       if (create) {
4580         bluefs->add_block_extent(
4581           BlueFS::BDEV_DB,
4582           SUPER_RESERVED,
4583           bluefs->get_block_device_size(BlueFS::BDEV_DB) - SUPER_RESERVED);
4584       }
4585       bluefs_shared_bdev = BlueFS::BDEV_SLOW;
4586       bluefs_single_shared_device = false;
4587     } else if (::lstat(bfn.c_str(), &st) == -1) {
4588       bluefs_shared_bdev = BlueFS::BDEV_DB;
4589     } else {
4590       //symlink exist is bug
4591       derr << __func__ << " " << bfn << " link target doesn't exist" << dendl;
4592       r = -errno;
4593       goto free_bluefs;
4594     }
4595
4596     // shared device
4597     if (read_meta("path_block", &bfn) < 0) {
4598       bfn = path + "/block";
4599     }
4600     r = bluefs->add_block_device(bluefs_shared_bdev, bfn);
4601     if (r < 0) {
4602       derr << __func__ << " add block device(" << bfn << ") returned: " 
4603            << cpp_strerror(r) << dendl;
4604       goto free_bluefs;
4605     }
4606     if (create) {
4607       // note: we always leave the first SUPER_RESERVED (8k) of the device unused
4608       uint64_t initial =
4609         bdev->get_size() * (cct->_conf->bluestore_bluefs_min_ratio +
4610                             cct->_conf->bluestore_bluefs_gift_ratio);
4611       initial = MAX(initial, cct->_conf->bluestore_bluefs_min);
4612       if (cct->_conf->bluefs_alloc_size % min_alloc_size) {
4613         derr << __func__ << " bluefs_alloc_size 0x" << std::hex
4614              << cct->_conf->bluefs_alloc_size << " is not a multiple of "
4615              << "min_alloc_size 0x" << min_alloc_size << std::dec << dendl;
4616         r = -EINVAL;
4617         goto free_bluefs;
4618       }
4619       // align to bluefs's alloc_size
4620       initial = P2ROUNDUP(initial, cct->_conf->bluefs_alloc_size);
4621       // put bluefs in the middle of the device in case it is an HDD
4622       uint64_t start = P2ALIGN((bdev->get_size() - initial) / 2,
4623                                cct->_conf->bluefs_alloc_size);
4624       bluefs->add_block_extent(bluefs_shared_bdev, start, initial);
4625       bluefs_extents.insert(start, initial);
4626     }
4627
4628     if (read_meta("path_block.wal", &bfn) < 0) {
4629       bfn = path + "/block.wal";
4630     }
4631     if (::stat(bfn.c_str(), &st) == 0) {
4632       r = bluefs->add_block_device(BlueFS::BDEV_WAL, bfn);
4633       if (r < 0) {
4634         derr << __func__ << " add block device(" << bfn << ") returned: " 
4635              << cpp_strerror(r) << dendl;
4636         goto free_bluefs;                       
4637       }
4638
4639       if (bluefs->bdev_support_label(BlueFS::BDEV_WAL)) {
4640         r = _check_or_set_bdev_label(
4641           bfn,
4642           bluefs->get_block_device_size(BlueFS::BDEV_WAL),
4643           "bluefs wal", create);
4644         if (r < 0) {
4645           derr << __func__ << " check block device(" << bfn
4646                << ") label returned: " << cpp_strerror(r) << dendl;
4647           goto free_bluefs;
4648         }
4649       }
4650
4651       if (create) {
4652         bluefs->add_block_extent(
4653           BlueFS::BDEV_WAL, BDEV_LABEL_BLOCK_SIZE,
4654           bluefs->get_block_device_size(BlueFS::BDEV_WAL) -
4655            BDEV_LABEL_BLOCK_SIZE);
4656       }
4657       cct->_conf->set_val("rocksdb_separate_wal_dir", "true");
4658       bluefs_single_shared_device = false;
4659     } else if (::lstat(bfn.c_str(), &st) == -1) {
4660       cct->_conf->set_val("rocksdb_separate_wal_dir", "false");
4661     } else {
4662       //symlink exist is bug
4663       derr << __func__ << " " << bfn << " link target doesn't exist" << dendl;
4664       r = -errno;
4665       goto free_bluefs;
4666     }
4667
4668     if (create) {
4669       bluefs->mkfs(fsid);
4670     }
4671     r = bluefs->mount();
4672     if (r < 0) {
4673       derr << __func__ << " failed bluefs mount: " << cpp_strerror(r) << dendl;
4674       goto free_bluefs;
4675     }
4676     if (cct->_conf->bluestore_bluefs_env_mirror) {
4677       rocksdb::Env *a = new BlueRocksEnv(bluefs);
4678       rocksdb::Env *b = rocksdb::Env::Default();
4679       if (create) {
4680         string cmd = "rm -rf " + path + "/db " +
4681           path + "/db.slow " +
4682           path + "/db.wal";
4683         int r = system(cmd.c_str());
4684         (void)r;
4685       }
4686       env = new rocksdb::EnvMirror(b, a, false, true);
4687     } else {
4688       env = new BlueRocksEnv(bluefs);
4689
4690       // simplify the dir names, too, as "seen" by rocksdb
4691       fn = "db";
4692     }
4693
4694     if (bluefs_shared_bdev == BlueFS::BDEV_SLOW) {
4695       // we have both block.db and block; tell rocksdb!
4696       // note: the second (last) size value doesn't really matter
4697       ostringstream db_paths;
4698       uint64_t db_size = bluefs->get_block_device_size(BlueFS::BDEV_DB);
4699       uint64_t slow_size = bluefs->get_block_device_size(BlueFS::BDEV_SLOW);
4700       db_paths << fn << ","
4701                << (uint64_t)(db_size * 95 / 100) << " "
4702                << fn + ".slow" << ","
4703                << (uint64_t)(slow_size * 95 / 100);
4704       cct->_conf->set_val("rocksdb_db_paths", db_paths.str(), false);
4705       dout(10) << __func__ << " set rocksdb_db_paths to "
4706                << cct->_conf->get_val<std::string>("rocksdb_db_paths") << dendl;
4707     }
4708
4709     if (create) {
4710       env->CreateDir(fn);
4711       if (cct->_conf->rocksdb_separate_wal_dir)
4712         env->CreateDir(fn + ".wal");
4713       if (cct->_conf->get_val<std::string>("rocksdb_db_paths").length())
4714         env->CreateDir(fn + ".slow");
4715     }
4716   } else if (create) {
4717     int r = ::mkdir(fn.c_str(), 0755);
4718     if (r < 0)
4719       r = -errno;
4720     if (r < 0 && r != -EEXIST) {
4721       derr << __func__ << " failed to create " << fn << ": " << cpp_strerror(r)
4722            << dendl;
4723       return r;
4724     }
4725
4726     // wal_dir, too!
4727     if (cct->_conf->rocksdb_separate_wal_dir) {
4728       string walfn = path + "/db.wal";
4729       r = ::mkdir(walfn.c_str(), 0755);
4730       if (r < 0)
4731         r = -errno;
4732       if (r < 0 && r != -EEXIST) {
4733         derr << __func__ << " failed to create " << walfn
4734           << ": " << cpp_strerror(r)
4735           << dendl;
4736         return r;
4737       }
4738     }
4739   }
4740
4741   db = KeyValueDB::create(cct,
4742                           kv_backend,
4743                           fn,
4744                           static_cast<void*>(env));
4745   if (!db) {
4746     derr << __func__ << " error creating db" << dendl;
4747     if (bluefs) {
4748       bluefs->umount();
4749       delete bluefs;
4750       bluefs = NULL;
4751     }
4752     // delete env manually here since we can't depend on db to do this
4753     // under this case
4754     delete env;
4755     env = NULL;
4756     return -EIO;
4757   }
4758
4759   FreelistManager::setup_merge_operators(db);
4760   db->set_merge_operator(PREFIX_STAT, merge_op);
4761
4762   db->set_cache_size(cache_size * cache_kv_ratio);
4763
4764   if (kv_backend == "rocksdb")
4765     options = cct->_conf->bluestore_rocksdb_options;
4766   db->init(options);
4767   if (create)
4768     r = db->create_and_open(err);
4769   else
4770     r = db->open(err);
4771   if (r) {
4772     derr << __func__ << " erroring opening db: " << err.str() << dendl;
4773     if (bluefs) {
4774       bluefs->umount();
4775       delete bluefs;
4776       bluefs = NULL;
4777     }
4778     delete db;
4779     db = NULL;
4780     return -EIO;
4781   }
4782   dout(1) << __func__ << " opened " << kv_backend
4783           << " path " << fn << " options " << options << dendl;
4784   return 0;
4785
4786 free_bluefs:
4787   assert(bluefs);
4788   delete bluefs;
4789   bluefs = NULL;
4790   return r;
4791 }
4792
4793 void BlueStore::_close_db()
4794 {
4795   assert(db);
4796   delete db;
4797   db = NULL;
4798   if (bluefs) {
4799     bluefs->umount();
4800     delete bluefs;
4801     bluefs = NULL;
4802   }
4803 }
4804
4805 int BlueStore::_reconcile_bluefs_freespace()
4806 {
4807   dout(10) << __func__ << dendl;
4808   interval_set<uint64_t> bset;
4809   int r = bluefs->get_block_extents(bluefs_shared_bdev, &bset);
4810   assert(r == 0);
4811   if (bset == bluefs_extents) {
4812     dout(10) << __func__ << " we agree bluefs has 0x" << std::hex << bset
4813              << std::dec << dendl;
4814     return 0;
4815   }
4816   dout(10) << __func__ << " bluefs says 0x" << std::hex << bset << std::dec
4817            << dendl;
4818   dout(10) << __func__ << " super says  0x" << std::hex << bluefs_extents
4819            << std::dec << dendl;
4820
4821   interval_set<uint64_t> overlap;
4822   overlap.intersection_of(bset, bluefs_extents);
4823
4824   bset.subtract(overlap);
4825   if (!bset.empty()) {
4826     derr << __func__ << " bluefs extra 0x" << std::hex << bset << std::dec
4827          << dendl;
4828     return -EIO;
4829   }
4830
4831   interval_set<uint64_t> super_extra;
4832   super_extra = bluefs_extents;
4833   super_extra.subtract(overlap);
4834   if (!super_extra.empty()) {
4835     // This is normal: it can happen if we commit to give extents to
4836     // bluefs and we crash before bluefs commits that it owns them.
4837     dout(10) << __func__ << " super extra " << super_extra << dendl;
4838     for (interval_set<uint64_t>::iterator p = super_extra.begin();
4839          p != super_extra.end();
4840          ++p) {
4841       bluefs->add_block_extent(bluefs_shared_bdev, p.get_start(), p.get_len());
4842     }
4843   }
4844
4845   return 0;
4846 }
4847
4848 int BlueStore::_balance_bluefs_freespace(PExtentVector *extents)
4849 {
4850   int ret = 0;
4851   assert(bluefs);
4852
4853   vector<pair<uint64_t,uint64_t>> bluefs_usage;  // <free, total> ...
4854   bluefs->get_usage(&bluefs_usage);
4855   assert(bluefs_usage.size() > bluefs_shared_bdev);
4856
4857   // fixme: look at primary bdev only for now
4858   uint64_t bluefs_free = bluefs_usage[bluefs_shared_bdev].first;
4859   uint64_t bluefs_total = bluefs_usage[bluefs_shared_bdev].second;
4860   float bluefs_free_ratio = (float)bluefs_free / (float)bluefs_total;
4861
4862   uint64_t my_free = alloc->get_free();
4863   uint64_t total = bdev->get_size();
4864   float my_free_ratio = (float)my_free / (float)total;
4865
4866   uint64_t total_free = bluefs_free + my_free;
4867
4868   float bluefs_ratio = (float)bluefs_free / (float)total_free;
4869
4870   dout(10) << __func__
4871            << " bluefs " << pretty_si_t(bluefs_free)
4872            << " free (" << bluefs_free_ratio
4873            << ") bluestore " << pretty_si_t(my_free)
4874            << " free (" << my_free_ratio
4875            << "), bluefs_ratio " << bluefs_ratio
4876            << dendl;
4877
4878   uint64_t gift = 0;
4879   uint64_t reclaim = 0;
4880   if (bluefs_ratio < cct->_conf->bluestore_bluefs_min_ratio) {
4881     gift = cct->_conf->bluestore_bluefs_gift_ratio * total_free;
4882     dout(10) << __func__ << " bluefs_ratio " << bluefs_ratio
4883              << " < min_ratio " << cct->_conf->bluestore_bluefs_min_ratio
4884              << ", should gift " << pretty_si_t(gift) << dendl;
4885   } else if (bluefs_ratio > cct->_conf->bluestore_bluefs_max_ratio) {
4886     reclaim = cct->_conf->bluestore_bluefs_reclaim_ratio * total_free;
4887     if (bluefs_total - reclaim < cct->_conf->bluestore_bluefs_min)
4888       reclaim = bluefs_total - cct->_conf->bluestore_bluefs_min;
4889     dout(10) << __func__ << " bluefs_ratio " << bluefs_ratio
4890              << " > max_ratio " << cct->_conf->bluestore_bluefs_max_ratio
4891              << ", should reclaim " << pretty_si_t(reclaim) << dendl;
4892   }
4893
4894   // don't take over too much of the freespace
4895   uint64_t free_cap = cct->_conf->bluestore_bluefs_max_ratio * total_free;
4896   if (bluefs_total < cct->_conf->bluestore_bluefs_min &&
4897       cct->_conf->bluestore_bluefs_min < free_cap) {
4898     uint64_t g = cct->_conf->bluestore_bluefs_min - bluefs_total;
4899     dout(10) << __func__ << " bluefs_total " << bluefs_total
4900              << " < min " << cct->_conf->bluestore_bluefs_min
4901              << ", should gift " << pretty_si_t(g) << dendl;
4902     if (g > gift)
4903       gift = g;
4904     reclaim = 0;
4905   }
4906   uint64_t min_free = cct->_conf->get_val<uint64_t>("bluestore_bluefs_min_free");
4907   if (bluefs_free < min_free &&
4908       min_free < free_cap) {
4909     uint64_t g = min_free - bluefs_free;
4910     dout(10) << __func__ << " bluefs_free " << bluefs_total
4911              << " < min " << min_free
4912              << ", should gift " << pretty_si_t(g) << dendl;
4913     if (g > gift)
4914       gift = g;
4915     reclaim = 0;
4916   }
4917
4918   if (gift) {
4919     // round up to alloc size
4920     gift = P2ROUNDUP(gift, cct->_conf->bluefs_alloc_size);
4921
4922     // hard cap to fit into 32 bits
4923     gift = MIN(gift, 1ull<<31);
4924     dout(10) << __func__ << " gifting " << gift
4925              << " (" << pretty_si_t(gift) << ")" << dendl;
4926
4927     // fixme: just do one allocation to start...
4928     int r = alloc->reserve(gift);
4929     assert(r == 0);
4930
4931     AllocExtentVector exts;
4932     int64_t alloc_len = alloc->allocate(gift, cct->_conf->bluefs_alloc_size,
4933                                         0, 0, &exts);
4934
4935     if (alloc_len < (int64_t)gift) {
4936       derr << __func__ << " allocate failed on 0x" << std::hex << gift
4937            << " min_alloc_size 0x" << min_alloc_size << std::dec << dendl;
4938       alloc->dump();
4939       assert(0 == "allocate failed, wtf");
4940       return -ENOSPC;
4941     }
4942     for (auto& p : exts) {
4943       bluestore_pextent_t e = bluestore_pextent_t(p);
4944       dout(1) << __func__ << " gifting " << e << " to bluefs" << dendl;
4945       extents->push_back(e);
4946     }
4947     gift = 0;
4948
4949     ret = 1;
4950   }
4951
4952   // reclaim from bluefs?
4953   if (reclaim) {
4954     // round up to alloc size
4955     reclaim = P2ROUNDUP(reclaim, cct->_conf->bluefs_alloc_size);
4956
4957     // hard cap to fit into 32 bits
4958     reclaim = MIN(reclaim, 1ull<<31);
4959     dout(10) << __func__ << " reclaiming " << reclaim
4960              << " (" << pretty_si_t(reclaim) << ")" << dendl;
4961
4962     while (reclaim > 0) {
4963       // NOTE: this will block and do IO.
4964       AllocExtentVector extents;
4965       int r = bluefs->reclaim_blocks(bluefs_shared_bdev, reclaim,
4966                                      &extents);
4967       if (r < 0) {
4968         derr << __func__ << " failed to reclaim space from bluefs"
4969              << dendl;
4970         break;
4971       }
4972       for (auto e : extents) {
4973         bluefs_extents.erase(e.offset, e.length);
4974         bluefs_extents_reclaiming.insert(e.offset, e.length);
4975         reclaim -= e.length;
4976       }
4977     }
4978
4979     ret = 1;
4980   }
4981
4982   return ret;
4983 }
4984
4985 void BlueStore::_commit_bluefs_freespace(
4986   const PExtentVector& bluefs_gift_extents)
4987 {
4988   dout(10) << __func__ << dendl;
4989   for (auto& p : bluefs_gift_extents) {
4990     bluefs->add_block_extent(bluefs_shared_bdev, p.offset, p.length);
4991   }
4992 }
4993
4994 int BlueStore::_open_collections(int *errors)
4995 {
4996   assert(coll_map.empty());
4997   KeyValueDB::Iterator it = db->get_iterator(PREFIX_COLL);
4998   for (it->upper_bound(string());
4999        it->valid();
5000        it->next()) {
5001     coll_t cid;
5002     if (cid.parse(it->key())) {
5003       CollectionRef c(
5004         new Collection(
5005           this,
5006           cache_shards[cid.hash_to_shard(cache_shards.size())],
5007           cid));
5008       bufferlist bl = it->value();
5009       bufferlist::iterator p = bl.begin();
5010       try {
5011         ::decode(c->cnode, p);
5012       } catch (buffer::error& e) {
5013         derr << __func__ << " failed to decode cnode, key:"
5014              << pretty_binary_string(it->key()) << dendl;
5015         return -EIO;
5016       }   
5017       dout(20) << __func__ << " opened " << cid << " " << c << dendl;
5018       coll_map[cid] = c;
5019     } else {
5020       derr << __func__ << " unrecognized collection " << it->key() << dendl;
5021       if (errors)
5022         (*errors)++;
5023     }
5024   }
5025   return 0;
5026 }
5027
5028 void BlueStore::_open_statfs()
5029 {
5030   bufferlist bl;
5031   int r = db->get(PREFIX_STAT, "bluestore_statfs", &bl);
5032   if (r >= 0) {
5033     if (size_t(bl.length()) >= sizeof(vstatfs.values)) {
5034       auto it = bl.begin();
5035       vstatfs.decode(it);
5036     } else {
5037       dout(10) << __func__ << " store_statfs is corrupt, using empty" << dendl;
5038     }
5039   }
5040   else {
5041     dout(10) << __func__ << " store_statfs missed, using empty" << dendl;
5042   }
5043 }
5044
5045 int BlueStore::_setup_block_symlink_or_file(
5046   string name,
5047   string epath,
5048   uint64_t size,
5049   bool create)
5050 {
5051   dout(20) << __func__ << " name " << name << " path " << epath
5052            << " size " << size << " create=" << (int)create << dendl;
5053   int r = 0;
5054   int flags = O_RDWR;
5055   if (create)
5056     flags |= O_CREAT;
5057   if (epath.length()) {
5058     r = ::symlinkat(epath.c_str(), path_fd, name.c_str());
5059     if (r < 0) {
5060       r = -errno;
5061       derr << __func__ << " failed to create " << name << " symlink to "
5062            << epath << ": " << cpp_strerror(r) << dendl;
5063       return r;
5064     }
5065
5066     if (!epath.compare(0, strlen(SPDK_PREFIX), SPDK_PREFIX)) {
5067       int fd = ::openat(path_fd, epath.c_str(), flags, 0644);
5068       if (fd < 0) {
5069         r = -errno;
5070         derr << __func__ << " failed to open " << epath << " file: "
5071              << cpp_strerror(r) << dendl;
5072         return r;
5073       }
5074       string serial_number = epath.substr(strlen(SPDK_PREFIX));
5075       r = ::write(fd, serial_number.c_str(), serial_number.size());
5076       assert(r == (int)serial_number.size());
5077       dout(1) << __func__ << " created " << name << " symlink to "
5078               << epath << dendl;
5079       VOID_TEMP_FAILURE_RETRY(::close(fd));
5080     }
5081   }
5082   if (size) {
5083     int fd = ::openat(path_fd, name.c_str(), flags, 0644);
5084     if (fd >= 0) {
5085       // block file is present
5086       struct stat st;
5087       int r = ::fstat(fd, &st);
5088       if (r == 0 &&
5089           S_ISREG(st.st_mode) &&   // if it is a regular file
5090           st.st_size == 0) {       // and is 0 bytes
5091         r = ::ftruncate(fd, size);
5092         if (r < 0) {
5093           r = -errno;
5094           derr << __func__ << " failed to resize " << name << " file to "
5095                << size << ": " << cpp_strerror(r) << dendl;
5096           VOID_TEMP_FAILURE_RETRY(::close(fd));
5097           return r;
5098         }
5099
5100         if (cct->_conf->bluestore_block_preallocate_file) {
5101 #ifdef HAVE_POSIX_FALLOCATE
5102           r = ::posix_fallocate(fd, 0, size);
5103           if (r) {
5104             derr << __func__ << " failed to prefallocate " << name << " file to "
5105               << size << ": " << cpp_strerror(r) << dendl;
5106             VOID_TEMP_FAILURE_RETRY(::close(fd));
5107             return -r;
5108           }
5109 #else
5110           char data[1024*128];
5111           for (uint64_t off = 0; off < size; off += sizeof(data)) {
5112             if (off + sizeof(data) > size)
5113               r = ::write(fd, data, size - off);
5114             else
5115               r = ::write(fd, data, sizeof(data));
5116             if (r < 0) {
5117               r = -errno;
5118               derr << __func__ << " failed to prefallocate w/ write " << name << " file to "
5119                 << size << ": " << cpp_strerror(r) << dendl;
5120               VOID_TEMP_FAILURE_RETRY(::close(fd));
5121               return r;
5122             }
5123           }
5124 #endif
5125         }
5126         dout(1) << __func__ << " resized " << name << " file to "
5127                 << pretty_si_t(size) << "B" << dendl;
5128       }
5129       VOID_TEMP_FAILURE_RETRY(::close(fd));
5130     } else {
5131       int r = -errno;
5132       if (r != -ENOENT) {
5133         derr << __func__ << " failed to open " << name << " file: "
5134              << cpp_strerror(r) << dendl;
5135         return r;
5136       }
5137     }
5138   }
5139   return 0;
5140 }
5141
5142 int BlueStore::mkfs()
5143 {
5144   dout(1) << __func__ << " path " << path << dendl;
5145   int r;
5146   uuid_d old_fsid;
5147
5148   {
5149     string done;
5150     r = read_meta("mkfs_done", &done);
5151     if (r == 0) {
5152       dout(1) << __func__ << " already created" << dendl;
5153       if (cct->_conf->bluestore_fsck_on_mkfs) {
5154         r = fsck(cct->_conf->bluestore_fsck_on_mkfs_deep);
5155         if (r < 0) {
5156           derr << __func__ << " fsck found fatal error: " << cpp_strerror(r)
5157                << dendl;
5158           return r;
5159         }
5160         if (r > 0) {
5161           derr << __func__ << " fsck found " << r << " errors" << dendl;
5162           r = -EIO;
5163         }
5164       }
5165       return r; // idempotent
5166     }
5167   }
5168
5169   {
5170     string type;
5171     r = read_meta("type", &type);
5172     if (r == 0) {
5173       if (type != "bluestore") {
5174         derr << __func__ << " expected bluestore, but type is " << type << dendl;
5175         return -EIO;
5176       }
5177     } else {
5178       r = write_meta("type", "bluestore");
5179       if (r < 0)
5180         return r;
5181     }
5182   }
5183
5184   freelist_type = "bitmap";
5185
5186   r = _open_path();
5187   if (r < 0)
5188     return r;
5189
5190   r = _open_fsid(true);
5191   if (r < 0)
5192     goto out_path_fd;
5193
5194   r = _lock_fsid();
5195   if (r < 0)
5196     goto out_close_fsid;
5197
5198   r = _read_fsid(&old_fsid);
5199   if (r < 0 || old_fsid.is_zero()) {
5200     if (fsid.is_zero()) {
5201       fsid.generate_random();
5202       dout(1) << __func__ << " generated fsid " << fsid << dendl;
5203     } else {
5204       dout(1) << __func__ << " using provided fsid " << fsid << dendl;
5205     }
5206     // we'll write it later.
5207   } else {
5208     if (!fsid.is_zero() && fsid != old_fsid) {
5209       derr << __func__ << " on-disk fsid " << old_fsid
5210            << " != provided " << fsid << dendl;
5211       r = -EINVAL;
5212       goto out_close_fsid;
5213     }
5214     fsid = old_fsid;
5215   }
5216
5217   r = _setup_block_symlink_or_file("block", cct->_conf->bluestore_block_path,
5218                                    cct->_conf->bluestore_block_size,
5219                                    cct->_conf->bluestore_block_create);
5220   if (r < 0)
5221     goto out_close_fsid;
5222   if (cct->_conf->bluestore_bluefs) {
5223     r = _setup_block_symlink_or_file("block.wal", cct->_conf->bluestore_block_wal_path,
5224         cct->_conf->bluestore_block_wal_size,
5225         cct->_conf->bluestore_block_wal_create);
5226     if (r < 0)
5227       goto out_close_fsid;
5228     r = _setup_block_symlink_or_file("block.db", cct->_conf->bluestore_block_db_path,
5229         cct->_conf->bluestore_block_db_size,
5230         cct->_conf->bluestore_block_db_create);
5231     if (r < 0)
5232       goto out_close_fsid;
5233   }
5234
5235   r = _open_bdev(true);
5236   if (r < 0)
5237     goto out_close_fsid;
5238
5239   {
5240     string wal_path = cct->_conf->get_val<string>("bluestore_block_wal_path");
5241     if (wal_path.size()) {
5242       write_meta("path_block.wal", wal_path);
5243     }
5244     string db_path = cct->_conf->get_val<string>("bluestore_block_db_path");
5245     if (db_path.size()) {
5246       write_meta("path_block.db", db_path);
5247     }
5248   }
5249
5250   // choose min_alloc_size
5251   if (cct->_conf->bluestore_min_alloc_size) {
5252     min_alloc_size = cct->_conf->bluestore_min_alloc_size;
5253   } else {
5254     assert(bdev);
5255     if (bdev->is_rotational()) {
5256       min_alloc_size = cct->_conf->bluestore_min_alloc_size_hdd;
5257     } else {
5258       min_alloc_size = cct->_conf->bluestore_min_alloc_size_ssd;
5259     }
5260   }
5261
5262   // make sure min_alloc_size is power of 2 aligned.
5263   if (!ISP2(min_alloc_size)) {
5264     derr << __func__ << " min_alloc_size 0x"
5265          << std::hex << min_alloc_size << std::dec
5266          << " is not power of 2 aligned!"
5267          << dendl;
5268     r = -EINVAL;
5269     goto out_close_bdev;
5270   }
5271
5272   r = _open_db(true);
5273   if (r < 0)
5274     goto out_close_bdev;
5275
5276   r = _open_fm(true);
5277   if (r < 0)
5278     goto out_close_db;
5279
5280   {
5281     KeyValueDB::Transaction t = db->get_transaction();
5282     {
5283       bufferlist bl;
5284       ::encode((uint64_t)0, bl);
5285       t->set(PREFIX_SUPER, "nid_max", bl);
5286       t->set(PREFIX_SUPER, "blobid_max", bl);
5287     }
5288
5289     {
5290       bufferlist bl;
5291       ::encode((uint64_t)min_alloc_size, bl);
5292       t->set(PREFIX_SUPER, "min_alloc_size", bl);
5293     }
5294
5295     ondisk_format = latest_ondisk_format;
5296     _prepare_ondisk_format_super(t);
5297     db->submit_transaction_sync(t);
5298   }
5299
5300
5301   r = write_meta("kv_backend", cct->_conf->bluestore_kvbackend);
5302   if (r < 0)
5303     goto out_close_fm;
5304
5305   r = write_meta("bluefs", stringify(bluefs ? 1 : 0));
5306   if (r < 0)
5307     goto out_close_fm;
5308
5309   if (fsid != old_fsid) {
5310     r = _write_fsid();
5311     if (r < 0) {
5312       derr << __func__ << " error writing fsid: " << cpp_strerror(r) << dendl;
5313       goto out_close_fm;
5314     }
5315   }
5316
5317  out_close_fm:
5318   _close_fm();
5319  out_close_db:
5320   _close_db();
5321  out_close_bdev:
5322   _close_bdev();
5323  out_close_fsid:
5324   _close_fsid();
5325  out_path_fd:
5326   _close_path();
5327
5328   if (r == 0 &&
5329       cct->_conf->bluestore_fsck_on_mkfs) {
5330     int rc = fsck(cct->_conf->bluestore_fsck_on_mkfs_deep);
5331     if (rc < 0)
5332       return rc;
5333     if (rc > 0) {
5334       derr << __func__ << " fsck found " << rc << " errors" << dendl;
5335       r = -EIO;
5336     }
5337   }
5338
5339   if (r == 0) {
5340     // indicate success by writing the 'mkfs_done' file
5341     r = write_meta("mkfs_done", "yes");
5342   }
5343
5344   if (r < 0) {
5345     derr << __func__ << " failed, " << cpp_strerror(r) << dendl;
5346   } else {
5347     dout(0) << __func__ << " success" << dendl;
5348   }
5349   return r;
5350 }
5351
5352 void BlueStore::set_cache_shards(unsigned num)
5353 {
5354   dout(10) << __func__ << " " << num << dendl;
5355   size_t old = cache_shards.size();
5356   assert(num >= old);
5357   cache_shards.resize(num);
5358   for (unsigned i = old; i < num; ++i) {
5359     cache_shards[i] = Cache::create(cct, cct->_conf->bluestore_cache_type,
5360                                     logger);
5361   }
5362 }
5363
5364 int BlueStore::_mount(bool kv_only)
5365 {
5366   dout(1) << __func__ << " path " << path << dendl;
5367
5368   _kv_only = kv_only;
5369
5370   {
5371     string type;
5372     int r = read_meta("type", &type);
5373     if (r < 0) {
5374       derr << __func__ << " failed to load os-type: " << cpp_strerror(r)
5375            << dendl;
5376       return r;
5377     }
5378
5379     if (type != "bluestore") {
5380       derr << __func__ << " expected bluestore, but type is " << type << dendl;
5381       return -EIO;
5382     }
5383   }
5384
5385   if (cct->_conf->bluestore_fsck_on_mount) {
5386     int rc = fsck(cct->_conf->bluestore_fsck_on_mount_deep);
5387     if (rc < 0)
5388       return rc;
5389     if (rc > 0) {
5390       derr << __func__ << " fsck found " << rc << " errors" << dendl;
5391       return -EIO;
5392     }
5393   }
5394
5395   int r = _open_path();
5396   if (r < 0)
5397     return r;
5398   r = _open_fsid(false);
5399   if (r < 0)
5400     goto out_path;
5401
5402   r = _read_fsid(&fsid);
5403   if (r < 0)
5404     goto out_fsid;
5405
5406   r = _lock_fsid();
5407   if (r < 0)
5408     goto out_fsid;
5409
5410   r = _open_bdev(false);
5411   if (r < 0)
5412     goto out_fsid;
5413
5414   r = _open_db(false);
5415   if (r < 0)
5416     goto out_bdev;
5417
5418   if (kv_only)
5419     return 0;
5420
5421   r = _open_super_meta();
5422   if (r < 0)
5423     goto out_db;
5424
5425   r = _open_fm(false);
5426   if (r < 0)
5427     goto out_db;
5428
5429   r = _open_alloc();
5430   if (r < 0)
5431     goto out_fm;
5432
5433   r = _open_collections();
5434   if (r < 0)
5435     goto out_alloc;
5436
5437   r = _reload_logger();
5438   if (r < 0)
5439     goto out_coll;
5440
5441   if (bluefs) {
5442     r = _reconcile_bluefs_freespace();
5443     if (r < 0)
5444       goto out_coll;
5445   }
5446
5447   _kv_start();
5448
5449   r = _deferred_replay();
5450   if (r < 0)
5451     goto out_stop;
5452
5453   mempool_thread.init();
5454
5455
5456   mounted = true;
5457   return 0;
5458
5459  out_stop:
5460   _kv_stop();
5461  out_coll:
5462   _flush_cache();
5463  out_alloc:
5464   _close_alloc();
5465  out_fm:
5466   _close_fm();
5467  out_db:
5468   _close_db();
5469  out_bdev:
5470   _close_bdev();
5471  out_fsid:
5472   _close_fsid();
5473  out_path:
5474   _close_path();
5475   return r;
5476 }
5477
5478 int BlueStore::umount()
5479 {
5480   assert(_kv_only || mounted);
5481   dout(1) << __func__ << dendl;
5482
5483   _osr_drain_all();
5484   _osr_unregister_all();
5485
5486   mounted = false;
5487   if (!_kv_only) {
5488     mempool_thread.shutdown();
5489     dout(20) << __func__ << " stopping kv thread" << dendl;
5490     _kv_stop();
5491     _reap_collections();
5492     _flush_cache();
5493     dout(20) << __func__ << " closing" << dendl;
5494
5495     _close_alloc();
5496     _close_fm();
5497   }
5498   _close_db();
5499   _close_bdev();
5500   _close_fsid();
5501   _close_path();
5502
5503   if (cct->_conf->bluestore_fsck_on_umount) {
5504     int rc = fsck(cct->_conf->bluestore_fsck_on_umount_deep);
5505     if (rc < 0)
5506       return rc;
5507     if (rc > 0) {
5508       derr << __func__ << " fsck found " << rc << " errors" << dendl;
5509       return -EIO;
5510     }
5511   }
5512   return 0;
5513 }
5514
5515 static void apply(uint64_t off,
5516                   uint64_t len,
5517                   uint64_t granularity,
5518                   BlueStore::mempool_dynamic_bitset &bitset,
5519                   const char *what,
5520                   std::function<void(uint64_t,
5521                                      BlueStore::mempool_dynamic_bitset &)> f) {
5522   auto end = ROUND_UP_TO(off + len, granularity);
5523   while (off < end) {
5524     uint64_t pos = off / granularity;
5525     f(pos, bitset);
5526     off += granularity;
5527   }
5528 }
5529
5530 int BlueStore::_fsck_check_extents(
5531   const ghobject_t& oid,
5532   const PExtentVector& extents,
5533   bool compressed,
5534   mempool_dynamic_bitset &used_blocks,
5535   store_statfs_t& expected_statfs)
5536 {
5537   dout(30) << __func__ << " oid " << oid << " extents " << extents << dendl;
5538   int errors = 0;
5539   for (auto e : extents) {
5540     if (!e.is_valid())
5541       continue;
5542     expected_statfs.allocated += e.length;
5543     if (compressed) {
5544       expected_statfs.compressed_allocated += e.length;
5545     }
5546     bool already = false;
5547     apply(
5548       e.offset, e.length, min_alloc_size, used_blocks, __func__,
5549       [&](uint64_t pos, mempool_dynamic_bitset &bs) {
5550         if (bs.test(pos))
5551           already = true;
5552         else
5553           bs.set(pos);
5554       });
5555     if (already) {
5556       derr << " " << oid << " extent " << e
5557            << " or a subset is already allocated" << dendl;
5558       ++errors;
5559     }
5560     if (e.end() > bdev->get_size()) {
5561       derr << " " << oid << " extent " << e
5562            << " past end of block device" << dendl;
5563       ++errors;
5564     }
5565   }
5566   return errors;
5567 }
5568
5569 int BlueStore::_fsck(bool deep, bool repair)
5570 {
5571   dout(1) << __func__
5572           << (repair ? " fsck" : " repair")
5573           << (deep ? " (deep)" : " (shallow)") << " start" << dendl;
5574   int errors = 0;
5575   int repaired = 0;
5576
5577   typedef btree::btree_set<
5578     uint64_t,std::less<uint64_t>,
5579     mempool::bluestore_fsck::pool_allocator<uint64_t>> uint64_t_btree_t;
5580   uint64_t_btree_t used_nids;
5581   uint64_t_btree_t used_omap_head;
5582   uint64_t_btree_t used_sbids;
5583
5584   mempool_dynamic_bitset used_blocks;
5585   KeyValueDB::Iterator it;
5586   store_statfs_t expected_statfs, actual_statfs;
5587   struct sb_info_t {
5588     list<ghobject_t> oids;
5589     SharedBlobRef sb;
5590     bluestore_extent_ref_map_t ref_map;
5591     bool compressed;
5592   };
5593   mempool::bluestore_fsck::map<uint64_t,sb_info_t> sb_info;
5594
5595   uint64_t num_objects = 0;
5596   uint64_t num_extents = 0;
5597   uint64_t num_blobs = 0;
5598   uint64_t num_spanning_blobs = 0;
5599   uint64_t num_shared_blobs = 0;
5600   uint64_t num_sharded_objects = 0;
5601   uint64_t num_object_shards = 0;
5602
5603   utime_t start = ceph_clock_now();
5604
5605   int r = _open_path();
5606   if (r < 0)
5607     return r;
5608   r = _open_fsid(false);
5609   if (r < 0)
5610     goto out_path;
5611
5612   r = _read_fsid(&fsid);
5613   if (r < 0)
5614     goto out_fsid;
5615
5616   r = _lock_fsid();
5617   if (r < 0)
5618     goto out_fsid;
5619
5620   r = _open_bdev(false);
5621   if (r < 0)
5622     goto out_fsid;
5623
5624   r = _open_db(false);
5625   if (r < 0)
5626     goto out_bdev;
5627
5628   r = _open_super_meta();
5629   if (r < 0)
5630     goto out_db;
5631
5632   r = _open_fm(false);
5633   if (r < 0)
5634     goto out_db;
5635
5636   r = _open_alloc();
5637   if (r < 0)
5638     goto out_fm;
5639
5640   r = _open_collections(&errors);
5641   if (r < 0)
5642     goto out_alloc;
5643
5644   mempool_thread.init();
5645
5646   // we need finishers and kv_{sync,finalize}_thread *just* for replay
5647   _kv_start();
5648   r = _deferred_replay();
5649   _kv_stop();
5650   if (r < 0)
5651     goto out_scan;
5652
5653   used_blocks.resize(bdev->get_size() / min_alloc_size);
5654   apply(
5655     0, MAX(min_alloc_size, SUPER_RESERVED), min_alloc_size, used_blocks,
5656     "0~SUPER_RESERVED",
5657     [&](uint64_t pos, mempool_dynamic_bitset &bs) {
5658       bs.set(pos);
5659     }
5660   );
5661
5662   if (bluefs) {
5663     for (auto e = bluefs_extents.begin(); e != bluefs_extents.end(); ++e) {
5664       apply(
5665         e.get_start(), e.get_len(), min_alloc_size, used_blocks, "bluefs",
5666         [&](uint64_t pos, mempool_dynamic_bitset &bs) {
5667           bs.set(pos);
5668         }
5669         );
5670     }
5671     r = bluefs->fsck();
5672     if (r < 0) {
5673       goto out_scan;
5674     }
5675     if (r > 0)
5676       errors += r;
5677   }
5678
5679   // get expected statfs; fill unaffected fields to be able to compare
5680   // structs
5681   statfs(&actual_statfs);
5682   expected_statfs.total = actual_statfs.total;
5683   expected_statfs.available = actual_statfs.available;
5684
5685   // walk PREFIX_OBJ
5686   dout(1) << __func__ << " walking object keyspace" << dendl;
5687   it = db->get_iterator(PREFIX_OBJ);
5688   if (it) {
5689     CollectionRef c;
5690     spg_t pgid;
5691     mempool::bluestore_fsck::list<string> expecting_shards;
5692     for (it->lower_bound(string()); it->valid(); it->next()) {
5693       if (g_conf->bluestore_debug_fsck_abort) {
5694         goto out_scan;
5695       }
5696       dout(30) << " key " << pretty_binary_string(it->key()) << dendl;
5697       if (is_extent_shard_key(it->key())) {
5698         while (!expecting_shards.empty() &&
5699                expecting_shards.front() < it->key()) {
5700           derr << "fsck error: missing shard key "
5701                << pretty_binary_string(expecting_shards.front())
5702                << dendl;
5703           ++errors;
5704           expecting_shards.pop_front();
5705         }
5706         if (!expecting_shards.empty() &&
5707             expecting_shards.front() == it->key()) {
5708           // all good
5709           expecting_shards.pop_front();
5710           continue;
5711         }
5712
5713         uint32_t offset;
5714         string okey;
5715         get_key_extent_shard(it->key(), &okey, &offset);
5716         derr << "fsck error: stray shard 0x" << std::hex << offset
5717              << std::dec << dendl;
5718         if (expecting_shards.empty()) {
5719           derr << "fsck error: " << pretty_binary_string(it->key())
5720                << " is unexpected" << dendl;
5721           ++errors;
5722           continue;
5723         }
5724         while (expecting_shards.front() > it->key()) {
5725           derr << "fsck error:   saw " << pretty_binary_string(it->key())
5726                << dendl;
5727           derr << "fsck error:   exp "
5728                << pretty_binary_string(expecting_shards.front()) << dendl;
5729           ++errors;
5730           expecting_shards.pop_front();
5731           if (expecting_shards.empty()) {
5732             break;
5733           }
5734         }
5735         continue;
5736       }
5737
5738       ghobject_t oid;
5739       int r = get_key_object(it->key(), &oid);
5740       if (r < 0) {
5741         derr << "fsck error: bad object key "
5742              << pretty_binary_string(it->key()) << dendl;
5743         ++errors;
5744         continue;
5745       }
5746       if (!c ||
5747           oid.shard_id != pgid.shard ||
5748           oid.hobj.pool != (int64_t)pgid.pool() ||
5749           !c->contains(oid)) {
5750         c = nullptr;
5751         for (ceph::unordered_map<coll_t, CollectionRef>::iterator p =
5752                coll_map.begin();
5753              p != coll_map.end();
5754              ++p) {
5755           if (p->second->contains(oid)) {
5756             c = p->second;
5757             break;
5758           }
5759         }
5760         if (!c) {
5761           derr << "fsck error: stray object " << oid
5762                << " not owned by any collection" << dendl;
5763           ++errors;
5764           continue;
5765         }
5766         c->cid.is_pg(&pgid);
5767         dout(20) << __func__ << "  collection " << c->cid << dendl;
5768       }
5769
5770       if (!expecting_shards.empty()) {
5771         for (auto &k : expecting_shards) {
5772           derr << "fsck error: missing shard key "
5773                << pretty_binary_string(k) << dendl;
5774         }
5775         ++errors;
5776         expecting_shards.clear();
5777       }
5778
5779       dout(10) << __func__ << "  " << oid << dendl;
5780       RWLock::RLocker l(c->lock);
5781       OnodeRef o = c->get_onode(oid, false);
5782       if (o->onode.nid) {
5783         if (o->onode.nid > nid_max) {
5784           derr << "fsck error: " << oid << " nid " << o->onode.nid
5785                << " > nid_max " << nid_max << dendl;
5786           ++errors;
5787         }
5788         if (used_nids.count(o->onode.nid)) {
5789           derr << "fsck error: " << oid << " nid " << o->onode.nid
5790                << " already in use" << dendl;
5791           ++errors;
5792           continue; // go for next object
5793         }
5794         used_nids.insert(o->onode.nid);
5795       }
5796       ++num_objects;
5797       num_spanning_blobs += o->extent_map.spanning_blob_map.size();
5798       o->extent_map.fault_range(db, 0, OBJECT_MAX_SIZE);
5799       _dump_onode(o, 30);
5800       // shards
5801       if (!o->extent_map.shards.empty()) {
5802         ++num_sharded_objects;
5803         num_object_shards += o->extent_map.shards.size();
5804       }
5805       for (auto& s : o->extent_map.shards) {
5806         dout(20) << __func__ << "    shard " << *s.shard_info << dendl;
5807         expecting_shards.push_back(string());
5808         get_extent_shard_key(o->key, s.shard_info->offset,
5809                              &expecting_shards.back());
5810         if (s.shard_info->offset >= o->onode.size) {
5811           derr << "fsck error: " << oid << " shard 0x" << std::hex
5812                << s.shard_info->offset << " past EOF at 0x" << o->onode.size
5813                << std::dec << dendl;
5814           ++errors;
5815         }
5816       }
5817       // lextents
5818       map<BlobRef,bluestore_blob_t::unused_t> referenced;
5819       uint64_t pos = 0;
5820       mempool::bluestore_fsck::map<BlobRef,
5821                                    bluestore_blob_use_tracker_t> ref_map;
5822       for (auto& l : o->extent_map.extent_map) {
5823         dout(20) << __func__ << "    " << l << dendl;
5824         if (l.logical_offset < pos) {
5825           derr << "fsck error: " << oid << " lextent at 0x"
5826                << std::hex << l.logical_offset
5827                << " overlaps with the previous, which ends at 0x" << pos
5828                << std::dec << dendl;
5829           ++errors;
5830         }
5831         if (o->extent_map.spans_shard(l.logical_offset, l.length)) {
5832           derr << "fsck error: " << oid << " lextent at 0x"
5833                << std::hex << l.logical_offset << "~" << l.length
5834                << " spans a shard boundary"
5835                << std::dec << dendl;
5836           ++errors;
5837         }
5838         pos = l.logical_offset + l.length;
5839         expected_statfs.stored += l.length;
5840         assert(l.blob);
5841         const bluestore_blob_t& blob = l.blob->get_blob();
5842
5843         auto& ref = ref_map[l.blob];
5844         if (ref.is_empty()) {
5845           uint32_t min_release_size = blob.get_release_size(min_alloc_size);
5846           uint32_t l = blob.get_logical_length();
5847           ref.init(l, min_release_size);
5848         }
5849         ref.get(
5850           l.blob_offset, 
5851           l.length);
5852         ++num_extents;
5853         if (blob.has_unused()) {
5854           auto p = referenced.find(l.blob);
5855           bluestore_blob_t::unused_t *pu;
5856           if (p == referenced.end()) {
5857             pu = &referenced[l.blob];
5858           } else {
5859             pu = &p->second;
5860           }
5861           uint64_t blob_len = blob.get_logical_length();
5862           assert((blob_len % (sizeof(*pu)*8)) == 0);
5863           assert(l.blob_offset + l.length <= blob_len);
5864           uint64_t chunk_size = blob_len / (sizeof(*pu)*8);
5865           uint64_t start = l.blob_offset / chunk_size;
5866           uint64_t end =
5867             ROUND_UP_TO(l.blob_offset + l.length, chunk_size) / chunk_size;
5868           for (auto i = start; i < end; ++i) {
5869             (*pu) |= (1u << i);
5870           }
5871         }
5872       }
5873       for (auto &i : referenced) {
5874         dout(20) << __func__ << "  referenced 0x" << std::hex << i.second
5875                  << std::dec << " for " << *i.first << dendl;
5876         const bluestore_blob_t& blob = i.first->get_blob();
5877         if (i.second & blob.unused) {
5878           derr << "fsck error: " << oid << " blob claims unused 0x"
5879                << std::hex << blob.unused
5880                << " but extents reference 0x" << i.second
5881                << " on blob " << *i.first << dendl;
5882           ++errors;
5883         }
5884         if (blob.has_csum()) {
5885           uint64_t blob_len = blob.get_logical_length();
5886           uint64_t unused_chunk_size = blob_len / (sizeof(blob.unused)*8);
5887           unsigned csum_count = blob.get_csum_count();
5888           unsigned csum_chunk_size = blob.get_csum_chunk_size();
5889           for (unsigned p = 0; p < csum_count; ++p) {
5890             unsigned pos = p * csum_chunk_size;
5891             unsigned firstbit = pos / unused_chunk_size;    // [firstbit,lastbit]
5892             unsigned lastbit = (pos + csum_chunk_size - 1) / unused_chunk_size;
5893             unsigned mask = 1u << firstbit;
5894             for (unsigned b = firstbit + 1; b <= lastbit; ++b) {
5895               mask |= 1u << b;
5896             }
5897             if ((blob.unused & mask) == mask) {
5898               // this csum chunk region is marked unused
5899               if (blob.get_csum_item(p) != 0) {
5900                 derr << "fsck error: " << oid
5901                      << " blob claims csum chunk 0x" << std::hex << pos
5902                      << "~" << csum_chunk_size
5903                      << " is unused (mask 0x" << mask << " of unused 0x"
5904                      << blob.unused << ") but csum is non-zero 0x"
5905                      << blob.get_csum_item(p) << std::dec << " on blob "
5906                      << *i.first << dendl;
5907                 ++errors;
5908               }
5909             }
5910           }
5911         }
5912       }
5913       for (auto &i : ref_map) {
5914         ++num_blobs;
5915         const bluestore_blob_t& blob = i.first->get_blob();
5916         bool equal = i.first->get_blob_use_tracker().equal(i.second);
5917         if (!equal) {
5918           derr << "fsck error: " << oid << " blob " << *i.first
5919                << " doesn't match expected ref_map " << i.second << dendl;
5920           ++errors;
5921         }
5922         if (blob.is_compressed()) {
5923           expected_statfs.compressed += blob.get_compressed_payload_length();
5924           expected_statfs.compressed_original += 
5925             i.first->get_referenced_bytes();
5926         }
5927         if (blob.is_shared()) {
5928           if (i.first->shared_blob->get_sbid() > blobid_max) {
5929             derr << "fsck error: " << oid << " blob " << blob
5930                  << " sbid " << i.first->shared_blob->get_sbid() << " > blobid_max "
5931                  << blobid_max << dendl;
5932             ++errors;
5933           } else if (i.first->shared_blob->get_sbid() == 0) {
5934             derr << "fsck error: " << oid << " blob " << blob
5935                  << " marked as shared but has uninitialized sbid"
5936                  << dendl;
5937             ++errors;
5938           }
5939           sb_info_t& sbi = sb_info[i.first->shared_blob->get_sbid()];
5940           sbi.sb = i.first->shared_blob;
5941           sbi.oids.push_back(oid);
5942           sbi.compressed = blob.is_compressed();
5943           for (auto e : blob.get_extents()) {
5944             if (e.is_valid()) {
5945               sbi.ref_map.get(e.offset, e.length);
5946             }
5947           }
5948         } else {
5949           errors += _fsck_check_extents(oid, blob.get_extents(),
5950                                         blob.is_compressed(),
5951                                         used_blocks,
5952                                         expected_statfs);
5953         }
5954       }
5955       if (deep) {
5956         bufferlist bl;
5957         int r = _do_read(c.get(), o, 0, o->onode.size, bl, 0);
5958         if (r < 0) {
5959           ++errors;
5960           derr << "fsck error: " << oid << " error during read: "
5961                << cpp_strerror(r) << dendl;
5962         }
5963       }
5964       // omap
5965       if (o->onode.has_omap()) {
5966         if (used_omap_head.count(o->onode.nid)) {
5967           derr << "fsck error: " << oid << " omap_head " << o->onode.nid
5968                << " already in use" << dendl;
5969           ++errors;
5970         } else {
5971           used_omap_head.insert(o->onode.nid);
5972         }
5973       }
5974     }
5975   }
5976   dout(1) << __func__ << " checking shared_blobs" << dendl;
5977   it = db->get_iterator(PREFIX_SHARED_BLOB);
5978   if (it) {
5979     for (it->lower_bound(string()); it->valid(); it->next()) {
5980       string key = it->key();
5981       uint64_t sbid;
5982       if (get_key_shared_blob(key, &sbid)) {
5983         derr << "fsck error: bad key '" << key
5984              << "' in shared blob namespace" << dendl;
5985         ++errors;
5986         continue;
5987       }
5988       auto p = sb_info.find(sbid);
5989       if (p == sb_info.end()) {
5990         derr << "fsck error: found stray shared blob data for sbid 0x"
5991              << std::hex << sbid << std::dec << dendl;
5992         ++errors;
5993       } else {
5994         ++num_shared_blobs;
5995         sb_info_t& sbi = p->second;
5996         bluestore_shared_blob_t shared_blob(sbid);
5997         bufferlist bl = it->value();
5998         bufferlist::iterator blp = bl.begin();
5999         ::decode(shared_blob, blp);
6000         dout(20) << __func__ << "  " << *sbi.sb << " " << shared_blob << dendl;
6001         if (shared_blob.ref_map != sbi.ref_map) {
6002           derr << "fsck error: shared blob 0x" << std::hex << sbid
6003                << std::dec << " ref_map " << shared_blob.ref_map
6004                << " != expected " << sbi.ref_map << dendl;
6005           ++errors;
6006         }
6007         PExtentVector extents;
6008         for (auto &r : shared_blob.ref_map.ref_map) {
6009           extents.emplace_back(bluestore_pextent_t(r.first, r.second.length));
6010         }
6011         errors += _fsck_check_extents(p->second.oids.front(),
6012                                       extents,
6013                                       p->second.compressed,
6014                                       used_blocks, expected_statfs);
6015         sb_info.erase(p);
6016       }
6017     }
6018   }
6019   for (auto &p : sb_info) {
6020     derr << "fsck error: shared_blob 0x" << p.first
6021          << " key is missing (" << *p.second.sb << ")" << dendl;
6022     ++errors;
6023   }
6024   if (!(actual_statfs == expected_statfs)) {
6025     derr << "fsck error: actual " << actual_statfs
6026          << " != expected " << expected_statfs << dendl;
6027     ++errors;
6028   }
6029
6030   dout(1) << __func__ << " checking for stray omap data" << dendl;
6031   it = db->get_iterator(PREFIX_OMAP);
6032   if (it) {
6033     for (it->lower_bound(string()); it->valid(); it->next()) {
6034       uint64_t omap_head;
6035       _key_decode_u64(it->key().c_str(), &omap_head);
6036       if (used_omap_head.count(omap_head) == 0) {
6037         derr << "fsck error: found stray omap data on omap_head "
6038              << omap_head << dendl;
6039         ++errors;
6040       }
6041     }
6042   }
6043
6044   dout(1) << __func__ << " checking deferred events" << dendl;
6045   it = db->get_iterator(PREFIX_DEFERRED);
6046   if (it) {
6047     for (it->lower_bound(string()); it->valid(); it->next()) {
6048       bufferlist bl = it->value();
6049       bufferlist::iterator p = bl.begin();
6050       bluestore_deferred_transaction_t wt;
6051       try {
6052         ::decode(wt, p);
6053       } catch (buffer::error& e) {
6054         derr << "fsck error: failed to decode deferred txn "
6055              << pretty_binary_string(it->key()) << dendl;
6056         r = -EIO;
6057         goto out_scan;
6058       }
6059       dout(20) << __func__ << "  deferred " << wt.seq
6060                << " ops " << wt.ops.size()
6061                << " released 0x" << std::hex << wt.released << std::dec << dendl;
6062       for (auto e = wt.released.begin(); e != wt.released.end(); ++e) {
6063         apply(
6064           e.get_start(), e.get_len(), min_alloc_size, used_blocks, "deferred",
6065           [&](uint64_t pos, mempool_dynamic_bitset &bs) {
6066             bs.set(pos);
6067           }
6068         );
6069       }
6070     }
6071   }
6072
6073   dout(1) << __func__ << " checking freelist vs allocated" << dendl;
6074   {
6075     // remove bluefs_extents from used set since the freelist doesn't
6076     // know they are allocated.
6077     for (auto e = bluefs_extents.begin(); e != bluefs_extents.end(); ++e) {
6078       apply(
6079         e.get_start(), e.get_len(), min_alloc_size, used_blocks,
6080         "bluefs_extents",
6081         [&](uint64_t pos, mempool_dynamic_bitset &bs) {
6082           bs.reset(pos);
6083         }
6084       );
6085     }
6086     fm->enumerate_reset();
6087     uint64_t offset, length;
6088     while (fm->enumerate_next(&offset, &length)) {
6089       bool intersects = false;
6090       apply(
6091         offset, length, min_alloc_size, used_blocks, "free",
6092         [&](uint64_t pos, mempool_dynamic_bitset &bs) {
6093           if (bs.test(pos)) {
6094             intersects = true;
6095           } else {
6096             bs.set(pos);
6097           }
6098         }
6099       );
6100       if (intersects) {
6101         if (offset == SUPER_RESERVED &&
6102             length == min_alloc_size - SUPER_RESERVED) {
6103           // this is due to the change just after luminous to min_alloc_size
6104           // granularity allocations, and our baked in assumption at the top
6105           // of _fsck that 0~ROUND_UP_TO(SUPER_RESERVED,min_alloc_size) is used
6106           // (vs luminous's ROUND_UP_TO(SUPER_RESERVED,block_size)).  harmless,
6107           // since we will never allocate this region below min_alloc_size.
6108           dout(10) << __func__ << " ignoring free extent between SUPER_RESERVED"
6109                    << " and min_alloc_size, 0x" << std::hex << offset << "~"
6110                    << length << dendl;
6111         } else {
6112           derr << "fsck error: free extent 0x" << std::hex << offset
6113                << "~" << length << std::dec
6114                << " intersects allocated blocks" << dendl;
6115           ++errors;
6116         }
6117       }
6118     }
6119     fm->enumerate_reset();
6120     size_t count = used_blocks.count();
6121     if (used_blocks.size() != count) {
6122       assert(used_blocks.size() > count);
6123       ++errors;
6124       used_blocks.flip();
6125       size_t start = used_blocks.find_first();
6126       while (start != decltype(used_blocks)::npos) {
6127         size_t cur = start;
6128         while (true) {
6129           size_t next = used_blocks.find_next(cur);
6130           if (next != cur + 1) {
6131             derr << "fsck error: leaked extent 0x" << std::hex
6132                  << ((uint64_t)start * min_alloc_size) << "~"
6133                  << ((cur + 1 - start) * min_alloc_size) << std::dec
6134                  << dendl;
6135             start = next;
6136             break;
6137           }
6138           cur = next;
6139         }
6140       }
6141       used_blocks.flip();
6142     }
6143   }
6144
6145  out_scan:
6146   mempool_thread.shutdown();
6147   _flush_cache();
6148  out_alloc:
6149   _close_alloc();
6150  out_fm:
6151   _close_fm();
6152  out_db:
6153   it.reset();  // before db is closed
6154   _close_db();
6155  out_bdev:
6156   _close_bdev();
6157  out_fsid:
6158   _close_fsid();
6159  out_path:
6160   _close_path();
6161
6162   // fatal errors take precedence
6163   if (r < 0)
6164     return r;
6165
6166   dout(2) << __func__ << " " << num_objects << " objects, "
6167           << num_sharded_objects << " of them sharded.  "
6168           << dendl;
6169   dout(2) << __func__ << " " << num_extents << " extents to "
6170           << num_blobs << " blobs, "
6171           << num_spanning_blobs << " spanning, "
6172           << num_shared_blobs << " shared."
6173           << dendl;
6174
6175   utime_t duration = ceph_clock_now() - start;
6176   dout(1) << __func__ << " finish with " << errors << " errors, " << repaired
6177           << " repaired, " << (errors - repaired) << " remaining in "
6178           << duration << " seconds" << dendl;
6179   return errors - repaired;
6180 }
6181
6182 void BlueStore::collect_metadata(map<string,string> *pm)
6183 {
6184   dout(10) << __func__ << dendl;
6185   bdev->collect_metadata("bluestore_bdev_", pm);
6186   if (bluefs) {
6187     (*pm)["bluefs"] = "1";
6188     (*pm)["bluefs_single_shared_device"] = stringify((int)bluefs_single_shared_device);
6189     bluefs->collect_metadata(pm);
6190   } else {
6191     (*pm)["bluefs"] = "0";
6192   }
6193 }
6194
6195 int BlueStore::statfs(struct store_statfs_t *buf)
6196 {
6197   buf->reset();
6198   buf->total = bdev->get_size();
6199   buf->available = alloc->get_free();
6200
6201   if (bluefs) {
6202     // part of our shared device is "free" according to BlueFS
6203     // Don't include bluestore_bluefs_min because that space can't
6204     // be used for any other purpose.
6205     buf->available += bluefs->get_free(bluefs_shared_bdev) - cct->_conf->bluestore_bluefs_min;
6206
6207     // include dedicated db, too, if that isn't the shared device.
6208     if (bluefs_shared_bdev != BlueFS::BDEV_DB) {
6209       buf->total += bluefs->get_total(BlueFS::BDEV_DB);
6210     }
6211   }
6212
6213   {
6214     std::lock_guard<std::mutex> l(vstatfs_lock);
6215     
6216     buf->allocated = vstatfs.allocated();
6217     buf->stored = vstatfs.stored();
6218     buf->compressed = vstatfs.compressed();
6219     buf->compressed_original = vstatfs.compressed_original();
6220     buf->compressed_allocated = vstatfs.compressed_allocated();
6221   }
6222
6223   dout(20) << __func__ << *buf << dendl;
6224   return 0;
6225 }
6226
6227 // ---------------
6228 // cache
6229
6230 BlueStore::CollectionRef BlueStore::_get_collection(const coll_t& cid)
6231 {
6232   RWLock::RLocker l(coll_lock);
6233   ceph::unordered_map<coll_t,CollectionRef>::iterator cp = coll_map.find(cid);
6234   if (cp == coll_map.end())
6235     return CollectionRef();
6236   return cp->second;
6237 }
6238
6239 void BlueStore::_queue_reap_collection(CollectionRef& c)
6240 {
6241   dout(10) << __func__ << " " << c << " " << c->cid << dendl;
6242   std::lock_guard<std::mutex> l(reap_lock);
6243   removed_collections.push_back(c);
6244 }
6245
6246 void BlueStore::_reap_collections()
6247 {
6248   list<CollectionRef> removed_colls;
6249   {
6250     std::lock_guard<std::mutex> l(reap_lock);
6251     removed_colls.swap(removed_collections);
6252   }
6253
6254   bool all_reaped = true;
6255
6256   for (list<CollectionRef>::iterator p = removed_colls.begin();
6257        p != removed_colls.end();
6258        ++p) {
6259     CollectionRef c = *p;
6260     dout(10) << __func__ << " " << c << " " << c->cid << dendl;
6261     if (c->onode_map.map_any([&](OnodeRef o) {
6262           assert(!o->exists);
6263           if (o->flushing_count.load()) {
6264             dout(10) << __func__ << " " << c << " " << c->cid << " " << o->oid
6265                      << " flush_txns " << o->flushing_count << dendl;
6266             return false;
6267           }
6268           return true;
6269         })) {
6270       all_reaped = false;
6271       continue;
6272     }
6273     c->onode_map.clear();
6274     dout(10) << __func__ << " " << c << " " << c->cid << " done" << dendl;
6275   }
6276
6277   if (all_reaped) {
6278     dout(10) << __func__ << " all reaped" << dendl;
6279   }
6280 }
6281
6282 void BlueStore::_update_cache_logger()
6283 {
6284   uint64_t num_onodes = 0;
6285   uint64_t num_extents = 0;
6286   uint64_t num_blobs = 0;
6287   uint64_t num_buffers = 0;
6288   uint64_t num_buffer_bytes = 0;
6289   for (auto c : cache_shards) {
6290     c->add_stats(&num_onodes, &num_extents, &num_blobs,
6291                  &num_buffers, &num_buffer_bytes);
6292   }
6293   logger->set(l_bluestore_onodes, num_onodes);
6294   logger->set(l_bluestore_extents, num_extents);
6295   logger->set(l_bluestore_blobs, num_blobs);
6296   logger->set(l_bluestore_buffers, num_buffers);
6297   logger->set(l_bluestore_buffer_bytes, num_buffer_bytes);
6298 }
6299
6300 // ---------------
6301 // read operations
6302
6303 ObjectStore::CollectionHandle BlueStore::open_collection(const coll_t& cid)
6304 {
6305   return _get_collection(cid);
6306 }
6307
6308 bool BlueStore::exists(const coll_t& cid, const ghobject_t& oid)
6309 {
6310   CollectionHandle c = _get_collection(cid);
6311   if (!c)
6312     return false;
6313   return exists(c, oid);
6314 }
6315
6316 bool BlueStore::exists(CollectionHandle &c_, const ghobject_t& oid)
6317 {
6318   Collection *c = static_cast<Collection *>(c_.get());
6319   dout(10) << __func__ << " " << c->cid << " " << oid << dendl;
6320   if (!c->exists)
6321     return false;
6322
6323   bool r = true;
6324
6325   {
6326     RWLock::RLocker l(c->lock);
6327     OnodeRef o = c->get_onode(oid, false);
6328     if (!o || !o->exists)
6329       r = false;
6330   }
6331
6332   return r;
6333 }
6334
6335 int BlueStore::stat(
6336     const coll_t& cid,
6337     const ghobject_t& oid,
6338     struct stat *st,
6339     bool allow_eio)
6340 {
6341   CollectionHandle c = _get_collection(cid);
6342   if (!c)
6343     return -ENOENT;
6344   return stat(c, oid, st, allow_eio);
6345 }
6346
6347 int BlueStore::stat(
6348   CollectionHandle &c_,
6349   const ghobject_t& oid,
6350   struct stat *st,
6351   bool allow_eio)
6352 {
6353   Collection *c = static_cast<Collection *>(c_.get());
6354   if (!c->exists)
6355     return -ENOENT;
6356   dout(10) << __func__ << " " << c->get_cid() << " " << oid << dendl;
6357
6358   {
6359     RWLock::RLocker l(c->lock);
6360     OnodeRef o = c->get_onode(oid, false);
6361     if (!o || !o->exists)
6362       return -ENOENT;
6363     st->st_size = o->onode.size;
6364     st->st_blksize = 4096;
6365     st->st_blocks = (st->st_size + st->st_blksize - 1) / st->st_blksize;
6366     st->st_nlink = 1;
6367   }
6368
6369   int r = 0;
6370   if (_debug_mdata_eio(oid)) {
6371     r = -EIO;
6372     derr << __func__ << " " << c->cid << " " << oid << " INJECT EIO" << dendl;
6373   }
6374   return r;
6375 }
6376 int BlueStore::set_collection_opts(
6377   const coll_t& cid,
6378   const pool_opts_t& opts)
6379 {
6380   CollectionHandle ch = _get_collection(cid);
6381   if (!ch)
6382     return -ENOENT;
6383   Collection *c = static_cast<Collection *>(ch.get());
6384   dout(15) << __func__ << " " << cid << " options " << opts << dendl;
6385   if (!c->exists)
6386     return -ENOENT;
6387   RWLock::WLocker l(c->lock);
6388   c->pool_opts = opts;
6389   return 0;
6390 }
6391
6392 int BlueStore::read(
6393   const coll_t& cid,
6394   const ghobject_t& oid,
6395   uint64_t offset,
6396   size_t length,
6397   bufferlist& bl,
6398   uint32_t op_flags)
6399 {
6400   CollectionHandle c = _get_collection(cid);
6401   if (!c)
6402     return -ENOENT;
6403   return read(c, oid, offset, length, bl, op_flags);
6404 }
6405
6406 int BlueStore::read(
6407   CollectionHandle &c_,
6408   const ghobject_t& oid,
6409   uint64_t offset,
6410   size_t length,
6411   bufferlist& bl,
6412   uint32_t op_flags)
6413 {
6414   utime_t start = ceph_clock_now();
6415   Collection *c = static_cast<Collection *>(c_.get());
6416   const coll_t &cid = c->get_cid();
6417   dout(15) << __func__ << " " << cid << " " << oid
6418            << " 0x" << std::hex << offset << "~" << length << std::dec
6419            << dendl;
6420   if (!c->exists)
6421     return -ENOENT;
6422
6423   bl.clear();
6424   int r;
6425   {
6426     RWLock::RLocker l(c->lock);
6427     utime_t start1 = ceph_clock_now();
6428     OnodeRef o = c->get_onode(oid, false);
6429     logger->tinc(l_bluestore_read_onode_meta_lat, ceph_clock_now() - start1);
6430     if (!o || !o->exists) {
6431       r = -ENOENT;
6432       goto out;
6433     }
6434
6435     if (offset == length && offset == 0)
6436       length = o->onode.size;
6437
6438     r = _do_read(c, o, offset, length, bl, op_flags);
6439   }
6440
6441  out:
6442   if (r == 0 && _debug_data_eio(oid)) {
6443     r = -EIO;
6444     derr << __func__ << " " << c->cid << " " << oid << " INJECT EIO" << dendl;
6445   } else if (cct->_conf->bluestore_debug_random_read_err &&
6446     (rand() % (int)(cct->_conf->bluestore_debug_random_read_err * 100.0)) == 0) {
6447     dout(0) << __func__ << ": inject random EIO" << dendl;
6448     r = -EIO;
6449   }
6450   dout(10) << __func__ << " " << cid << " " << oid
6451            << " 0x" << std::hex << offset << "~" << length << std::dec
6452            << " = " << r << dendl;
6453   logger->tinc(l_bluestore_read_lat, ceph_clock_now() - start);
6454   return r;
6455 }
6456
6457 // --------------------------------------------------------
6458 // intermediate data structures used while reading
6459 struct region_t {
6460   uint64_t logical_offset;
6461   uint64_t blob_xoffset;   //region offset within the blob
6462   uint64_t length;
6463   bufferlist bl;
6464
6465   // used later in read process
6466   uint64_t front = 0;
6467   uint64_t r_off = 0;
6468
6469   region_t(uint64_t offset, uint64_t b_offs, uint64_t len)
6470     : logical_offset(offset),
6471     blob_xoffset(b_offs),
6472     length(len){}
6473   region_t(const region_t& from)
6474     : logical_offset(from.logical_offset),
6475     blob_xoffset(from.blob_xoffset),
6476     length(from.length){}
6477
6478   friend ostream& operator<<(ostream& out, const region_t& r) {
6479     return out << "0x" << std::hex << r.logical_offset << ":"
6480       << r.blob_xoffset << "~" << r.length << std::dec;
6481   }
6482 };
6483
6484 typedef list<region_t> regions2read_t;
6485 typedef map<BlueStore::BlobRef, regions2read_t> blobs2read_t;
6486
6487 int BlueStore::_do_read(
6488   Collection *c,
6489   OnodeRef o,
6490   uint64_t offset,
6491   size_t length,
6492   bufferlist& bl,
6493   uint32_t op_flags)
6494 {
6495   FUNCTRACE();
6496   int r = 0;
6497
6498   dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
6499            << " size 0x" << o->onode.size << " (" << std::dec
6500            << o->onode.size << ")" << dendl;
6501   bl.clear();
6502
6503   if (offset >= o->onode.size) {
6504     return r;
6505   }
6506
6507   // generally, don't buffer anything, unless the client explicitly requests
6508   // it.
6509   bool buffered = false;
6510   if (op_flags & CEPH_OSD_OP_FLAG_FADVISE_WILLNEED) {
6511     dout(20) << __func__ << " will do buffered read" << dendl;
6512     buffered = true;
6513   } else if (cct->_conf->bluestore_default_buffered_read &&
6514              (op_flags & (CEPH_OSD_OP_FLAG_FADVISE_DONTNEED |
6515                           CEPH_OSD_OP_FLAG_FADVISE_NOCACHE)) == 0) {
6516     dout(20) << __func__ << " defaulting to buffered read" << dendl;
6517     buffered = true;
6518   }
6519
6520   if (offset + length > o->onode.size) {
6521     length = o->onode.size - offset;
6522   }
6523
6524   utime_t start = ceph_clock_now();
6525   o->extent_map.fault_range(db, offset, length);
6526   logger->tinc(l_bluestore_read_onode_meta_lat, ceph_clock_now() - start);
6527   _dump_onode(o);
6528
6529   ready_regions_t ready_regions;
6530
6531   // build blob-wise list to of stuff read (that isn't cached)
6532   blobs2read_t blobs2read;
6533   unsigned left = length;
6534   uint64_t pos = offset;
6535   unsigned num_regions = 0;
6536   auto lp = o->extent_map.seek_lextent(offset);
6537   while (left > 0 && lp != o->extent_map.extent_map.end()) {
6538     if (pos < lp->logical_offset) {
6539       unsigned hole = lp->logical_offset - pos;
6540       if (hole >= left) {
6541         break;
6542       }
6543       dout(30) << __func__ << "  hole 0x" << std::hex << pos << "~" << hole
6544                << std::dec << dendl;
6545       pos += hole;
6546       left -= hole;
6547     }
6548     BlobRef bptr = lp->blob;
6549     unsigned l_off = pos - lp->logical_offset;
6550     unsigned b_off = l_off + lp->blob_offset;
6551     unsigned b_len = std::min(left, lp->length - l_off);
6552
6553     ready_regions_t cache_res;
6554     interval_set<uint32_t> cache_interval;
6555     bptr->shared_blob->bc.read(
6556       bptr->shared_blob->get_cache(), b_off, b_len, cache_res, cache_interval);
6557     dout(20) << __func__ << "  blob " << *bptr << std::hex
6558              << " need 0x" << b_off << "~" << b_len
6559              << " cache has 0x" << cache_interval
6560              << std::dec << dendl;
6561
6562     auto pc = cache_res.begin();
6563     while (b_len > 0) {
6564       unsigned l;
6565       if (pc != cache_res.end() &&
6566           pc->first == b_off) {
6567         l = pc->second.length();
6568         ready_regions[pos].claim(pc->second);
6569         dout(30) << __func__ << "    use cache 0x" << std::hex << pos << ": 0x"
6570                  << b_off << "~" << l << std::dec << dendl;
6571         ++pc;
6572       } else {
6573         l = b_len;
6574         if (pc != cache_res.end()) {
6575           assert(pc->first > b_off);
6576           l = pc->first - b_off;
6577         }
6578         dout(30) << __func__ << "    will read 0x" << std::hex << pos << ": 0x"
6579                  << b_off << "~" << l << std::dec << dendl;
6580         blobs2read[bptr].emplace_back(region_t(pos, b_off, l));
6581         ++num_regions;
6582       }
6583       pos += l;
6584       b_off += l;
6585       left -= l;
6586       b_len -= l;
6587     }
6588     ++lp;
6589   }
6590
6591   // read raw blob data.  use aio if we have >1 blobs to read.
6592   start = ceph_clock_now(); // for the sake of simplicity 
6593                                     // measure the whole block below.
6594                                     // The error isn't that much...
6595   vector<bufferlist> compressed_blob_bls;
6596   IOContext ioc(cct, NULL);
6597   for (auto& p : blobs2read) {
6598     BlobRef bptr = p.first;
6599     dout(20) << __func__ << "  blob " << *bptr << std::hex
6600              << " need " << p.second << std::dec << dendl;
6601     if (bptr->get_blob().is_compressed()) {
6602       // read the whole thing
6603       if (compressed_blob_bls.empty()) {
6604         // ensure we avoid any reallocation on subsequent blobs
6605         compressed_blob_bls.reserve(blobs2read.size());
6606       }
6607       compressed_blob_bls.push_back(bufferlist());
6608       bufferlist& bl = compressed_blob_bls.back();
6609       r = bptr->get_blob().map(
6610         0, bptr->get_blob().get_ondisk_length(),
6611         [&](uint64_t offset, uint64_t length) {
6612           int r;
6613           // use aio if there are more regions to read than those in this blob
6614           if (num_regions > p.second.size()) {
6615             r = bdev->aio_read(offset, length, &bl, &ioc);
6616           } else {
6617             r = bdev->read(offset, length, &bl, &ioc, false);
6618           }
6619           if (r < 0)
6620             return r;
6621           return 0;
6622         });
6623         assert(r == 0);
6624     } else {
6625       // read the pieces
6626       for (auto& reg : p.second) {
6627         // determine how much of the blob to read
6628         uint64_t chunk_size = bptr->get_blob().get_chunk_size(block_size);
6629         reg.r_off = reg.blob_xoffset;
6630         uint64_t r_len = reg.length;
6631         reg.front = reg.r_off % chunk_size;
6632         if (reg.front) {
6633           reg.r_off -= reg.front;
6634           r_len += reg.front;
6635         }
6636         unsigned tail = r_len % chunk_size;
6637         if (tail) {
6638           r_len += chunk_size - tail;
6639         }
6640         dout(20) << __func__ << "    region 0x" << std::hex
6641                  << reg.logical_offset
6642                  << ": 0x" << reg.blob_xoffset << "~" << reg.length
6643                  << " reading 0x" << reg.r_off << "~" << r_len << std::dec
6644                  << dendl;
6645
6646         // read it
6647         r = bptr->get_blob().map(
6648           reg.r_off, r_len,
6649           [&](uint64_t offset, uint64_t length) {
6650             int r;
6651             // use aio if there is more than one region to read
6652             if (num_regions > 1) {
6653               r = bdev->aio_read(offset, length, &reg.bl, &ioc);
6654             } else {
6655               r = bdev->read(offset, length, &reg.bl, &ioc, false);
6656             }
6657             if (r < 0)
6658               return r;
6659             return 0;
6660           });
6661         assert(r == 0);
6662         assert(reg.bl.length() == r_len);
6663       }
6664     }
6665   }
6666   if (ioc.has_pending_aios()) {
6667     bdev->aio_submit(&ioc);
6668     dout(20) << __func__ << " waiting for aio" << dendl;
6669     ioc.aio_wait();
6670   }
6671   logger->tinc(l_bluestore_read_wait_aio_lat, ceph_clock_now() - start);
6672
6673   // enumerate and decompress desired blobs
6674   auto p = compressed_blob_bls.begin();
6675   blobs2read_t::iterator b2r_it = blobs2read.begin();
6676   while (b2r_it != blobs2read.end()) {
6677     BlobRef bptr = b2r_it->first;
6678     dout(20) << __func__ << "  blob " << *bptr << std::hex
6679              << " need 0x" << b2r_it->second << std::dec << dendl;
6680     if (bptr->get_blob().is_compressed()) {
6681       assert(p != compressed_blob_bls.end());
6682       bufferlist& compressed_bl = *p++;
6683       if (_verify_csum(o, &bptr->get_blob(), 0, compressed_bl,
6684                        b2r_it->second.front().logical_offset) < 0) {
6685         return -EIO;
6686       }
6687       bufferlist raw_bl;
6688       r = _decompress(compressed_bl, &raw_bl);
6689       if (r < 0)
6690         return r;
6691       if (buffered) {
6692         bptr->shared_blob->bc.did_read(bptr->shared_blob->get_cache(), 0,
6693                                        raw_bl);
6694       }
6695       for (auto& i : b2r_it->second) {
6696         ready_regions[i.logical_offset].substr_of(
6697           raw_bl, i.blob_xoffset, i.length);
6698       }
6699     } else {
6700       for (auto& reg : b2r_it->second) {
6701         if (_verify_csum(o, &bptr->get_blob(), reg.r_off, reg.bl,
6702                          reg.logical_offset) < 0) {
6703           return -EIO;
6704         }
6705         if (buffered) {
6706           bptr->shared_blob->bc.did_read(bptr->shared_blob->get_cache(),
6707                                          reg.r_off, reg.bl);
6708         }
6709
6710         // prune and keep result
6711         ready_regions[reg.logical_offset].substr_of(
6712           reg.bl, reg.front, reg.length);
6713       }
6714     }
6715     ++b2r_it;
6716   }
6717
6718   // generate a resulting buffer
6719   auto pr = ready_regions.begin();
6720   auto pr_end = ready_regions.end();
6721   pos = 0;
6722   while (pos < length) {
6723     if (pr != pr_end && pr->first == pos + offset) {
6724       dout(30) << __func__ << " assemble 0x" << std::hex << pos
6725                << ": data from 0x" << pr->first << "~" << pr->second.length()
6726                << std::dec << dendl;
6727       pos += pr->second.length();
6728       bl.claim_append(pr->second);
6729       ++pr;
6730     } else {
6731       uint64_t l = length - pos;
6732       if (pr != pr_end) {
6733         assert(pr->first > pos + offset);
6734         l = pr->first - (pos + offset);
6735       }
6736       dout(30) << __func__ << " assemble 0x" << std::hex << pos
6737                << ": zeros for 0x" << (pos + offset) << "~" << l
6738                << std::dec << dendl;
6739       bl.append_zero(l);
6740       pos += l;
6741     }
6742   }
6743   assert(bl.length() == length);
6744   assert(pos == length);
6745   assert(pr == pr_end);
6746   r = bl.length();
6747   return r;
6748 }
6749
6750 int BlueStore::_verify_csum(OnodeRef& o,
6751                             const bluestore_blob_t* blob, uint64_t blob_xoffset,
6752                             const bufferlist& bl,
6753                             uint64_t logical_offset) const
6754 {
6755   int bad;
6756   uint64_t bad_csum;
6757   utime_t start = ceph_clock_now();
6758   int r = blob->verify_csum(blob_xoffset, bl, &bad, &bad_csum);
6759   if (r < 0) {
6760     if (r == -1) {
6761       PExtentVector pex;
6762       blob->map(
6763         bad,
6764         blob->get_csum_chunk_size(),
6765         [&](uint64_t offset, uint64_t length) {
6766           pex.emplace_back(bluestore_pextent_t(offset, length));
6767           return 0;
6768         });
6769       derr << __func__ << " bad "
6770            << Checksummer::get_csum_type_string(blob->csum_type)
6771            << "/0x" << std::hex << blob->get_csum_chunk_size()
6772            << " checksum at blob offset 0x" << bad
6773            << ", got 0x" << bad_csum << ", expected 0x"
6774            << blob->get_csum_item(bad / blob->get_csum_chunk_size()) << std::dec
6775            << ", device location " << pex
6776            << ", logical extent 0x" << std::hex
6777            << (logical_offset + bad - blob_xoffset) << "~"
6778            << blob->get_csum_chunk_size() << std::dec
6779            << ", object " << o->oid
6780            << dendl;
6781     } else {
6782       derr << __func__ << " failed with exit code: " << cpp_strerror(r) << dendl;
6783     }
6784   }
6785   logger->tinc(l_bluestore_csum_lat, ceph_clock_now() - start);
6786   return r;
6787 }
6788
6789 int BlueStore::_decompress(bufferlist& source, bufferlist* result)
6790 {
6791   int r = 0;
6792   utime_t start = ceph_clock_now();
6793   bufferlist::iterator i = source.begin();
6794   bluestore_compression_header_t chdr;
6795   ::decode(chdr, i);
6796   int alg = int(chdr.type);
6797   CompressorRef cp = compressor;
6798   if (!cp || (int)cp->get_type() != alg) {
6799     cp = Compressor::create(cct, alg);
6800   }
6801
6802   if (!cp.get()) {
6803     // if compressor isn't available - error, because cannot return
6804     // decompressed data?
6805     derr << __func__ << " can't load decompressor " << alg << dendl;
6806     r = -EIO;
6807   } else {
6808     r = cp->decompress(i, chdr.length, *result);
6809     if (r < 0) {
6810       derr << __func__ << " decompression failed with exit code " << r << dendl;
6811       r = -EIO;
6812     }
6813   }
6814   logger->tinc(l_bluestore_decompress_lat, ceph_clock_now() - start);
6815   return r;
6816 }
6817
6818 // this stores fiemap into interval_set, other variations
6819 // use it internally
6820 int BlueStore::_fiemap(
6821   CollectionHandle &c_,
6822   const ghobject_t& oid,
6823   uint64_t offset,
6824   size_t length,
6825   interval_set<uint64_t>& destset)
6826 {
6827   Collection *c = static_cast<Collection *>(c_.get());
6828   if (!c->exists)
6829     return -ENOENT;
6830   {
6831     RWLock::RLocker l(c->lock);
6832
6833     OnodeRef o = c->get_onode(oid, false);
6834     if (!o || !o->exists) {
6835       return -ENOENT;
6836     }
6837     _dump_onode(o);
6838
6839     dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
6840              << " size 0x" << o->onode.size << std::dec << dendl;
6841
6842     boost::intrusive::set<Extent>::iterator ep, eend;
6843     if (offset >= o->onode.size)
6844       goto out;
6845
6846     if (offset + length > o->onode.size) {
6847       length = o->onode.size - offset;
6848     }
6849
6850     o->extent_map.fault_range(db, offset, length);
6851     eend = o->extent_map.extent_map.end();
6852     ep = o->extent_map.seek_lextent(offset);
6853     while (length > 0) {
6854       dout(20) << __func__ << " offset " << offset << dendl;
6855       if (ep != eend && ep->logical_offset + ep->length <= offset) {
6856         ++ep;
6857         continue;
6858       }
6859
6860       uint64_t x_len = length;
6861       if (ep != eend && ep->logical_offset <= offset) {
6862         uint64_t x_off = offset - ep->logical_offset;
6863         x_len = MIN(x_len, ep->length - x_off);
6864         dout(30) << __func__ << " lextent 0x" << std::hex << offset << "~"
6865                  << x_len << std::dec << " blob " << ep->blob << dendl;
6866         destset.insert(offset, x_len);
6867         length -= x_len;
6868         offset += x_len;
6869         if (x_off + x_len == ep->length)
6870           ++ep;
6871         continue;
6872       }
6873       if (ep != eend &&
6874           ep->logical_offset > offset &&
6875           ep->logical_offset - offset < x_len) {
6876         x_len = ep->logical_offset - offset;
6877       }
6878       offset += x_len;
6879       length -= x_len;
6880     }
6881   }
6882
6883  out:
6884   dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
6885            << " size = 0x(" << destset << ")" << std::dec << dendl;
6886   return 0;
6887 }
6888
6889 int BlueStore::fiemap(
6890   const coll_t& cid,
6891   const ghobject_t& oid,
6892   uint64_t offset,
6893   size_t len,
6894   bufferlist& bl)
6895 {
6896   CollectionHandle c = _get_collection(cid);
6897   if (!c)
6898     return -ENOENT;
6899   return fiemap(c, oid, offset, len, bl);
6900 }
6901
6902 int BlueStore::fiemap(
6903   CollectionHandle &c_,
6904   const ghobject_t& oid,
6905   uint64_t offset,
6906   size_t length,
6907   bufferlist& bl)
6908 {
6909   interval_set<uint64_t> m;
6910   int r = _fiemap(c_, oid, offset, length, m);
6911   if (r >= 0) {
6912     ::encode(m, bl);
6913   }
6914   return r;
6915 }
6916
6917 int BlueStore::fiemap(
6918   const coll_t& cid,
6919   const ghobject_t& oid,
6920   uint64_t offset,
6921   size_t len,
6922   map<uint64_t, uint64_t>& destmap)
6923 {
6924   CollectionHandle c = _get_collection(cid);
6925   if (!c)
6926     return -ENOENT;
6927   return fiemap(c, oid, offset, len, destmap);
6928 }
6929
6930 int BlueStore::fiemap(
6931   CollectionHandle &c_,
6932   const ghobject_t& oid,
6933   uint64_t offset,
6934   size_t length,
6935   map<uint64_t, uint64_t>& destmap)
6936 {
6937   interval_set<uint64_t> m;
6938   int r = _fiemap(c_, oid, offset, length, m);
6939   if (r >= 0) {
6940     m.move_into(destmap);
6941   }
6942   return r;
6943 }
6944
6945 int BlueStore::getattr(
6946   const coll_t& cid,
6947   const ghobject_t& oid,
6948   const char *name,
6949   bufferptr& value)
6950 {
6951   CollectionHandle c = _get_collection(cid);
6952   if (!c)
6953     return -ENOENT;
6954   return getattr(c, oid, name, value);
6955 }
6956
6957 int BlueStore::getattr(
6958   CollectionHandle &c_,
6959   const ghobject_t& oid,
6960   const char *name,
6961   bufferptr& value)
6962 {
6963   Collection *c = static_cast<Collection *>(c_.get());
6964   dout(15) << __func__ << " " << c->cid << " " << oid << " " << name << dendl;
6965   if (!c->exists)
6966     return -ENOENT;
6967
6968   int r;
6969   {
6970     RWLock::RLocker l(c->lock);
6971     mempool::bluestore_cache_other::string k(name);
6972
6973     OnodeRef o = c->get_onode(oid, false);
6974     if (!o || !o->exists) {
6975       r = -ENOENT;
6976       goto out;
6977     }
6978
6979     if (!o->onode.attrs.count(k)) {
6980       r = -ENODATA;
6981       goto out;
6982     }
6983     value = o->onode.attrs[k];
6984     r = 0;
6985   }
6986  out:
6987   if (r == 0 && _debug_mdata_eio(oid)) {
6988     r = -EIO;
6989     derr << __func__ << " " << c->cid << " " << oid << " INJECT EIO" << dendl;
6990   }
6991   dout(10) << __func__ << " " << c->cid << " " << oid << " " << name
6992            << " = " << r << dendl;
6993   return r;
6994 }
6995
6996
6997 int BlueStore::getattrs(
6998   const coll_t& cid,
6999   const ghobject_t& oid,
7000   map<string,bufferptr>& aset)
7001 {
7002   CollectionHandle c = _get_collection(cid);
7003   if (!c)
7004     return -ENOENT;
7005   return getattrs(c, oid, aset);
7006 }
7007
7008 int BlueStore::getattrs(
7009   CollectionHandle &c_,
7010   const ghobject_t& oid,
7011   map<string,bufferptr>& aset)
7012 {
7013   Collection *c = static_cast<Collection *>(c_.get());
7014   dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
7015   if (!c->exists)
7016     return -ENOENT;
7017
7018   int r;
7019   {
7020     RWLock::RLocker l(c->lock);
7021
7022     OnodeRef o = c->get_onode(oid, false);
7023     if (!o || !o->exists) {
7024       r = -ENOENT;
7025       goto out;
7026     }
7027     for (auto& i : o->onode.attrs) {
7028       aset.emplace(i.first.c_str(), i.second);
7029     }
7030     r = 0;
7031   }
7032
7033  out:
7034   if (r == 0 && _debug_mdata_eio(oid)) {
7035     r = -EIO;
7036     derr << __func__ << " " << c->cid << " " << oid << " INJECT EIO" << dendl;
7037   }
7038   dout(10) << __func__ << " " << c->cid << " " << oid
7039            << " = " << r << dendl;
7040   return r;
7041 }
7042
7043 int BlueStore::list_collections(vector<coll_t>& ls)
7044 {
7045   RWLock::RLocker l(coll_lock);
7046   for (ceph::unordered_map<coll_t, CollectionRef>::iterator p = coll_map.begin();
7047        p != coll_map.end();
7048        ++p)
7049     ls.push_back(p->first);
7050   return 0;
7051 }
7052
7053 bool BlueStore::collection_exists(const coll_t& c)
7054 {
7055   RWLock::RLocker l(coll_lock);
7056   return coll_map.count(c);
7057 }
7058
7059 int BlueStore::collection_empty(const coll_t& cid, bool *empty)
7060 {
7061   dout(15) << __func__ << " " << cid << dendl;
7062   vector<ghobject_t> ls;
7063   ghobject_t next;
7064   int r = collection_list(cid, ghobject_t(), ghobject_t::get_max(), 1,
7065                           &ls, &next);
7066   if (r < 0) {
7067     derr << __func__ << " collection_list returned: " << cpp_strerror(r)
7068          << dendl;
7069     return r;
7070   }
7071   *empty = ls.empty();
7072   dout(10) << __func__ << " " << cid << " = " << (int)(*empty) << dendl;
7073   return 0;
7074 }
7075
7076 int BlueStore::collection_bits(const coll_t& cid)
7077 {
7078   dout(15) << __func__ << " " << cid << dendl;
7079   CollectionRef c = _get_collection(cid);
7080   if (!c)
7081     return -ENOENT;
7082   RWLock::RLocker l(c->lock);
7083   dout(10) << __func__ << " " << cid << " = " << c->cnode.bits << dendl;
7084   return c->cnode.bits;
7085 }
7086
7087 int BlueStore::collection_list(
7088   const coll_t& cid, const ghobject_t& start, const ghobject_t& end, int max,
7089   vector<ghobject_t> *ls, ghobject_t *pnext)
7090 {
7091   CollectionHandle c = _get_collection(cid);
7092   if (!c)
7093     return -ENOENT;
7094   return collection_list(c, start, end, max, ls, pnext);
7095 }
7096
7097 int BlueStore::collection_list(
7098   CollectionHandle &c_, const ghobject_t& start, const ghobject_t& end, int max,
7099   vector<ghobject_t> *ls, ghobject_t *pnext)
7100 {
7101   Collection *c = static_cast<Collection *>(c_.get());
7102   dout(15) << __func__ << " " << c->cid
7103            << " start " << start << " end " << end << " max " << max << dendl;
7104   int r;
7105   {
7106     RWLock::RLocker l(c->lock);
7107     r = _collection_list(c, start, end, max, ls, pnext);
7108   }
7109
7110   dout(10) << __func__ << " " << c->cid
7111     << " start " << start << " end " << end << " max " << max
7112     << " = " << r << ", ls.size() = " << ls->size()
7113     << ", next = " << (pnext ? *pnext : ghobject_t())  << dendl;
7114   return r;
7115 }
7116
7117 int BlueStore::_collection_list(
7118   Collection *c, const ghobject_t& start, const ghobject_t& end, int max,
7119   vector<ghobject_t> *ls, ghobject_t *pnext)
7120 {
7121
7122   if (!c->exists)
7123     return -ENOENT;
7124
7125   int r = 0;
7126   ghobject_t static_next;
7127   KeyValueDB::Iterator it;
7128   string temp_start_key, temp_end_key;
7129   string start_key, end_key;
7130   bool set_next = false;
7131   string pend;
7132   bool temp;
7133
7134   if (!pnext)
7135     pnext = &static_next;
7136
7137   if (start == ghobject_t::get_max() ||
7138     start.hobj.is_max()) {
7139     goto out;
7140   }
7141   get_coll_key_range(c->cid, c->cnode.bits, &temp_start_key, &temp_end_key,
7142     &start_key, &end_key);
7143   dout(20) << __func__
7144     << " range " << pretty_binary_string(temp_start_key)
7145     << " to " << pretty_binary_string(temp_end_key)
7146     << " and " << pretty_binary_string(start_key)
7147     << " to " << pretty_binary_string(end_key)
7148     << " start " << start << dendl;
7149   it = db->get_iterator(PREFIX_OBJ);
7150   if (start == ghobject_t() ||
7151     start.hobj == hobject_t() ||
7152     start == c->cid.get_min_hobj()) {
7153     it->upper_bound(temp_start_key);
7154     temp = true;
7155   } else {
7156     string k;
7157     get_object_key(cct, start, &k);
7158     if (start.hobj.is_temp()) {
7159       temp = true;
7160       assert(k >= temp_start_key && k < temp_end_key);
7161     } else {
7162       temp = false;
7163       assert(k >= start_key && k < end_key);
7164     }
7165     dout(20) << " start from " << pretty_binary_string(k)
7166       << " temp=" << (int)temp << dendl;
7167     it->lower_bound(k);
7168   }
7169   if (end.hobj.is_max()) {
7170     pend = temp ? temp_end_key : end_key;
7171   } else {
7172     get_object_key(cct, end, &end_key);
7173     if (end.hobj.is_temp()) {
7174       if (temp)
7175         pend = end_key;
7176       else
7177         goto out;
7178     } else {
7179       pend = temp ? temp_end_key : end_key;
7180     }
7181   }
7182   dout(20) << __func__ << " pend " << pretty_binary_string(pend) << dendl;
7183   while (true) {
7184     if (!it->valid() || it->key() >= pend) {
7185       if (!it->valid())
7186         dout(20) << __func__ << " iterator not valid (end of db?)" << dendl;
7187       else
7188         dout(20) << __func__ << " key " << pretty_binary_string(it->key())
7189                  << " >= " << end << dendl;
7190       if (temp) {
7191         if (end.hobj.is_temp()) {
7192           break;
7193         }
7194         dout(30) << __func__ << " switch to non-temp namespace" << dendl;
7195         temp = false;
7196         it->upper_bound(start_key);
7197         pend = end_key;
7198         dout(30) << __func__ << " pend " << pretty_binary_string(pend) << dendl;
7199         continue;
7200       }
7201       break;
7202     }
7203     dout(30) << __func__ << " key " << pretty_binary_string(it->key()) << dendl;
7204     if (is_extent_shard_key(it->key())) {
7205       it->next();
7206       continue;
7207     }
7208     ghobject_t oid;
7209     int r = get_key_object(it->key(), &oid);
7210     assert(r == 0);
7211     dout(20) << __func__ << " oid " << oid << " end " << end << dendl;
7212     if (ls->size() >= (unsigned)max) {
7213       dout(20) << __func__ << " reached max " << max << dendl;
7214       *pnext = oid;
7215       set_next = true;
7216       break;
7217     }
7218     ls->push_back(oid);
7219     it->next();
7220   }
7221 out:
7222   if (!set_next) {
7223     *pnext = ghobject_t::get_max();
7224   }
7225
7226   return r;
7227 }
7228
7229 int BlueStore::omap_get(
7230   const coll_t& cid,                ///< [in] Collection containing oid
7231   const ghobject_t &oid,   ///< [in] Object containing omap
7232   bufferlist *header,      ///< [out] omap header
7233   map<string, bufferlist> *out /// < [out] Key to value map
7234   )
7235 {
7236   CollectionHandle c = _get_collection(cid);
7237   if (!c)
7238     return -ENOENT;
7239   return omap_get(c, oid, header, out);
7240 }
7241
7242 int BlueStore::omap_get(
7243   CollectionHandle &c_,    ///< [in] Collection containing oid
7244   const ghobject_t &oid,   ///< [in] Object containing omap
7245   bufferlist *header,      ///< [out] omap header
7246   map<string, bufferlist> *out /// < [out] Key to value map
7247   )
7248 {
7249   Collection *c = static_cast<Collection *>(c_.get());
7250   dout(15) << __func__ << " " << c->get_cid() << " oid " << oid << dendl;
7251   if (!c->exists)
7252     return -ENOENT;
7253   RWLock::RLocker l(c->lock);
7254   int r = 0;
7255   OnodeRef o = c->get_onode(oid, false);
7256   if (!o || !o->exists) {
7257     r = -ENOENT;
7258     goto out;
7259   }
7260   if (!o->onode.has_omap())
7261     goto out;
7262   o->flush();
7263   {
7264     KeyValueDB::Iterator it = db->get_iterator(PREFIX_OMAP);
7265     string head, tail;
7266     get_omap_header(o->onode.nid, &head);
7267     get_omap_tail(o->onode.nid, &tail);
7268     it->lower_bound(head);
7269     while (it->valid()) {
7270       if (it->key() == head) {
7271         dout(30) << __func__ << "  got header" << dendl;
7272         *header = it->value();
7273       } else if (it->key() >= tail) {
7274         dout(30) << __func__ << "  reached tail" << dendl;
7275         break;
7276       } else {
7277         string user_key;
7278         decode_omap_key(it->key(), &user_key);
7279         dout(30) << __func__ << "  got " << pretty_binary_string(it->key())
7280                  << " -> " << user_key << dendl;
7281         (*out)[user_key] = it->value();
7282       }
7283       it->next();
7284     }
7285   }
7286  out:
7287   dout(10) << __func__ << " " << c->get_cid() << " oid " << oid << " = " << r
7288            << dendl;
7289   return r;
7290 }
7291
7292 int BlueStore::omap_get_header(
7293   const coll_t& cid,                ///< [in] Collection containing oid
7294   const ghobject_t &oid,   ///< [in] Object containing omap
7295   bufferlist *header,      ///< [out] omap header
7296   bool allow_eio ///< [in] don't assert on eio
7297   )
7298 {
7299   CollectionHandle c = _get_collection(cid);
7300   if (!c)
7301     return -ENOENT;
7302   return omap_get_header(c, oid, header, allow_eio);
7303 }
7304
7305 int BlueStore::omap_get_header(
7306   CollectionHandle &c_,                ///< [in] Collection containing oid
7307   const ghobject_t &oid,   ///< [in] Object containing omap
7308   bufferlist *header,      ///< [out] omap header
7309   bool allow_eio ///< [in] don't assert on eio
7310   )
7311 {
7312   Collection *c = static_cast<Collection *>(c_.get());
7313   dout(15) << __func__ << " " << c->get_cid() << " oid " << oid << dendl;
7314   if (!c->exists)
7315     return -ENOENT;
7316   RWLock::RLocker l(c->lock);
7317   int r = 0;
7318   OnodeRef o = c->get_onode(oid, false);
7319   if (!o || !o->exists) {
7320     r = -ENOENT;
7321     goto out;
7322   }
7323   if (!o->onode.has_omap())
7324     goto out;
7325   o->flush();
7326   {
7327     string head;
7328     get_omap_header(o->onode.nid, &head);
7329     if (db->get(PREFIX_OMAP, head, header) >= 0) {
7330       dout(30) << __func__ << "  got header" << dendl;
7331     } else {
7332       dout(30) << __func__ << "  no header" << dendl;
7333     }
7334   }
7335  out:
7336   dout(10) << __func__ << " " << c->get_cid() << " oid " << oid << " = " << r
7337            << dendl;
7338   return r;
7339 }
7340
7341 int BlueStore::omap_get_keys(
7342   const coll_t& cid,              ///< [in] Collection containing oid
7343   const ghobject_t &oid, ///< [in] Object containing omap
7344   set<string> *keys      ///< [out] Keys defined on oid
7345   )
7346 {
7347   CollectionHandle c = _get_collection(cid);
7348   if (!c)
7349     return -ENOENT;
7350   return omap_get_keys(c, oid, keys);
7351 }
7352
7353 int BlueStore::omap_get_keys(
7354   CollectionHandle &c_,              ///< [in] Collection containing oid
7355   const ghobject_t &oid, ///< [in] Object containing omap
7356   set<string> *keys      ///< [out] Keys defined on oid
7357   )
7358 {
7359   Collection *c = static_cast<Collection *>(c_.get());
7360   dout(15) << __func__ << " " << c->get_cid() << " oid " << oid << dendl;
7361   if (!c->exists)
7362     return -ENOENT;
7363   RWLock::RLocker l(c->lock);
7364   int r = 0;
7365   OnodeRef o = c->get_onode(oid, false);
7366   if (!o || !o->exists) {
7367     r = -ENOENT;
7368     goto out;
7369   }
7370   if (!o->onode.has_omap())
7371     goto out;
7372   o->flush();
7373   {
7374     KeyValueDB::Iterator it = db->get_iterator(PREFIX_OMAP);
7375     string head, tail;
7376     get_omap_key(o->onode.nid, string(), &head);
7377     get_omap_tail(o->onode.nid, &tail);
7378     it->lower_bound(head);
7379     while (it->valid()) {
7380       if (it->key() >= tail) {
7381         dout(30) << __func__ << "  reached tail" << dendl;
7382         break;
7383       }
7384       string user_key;
7385       decode_omap_key(it->key(), &user_key);
7386       dout(30) << __func__ << "  got " << pretty_binary_string(it->key())
7387                << " -> " << user_key << dendl;
7388       keys->insert(user_key);
7389       it->next();
7390     }
7391   }
7392  out:
7393   dout(10) << __func__ << " " << c->get_cid() << " oid " << oid << " = " << r
7394            << dendl;
7395   return r;
7396 }
7397
7398 int BlueStore::omap_get_values(
7399   const coll_t& cid,                    ///< [in] Collection containing oid
7400   const ghobject_t &oid,       ///< [in] Object containing omap
7401   const set<string> &keys,     ///< [in] Keys to get
7402   map<string, bufferlist> *out ///< [out] Returned keys and values
7403   )
7404 {
7405   CollectionHandle c = _get_collection(cid);
7406   if (!c)
7407     return -ENOENT;
7408   return omap_get_values(c, oid, keys, out);
7409 }
7410
7411 int BlueStore::omap_get_values(
7412   CollectionHandle &c_,        ///< [in] Collection containing oid
7413   const ghobject_t &oid,       ///< [in] Object containing omap
7414   const set<string> &keys,     ///< [in] Keys to get
7415   map<string, bufferlist> *out ///< [out] Returned keys and values
7416   )
7417 {
7418   Collection *c = static_cast<Collection *>(c_.get());
7419   dout(15) << __func__ << " " << c->get_cid() << " oid " << oid << dendl;
7420   if (!c->exists)
7421     return -ENOENT;
7422   RWLock::RLocker l(c->lock);
7423   int r = 0;
7424   string final_key;
7425   OnodeRef o = c->get_onode(oid, false);
7426   if (!o || !o->exists) {
7427     r = -ENOENT;
7428     goto out;
7429   }
7430   if (!o->onode.has_omap())
7431     goto out;
7432   o->flush();
7433   _key_encode_u64(o->onode.nid, &final_key);
7434   final_key.push_back('.');
7435   for (set<string>::const_iterator p = keys.begin(); p != keys.end(); ++p) {
7436     final_key.resize(9); // keep prefix
7437     final_key += *p;
7438     bufferlist val;
7439     if (db->get(PREFIX_OMAP, final_key, &val) >= 0) {
7440       dout(30) << __func__ << "  got " << pretty_binary_string(final_key)
7441                << " -> " << *p << dendl;
7442       out->insert(make_pair(*p, val));
7443     }
7444   }
7445  out:
7446   dout(10) << __func__ << " " << c->get_cid() << " oid " << oid << " = " << r
7447            << dendl;
7448   return r;
7449 }
7450
7451 int BlueStore::omap_check_keys(
7452   const coll_t& cid,                ///< [in] Collection containing oid
7453   const ghobject_t &oid,   ///< [in] Object containing omap
7454   const set<string> &keys, ///< [in] Keys to check
7455   set<string> *out         ///< [out] Subset of keys defined on oid
7456   )
7457 {
7458   CollectionHandle c = _get_collection(cid);
7459   if (!c)
7460     return -ENOENT;
7461   return omap_check_keys(c, oid, keys, out);
7462 }
7463
7464 int BlueStore::omap_check_keys(
7465   CollectionHandle &c_,    ///< [in] Collection containing oid
7466   const ghobject_t &oid,   ///< [in] Object containing omap
7467   const set<string> &keys, ///< [in] Keys to check
7468   set<string> *out         ///< [out] Subset of keys defined on oid
7469   )
7470 {
7471   Collection *c = static_cast<Collection *>(c_.get());
7472   dout(15) << __func__ << " " << c->get_cid() << " oid " << oid << dendl;
7473   if (!c->exists)
7474     return -ENOENT;
7475   RWLock::RLocker l(c->lock);
7476   int r = 0;
7477   string final_key;
7478   OnodeRef o = c->get_onode(oid, false);
7479   if (!o || !o->exists) {
7480     r = -ENOENT;
7481     goto out;
7482   }
7483   if (!o->onode.has_omap())
7484     goto out;
7485   o->flush();
7486   _key_encode_u64(o->onode.nid, &final_key);
7487   final_key.push_back('.');
7488   for (set<string>::const_iterator p = keys.begin(); p != keys.end(); ++p) {
7489     final_key.resize(9); // keep prefix
7490     final_key += *p;
7491     bufferlist val;
7492     if (db->get(PREFIX_OMAP, final_key, &val) >= 0) {
7493       dout(30) << __func__ << "  have " << pretty_binary_string(final_key)
7494                << " -> " << *p << dendl;
7495       out->insert(*p);
7496     } else {
7497       dout(30) << __func__ << "  miss " << pretty_binary_string(final_key)
7498                << " -> " << *p << dendl;
7499     }
7500   }
7501  out:
7502   dout(10) << __func__ << " " << c->get_cid() << " oid " << oid << " = " << r
7503            << dendl;
7504   return r;
7505 }
7506
7507 ObjectMap::ObjectMapIterator BlueStore::get_omap_iterator(
7508   const coll_t& cid,              ///< [in] collection
7509   const ghobject_t &oid  ///< [in] object
7510   )
7511 {
7512   CollectionHandle c = _get_collection(cid);
7513   if (!c) {
7514     dout(10) << __func__ << " " << cid << "doesn't exist" <<dendl;
7515     return ObjectMap::ObjectMapIterator();
7516   }
7517   return get_omap_iterator(c, oid);
7518 }
7519
7520 ObjectMap::ObjectMapIterator BlueStore::get_omap_iterator(
7521   CollectionHandle &c_,              ///< [in] collection
7522   const ghobject_t &oid  ///< [in] object
7523   )
7524 {
7525   Collection *c = static_cast<Collection *>(c_.get());
7526   dout(10) << __func__ << " " << c->get_cid() << " " << oid << dendl;
7527   if (!c->exists) {
7528     return ObjectMap::ObjectMapIterator();
7529   }
7530   RWLock::RLocker l(c->lock);
7531   OnodeRef o = c->get_onode(oid, false);
7532   if (!o || !o->exists) {
7533     dout(10) << __func__ << " " << oid << "doesn't exist" <<dendl;
7534     return ObjectMap::ObjectMapIterator();
7535   }
7536   o->flush();
7537   dout(10) << __func__ << " has_omap = " << (int)o->onode.has_omap() <<dendl;
7538   KeyValueDB::Iterator it = db->get_iterator(PREFIX_OMAP);
7539   return ObjectMap::ObjectMapIterator(new OmapIteratorImpl(c, o, it));
7540 }
7541
7542 // -----------------
7543 // write helpers
7544
7545 void BlueStore::_prepare_ondisk_format_super(KeyValueDB::Transaction& t)
7546 {
7547   dout(10) << __func__ << " ondisk_format " << ondisk_format
7548            << " min_compat_ondisk_format " << min_compat_ondisk_format
7549            << dendl;
7550   assert(ondisk_format == latest_ondisk_format);
7551   {
7552     bufferlist bl;
7553     ::encode(ondisk_format, bl);
7554     t->set(PREFIX_SUPER, "ondisk_format", bl);
7555   }
7556   {
7557     bufferlist bl;
7558     ::encode(min_compat_ondisk_format, bl);
7559     t->set(PREFIX_SUPER, "min_compat_ondisk_format", bl);
7560   }
7561 }
7562
7563 int BlueStore::_open_super_meta()
7564 {
7565   // nid
7566   {
7567     nid_max = 0;
7568     bufferlist bl;
7569     db->get(PREFIX_SUPER, "nid_max", &bl);
7570     bufferlist::iterator p = bl.begin();
7571     try {
7572       uint64_t v;
7573       ::decode(v, p);
7574       nid_max = v;
7575     } catch (buffer::error& e) {
7576       derr << __func__ << " unable to read nid_max" << dendl;
7577       return -EIO;
7578     }
7579     dout(10) << __func__ << " old nid_max " << nid_max << dendl;
7580     nid_last = nid_max.load();
7581   }
7582
7583   // blobid
7584   {
7585     blobid_max = 0;
7586     bufferlist bl;
7587     db->get(PREFIX_SUPER, "blobid_max", &bl);
7588     bufferlist::iterator p = bl.begin();
7589     try {
7590       uint64_t v;
7591       ::decode(v, p);
7592       blobid_max = v;
7593     } catch (buffer::error& e) {
7594       derr << __func__ << " unable to read blobid_max" << dendl;
7595       return -EIO;
7596     }
7597     dout(10) << __func__ << " old blobid_max " << blobid_max << dendl;
7598     blobid_last = blobid_max.load();
7599   }
7600
7601   // freelist
7602   {
7603     bufferlist bl;
7604     db->get(PREFIX_SUPER, "freelist_type", &bl);
7605     if (bl.length()) {
7606       freelist_type = std::string(bl.c_str(), bl.length());
7607       dout(10) << __func__ << " freelist_type " << freelist_type << dendl;
7608     } else {
7609       assert("Not Support extent freelist manager" == 0);
7610     }
7611   }
7612
7613   // bluefs alloc
7614   if (cct->_conf->bluestore_bluefs) {
7615     bluefs_extents.clear();
7616     bufferlist bl;
7617     db->get(PREFIX_SUPER, "bluefs_extents", &bl);
7618     bufferlist::iterator p = bl.begin();
7619     try {
7620       ::decode(bluefs_extents, p);
7621     }
7622     catch (buffer::error& e) {
7623       derr << __func__ << " unable to read bluefs_extents" << dendl;
7624       return -EIO;
7625     }
7626     dout(10) << __func__ << " bluefs_extents 0x" << std::hex << bluefs_extents
7627              << std::dec << dendl;
7628   }
7629
7630   // ondisk format
7631   int32_t compat_ondisk_format = 0;
7632   {
7633     bufferlist bl;
7634     int r = db->get(PREFIX_SUPER, "ondisk_format", &bl);
7635     if (r < 0) {
7636       // base case: kraken bluestore is v1 and readable by v1
7637       dout(20) << __func__ << " missing ondisk_format; assuming kraken"
7638                << dendl;
7639       ondisk_format = 1;
7640       compat_ondisk_format = 1;
7641     } else {
7642       auto p = bl.begin();
7643       try {
7644         ::decode(ondisk_format, p);
7645       } catch (buffer::error& e) {
7646         derr << __func__ << " unable to read ondisk_format" << dendl;
7647         return -EIO;
7648       }
7649       bl.clear();
7650       {
7651         r = db->get(PREFIX_SUPER, "min_compat_ondisk_format", &bl);
7652         assert(!r);
7653         auto p = bl.begin();
7654         try {
7655           ::decode(compat_ondisk_format, p);
7656         } catch (buffer::error& e) {
7657           derr << __func__ << " unable to read compat_ondisk_format" << dendl;
7658           return -EIO;
7659         }
7660       }
7661     }
7662     dout(10) << __func__ << " ondisk_format " << ondisk_format
7663              << " compat_ondisk_format " << compat_ondisk_format
7664              << dendl;
7665   }
7666
7667   if (latest_ondisk_format < compat_ondisk_format) {
7668     derr << __func__ << " compat_ondisk_format is "
7669          << compat_ondisk_format << " but we only understand version "
7670          << latest_ondisk_format << dendl;
7671     return -EPERM;
7672   }
7673   if (ondisk_format < latest_ondisk_format) {
7674     int r = _upgrade_super();
7675     if (r < 0) {
7676       return r;
7677     }
7678   }
7679
7680   {
7681     bufferlist bl;
7682     db->get(PREFIX_SUPER, "min_alloc_size", &bl);
7683     auto p = bl.begin();
7684     try {
7685       uint64_t val;
7686       ::decode(val, p);
7687       min_alloc_size = val;
7688       min_alloc_size_order = ctz(val);
7689       assert(min_alloc_size == 1u << min_alloc_size_order);
7690     } catch (buffer::error& e) {
7691       derr << __func__ << " unable to read min_alloc_size" << dendl;
7692       return -EIO;
7693     }
7694     dout(10) << __func__ << " min_alloc_size 0x" << std::hex << min_alloc_size
7695              << std::dec << dendl;
7696   }
7697   _open_statfs();
7698   _set_alloc_sizes();
7699   _set_throttle_params();
7700
7701   _set_csum();
7702   _set_compression();
7703   _set_blob_size();
7704
7705   return 0;
7706 }
7707
7708 int BlueStore::_upgrade_super()
7709 {
7710   dout(1) << __func__ << " from " << ondisk_format << ", latest "
7711           << latest_ondisk_format << dendl;
7712   assert(ondisk_format > 0);
7713   assert(ondisk_format < latest_ondisk_format);
7714
7715   if (ondisk_format == 1) {
7716     // changes:
7717     // - super: added ondisk_format
7718     // - super: added min_readable_ondisk_format
7719     // - super: added min_compat_ondisk_format
7720     // - super: added min_alloc_size
7721     // - super: removed min_min_alloc_size
7722     KeyValueDB::Transaction t = db->get_transaction();
7723     {
7724       bufferlist bl;
7725       db->get(PREFIX_SUPER, "min_min_alloc_size", &bl);
7726       auto p = bl.begin();
7727       try {
7728         uint64_t val;
7729         ::decode(val, p);
7730         min_alloc_size = val;
7731       } catch (buffer::error& e) {
7732         derr << __func__ << " failed to read min_min_alloc_size" << dendl;
7733         return -EIO;
7734       }
7735       t->set(PREFIX_SUPER, "min_alloc_size", bl);
7736       t->rmkey(PREFIX_SUPER, "min_min_alloc_size");
7737     }
7738     ondisk_format = 2;
7739     _prepare_ondisk_format_super(t);
7740     int r = db->submit_transaction_sync(t);
7741     assert(r == 0);
7742   }
7743
7744   // done
7745   dout(1) << __func__ << " done" << dendl;
7746   return 0;
7747 }
7748
7749 void BlueStore::_assign_nid(TransContext *txc, OnodeRef o)
7750 {
7751   if (o->onode.nid) {
7752     assert(o->exists);
7753     return;
7754   }
7755   uint64_t nid = ++nid_last;
7756   dout(20) << __func__ << " " << nid << dendl;
7757   o->onode.nid = nid;
7758   txc->last_nid = nid;
7759   o->exists = true;
7760 }
7761
7762 uint64_t BlueStore::_assign_blobid(TransContext *txc)
7763 {
7764   uint64_t bid = ++blobid_last;
7765   dout(20) << __func__ << " " << bid << dendl;
7766   txc->last_blobid = bid;
7767   return bid;
7768 }
7769
7770 void BlueStore::get_db_statistics(Formatter *f)
7771 {
7772   db->get_statistics(f);
7773 }
7774
7775 BlueStore::TransContext *BlueStore::_txc_create(OpSequencer *osr)
7776 {
7777   TransContext *txc = new TransContext(cct, osr);
7778   txc->t = db->get_transaction();
7779   osr->queue_new(txc);
7780   dout(20) << __func__ << " osr " << osr << " = " << txc
7781            << " seq " << txc->seq << dendl;
7782   return txc;
7783 }
7784
7785 void BlueStore::_txc_calc_cost(TransContext *txc)
7786 {
7787   // this is about the simplest model for transaction cost you can
7788   // imagine.  there is some fixed overhead cost by saying there is a
7789   // minimum of one "io".  and then we have some cost per "io" that is
7790   // a configurable (with different hdd and ssd defaults), and add
7791   // that to the bytes value.
7792   int ios = 1;  // one "io" for the kv commit
7793   for (auto& p : txc->ioc.pending_aios) {
7794     ios += p.iov.size();
7795   }
7796   auto cost = throttle_cost_per_io.load();
7797   txc->cost = ios * cost + txc->bytes;
7798   dout(10) << __func__ << " " << txc << " cost " << txc->cost << " ("
7799            << ios << " ios * " << cost << " + " << txc->bytes
7800            << " bytes)" << dendl;
7801 }
7802
7803 void BlueStore::_txc_update_store_statfs(TransContext *txc)
7804 {
7805   if (txc->statfs_delta.is_empty())
7806     return;
7807
7808   logger->inc(l_bluestore_allocated, txc->statfs_delta.allocated());
7809   logger->inc(l_bluestore_stored, txc->statfs_delta.stored());
7810   logger->inc(l_bluestore_compressed, txc->statfs_delta.compressed());
7811   logger->inc(l_bluestore_compressed_allocated, txc->statfs_delta.compressed_allocated());
7812   logger->inc(l_bluestore_compressed_original, txc->statfs_delta.compressed_original());
7813
7814   {
7815     std::lock_guard<std::mutex> l(vstatfs_lock);
7816     vstatfs += txc->statfs_delta;
7817   }
7818
7819   bufferlist bl;
7820   txc->statfs_delta.encode(bl);
7821
7822   txc->t->merge(PREFIX_STAT, "bluestore_statfs", bl);
7823   txc->statfs_delta.reset();
7824 }
7825
7826 void BlueStore::_txc_state_proc(TransContext *txc)
7827 {
7828   while (true) {
7829     dout(10) << __func__ << " txc " << txc
7830              << " " << txc->get_state_name() << dendl;
7831     switch (txc->state) {
7832     case TransContext::STATE_PREPARE:
7833       txc->log_state_latency(logger, l_bluestore_state_prepare_lat);
7834       if (txc->ioc.has_pending_aios()) {
7835         txc->state = TransContext::STATE_AIO_WAIT;
7836         txc->had_ios = true;
7837         _txc_aio_submit(txc);
7838         return;
7839       }
7840       // ** fall-thru **
7841
7842     case TransContext::STATE_AIO_WAIT:
7843       txc->log_state_latency(logger, l_bluestore_state_aio_wait_lat);
7844       _txc_finish_io(txc);  // may trigger blocked txc's too
7845       return;
7846
7847     case TransContext::STATE_IO_DONE:
7848       //assert(txc->osr->qlock.is_locked());  // see _txc_finish_io
7849       if (txc->had_ios) {
7850         ++txc->osr->txc_with_unstable_io;
7851       }
7852       txc->log_state_latency(logger, l_bluestore_state_io_done_lat);
7853       txc->state = TransContext::STATE_KV_QUEUED;
7854       if (cct->_conf->bluestore_sync_submit_transaction) {
7855         if (txc->last_nid >= nid_max ||
7856             txc->last_blobid >= blobid_max) {
7857           dout(20) << __func__
7858                    << " last_{nid,blobid} exceeds max, submit via kv thread"
7859                    << dendl;
7860         } else if (txc->osr->kv_committing_serially) {
7861           dout(20) << __func__ << " prior txc submitted via kv thread, us too"
7862                    << dendl;
7863           // note: this is starvation-prone.  once we have a txc in a busy
7864           // sequencer that is committing serially it is possible to keep
7865           // submitting new transactions fast enough that we get stuck doing
7866           // so.  the alternative is to block here... fixme?
7867         } else if (txc->osr->txc_with_unstable_io) {
7868           dout(20) << __func__ << " prior txc(s) with unstable ios "
7869                    << txc->osr->txc_with_unstable_io.load() << dendl;
7870         } else if (cct->_conf->bluestore_debug_randomize_serial_transaction &&
7871                    rand() % cct->_conf->bluestore_debug_randomize_serial_transaction
7872                    == 0) {
7873           dout(20) << __func__ << " DEBUG randomly forcing submit via kv thread"
7874                    << dendl;
7875         } else {
7876           txc->state = TransContext::STATE_KV_SUBMITTED;
7877           int r = cct->_conf->bluestore_debug_omit_kv_commit ? 0 : db->submit_transaction(txc->t);
7878           assert(r == 0);
7879           _txc_applied_kv(txc);
7880         }
7881       }
7882       {
7883         std::lock_guard<std::mutex> l(kv_lock);
7884         kv_queue.push_back(txc);
7885         kv_cond.notify_one();
7886         if (txc->state != TransContext::STATE_KV_SUBMITTED) {
7887           kv_queue_unsubmitted.push_back(txc);
7888           ++txc->osr->kv_committing_serially;
7889         }
7890         if (txc->had_ios)
7891           kv_ios++;
7892         kv_throttle_costs += txc->cost;
7893       }
7894       return;
7895     case TransContext::STATE_KV_SUBMITTED:
7896       txc->log_state_latency(logger, l_bluestore_state_kv_committing_lat);
7897       txc->state = TransContext::STATE_KV_DONE;
7898       _txc_committed_kv(txc);
7899       // ** fall-thru **
7900
7901     case TransContext::STATE_KV_DONE:
7902       txc->log_state_latency(logger, l_bluestore_state_kv_done_lat);
7903       if (txc->deferred_txn) {
7904         txc->state = TransContext::STATE_DEFERRED_QUEUED;
7905         _deferred_queue(txc);
7906         return;
7907       }
7908       txc->state = TransContext::STATE_FINISHING;
7909       break;
7910
7911     case TransContext::STATE_DEFERRED_CLEANUP:
7912       txc->log_state_latency(logger, l_bluestore_state_deferred_cleanup_lat);
7913       txc->state = TransContext::STATE_FINISHING;
7914       // ** fall-thru **
7915
7916     case TransContext::STATE_FINISHING:
7917       txc->log_state_latency(logger, l_bluestore_state_finishing_lat);
7918       _txc_finish(txc);
7919       return;
7920
7921     default:
7922       derr << __func__ << " unexpected txc " << txc
7923            << " state " << txc->get_state_name() << dendl;
7924       assert(0 == "unexpected txc state");
7925       return;
7926     }
7927   }
7928 }
7929
7930 void BlueStore::_txc_finish_io(TransContext *txc)
7931 {
7932   dout(20) << __func__ << " " << txc << dendl;
7933
7934   /*
7935    * we need to preserve the order of kv transactions,
7936    * even though aio will complete in any order.
7937    */
7938
7939   OpSequencer *osr = txc->osr.get();
7940   std::lock_guard<std::mutex> l(osr->qlock);
7941   txc->state = TransContext::STATE_IO_DONE;
7942
7943   // release aio contexts (including pinned buffers).
7944   txc->ioc.running_aios.clear();
7945
7946   OpSequencer::q_list_t::iterator p = osr->q.iterator_to(*txc);
7947   while (p != osr->q.begin()) {
7948     --p;
7949     if (p->state < TransContext::STATE_IO_DONE) {
7950       dout(20) << __func__ << " " << txc << " blocked by " << &*p << " "
7951                << p->get_state_name() << dendl;
7952       return;
7953     }
7954     if (p->state > TransContext::STATE_IO_DONE) {
7955       ++p;
7956       break;
7957     }
7958   }
7959   do {
7960     _txc_state_proc(&*p++);
7961   } while (p != osr->q.end() &&
7962            p->state == TransContext::STATE_IO_DONE);
7963
7964   if (osr->kv_submitted_waiters &&
7965       osr->_is_all_kv_submitted()) {
7966     osr->qcond.notify_all();
7967   }
7968 }
7969
7970 void BlueStore::_txc_write_nodes(TransContext *txc, KeyValueDB::Transaction t)
7971 {
7972   dout(20) << __func__ << " txc " << txc
7973            << " onodes " << txc->onodes
7974            << " shared_blobs " << txc->shared_blobs
7975            << dendl;
7976
7977   // finalize onodes
7978   for (auto o : txc->onodes) {
7979     // finalize extent_map shards
7980     o->extent_map.update(t, false);
7981     if (o->extent_map.needs_reshard()) {
7982       o->extent_map.reshard(db, t);
7983       o->extent_map.update(t, true);
7984       if (o->extent_map.needs_reshard()) {
7985         dout(20) << __func__ << " warning: still wants reshard, check options?"
7986                  << dendl;
7987         o->extent_map.clear_needs_reshard();
7988       }
7989       logger->inc(l_bluestore_onode_reshard);
7990     }
7991
7992     // bound encode
7993     size_t bound = 0;
7994     denc(o->onode, bound);
7995     o->extent_map.bound_encode_spanning_blobs(bound);
7996     if (o->onode.extent_map_shards.empty()) {
7997       denc(o->extent_map.inline_bl, bound);
7998     }
7999
8000     // encode
8001     bufferlist bl;
8002     unsigned onode_part, blob_part, extent_part;
8003     {
8004       auto p = bl.get_contiguous_appender(bound, true);
8005       denc(o->onode, p);
8006       onode_part = p.get_logical_offset();
8007       o->extent_map.encode_spanning_blobs(p);
8008       blob_part = p.get_logical_offset() - onode_part;
8009       if (o->onode.extent_map_shards.empty()) {
8010         denc(o->extent_map.inline_bl, p);
8011       }
8012       extent_part = p.get_logical_offset() - onode_part - blob_part;
8013     }
8014
8015     dout(20) << "  onode " << o->oid << " is " << bl.length()
8016              << " (" << onode_part << " bytes onode + "
8017              << blob_part << " bytes spanning blobs + "
8018              << extent_part << " bytes inline extents)"
8019              << dendl;
8020     t->set(PREFIX_OBJ, o->key.c_str(), o->key.size(), bl);
8021     o->flushing_count++;
8022   }
8023
8024   // objects we modified but didn't affect the onode
8025   auto p = txc->modified_objects.begin();
8026   while (p != txc->modified_objects.end()) {
8027     if (txc->onodes.count(*p) == 0) {
8028       (*p)->flushing_count++;
8029       ++p;
8030     } else {
8031       // remove dups with onodes list to avoid problems in _txc_finish
8032       p = txc->modified_objects.erase(p);
8033     }
8034   }
8035
8036   // finalize shared_blobs
8037   for (auto sb : txc->shared_blobs) {
8038     string key;
8039     auto sbid = sb->get_sbid();
8040     get_shared_blob_key(sbid, &key);
8041     if (sb->persistent->empty()) {
8042       dout(20) << "  shared_blob 0x" << std::hex << sbid << std::dec
8043                << " is empty" << dendl;
8044       t->rmkey(PREFIX_SHARED_BLOB, key);
8045     } else {
8046       bufferlist bl;
8047       ::encode(*(sb->persistent), bl);
8048       dout(20) << "  shared_blob 0x" << std::hex << sbid << std::dec
8049                << " is " << bl.length() << " " << *sb << dendl;
8050       t->set(PREFIX_SHARED_BLOB, key, bl);
8051     }
8052   }
8053 }
8054
8055 void BlueStore::BSPerfTracker::update_from_perfcounters(
8056   PerfCounters &logger)
8057 {
8058   os_commit_latency.consume_next(
8059     logger.get_tavg_ms(
8060       l_bluestore_commit_lat));
8061   os_apply_latency.consume_next(
8062     logger.get_tavg_ms(
8063       l_bluestore_commit_lat));
8064 }
8065
8066 void BlueStore::_txc_finalize_kv(TransContext *txc, KeyValueDB::Transaction t)
8067 {
8068   dout(20) << __func__ << " txc " << txc << std::hex
8069            << " allocated 0x" << txc->allocated
8070            << " released 0x" << txc->released
8071            << std::dec << dendl;
8072
8073   // We have to handle the case where we allocate *and* deallocate the
8074   // same region in this transaction.  The freelist doesn't like that.
8075   // (Actually, the only thing that cares is the BitmapFreelistManager
8076   // debug check. But that's important.)
8077   interval_set<uint64_t> tmp_allocated, tmp_released;
8078   interval_set<uint64_t> *pallocated = &txc->allocated;
8079   interval_set<uint64_t> *preleased = &txc->released;
8080   if (!txc->allocated.empty() && !txc->released.empty()) {
8081     interval_set<uint64_t> overlap;
8082     overlap.intersection_of(txc->allocated, txc->released);
8083     if (!overlap.empty()) {
8084       tmp_allocated = txc->allocated;
8085       tmp_allocated.subtract(overlap);
8086       tmp_released = txc->released;
8087       tmp_released.subtract(overlap);
8088       dout(20) << __func__ << "  overlap 0x" << std::hex << overlap
8089                << ", new allocated 0x" << tmp_allocated
8090                << " released 0x" << tmp_released << std::dec
8091                << dendl;
8092       pallocated = &tmp_allocated;
8093       preleased = &tmp_released;
8094     }
8095   }
8096
8097   // update freelist with non-overlap sets
8098   for (interval_set<uint64_t>::iterator p = pallocated->begin();
8099        p != pallocated->end();
8100        ++p) {
8101     fm->allocate(p.get_start(), p.get_len(), t);
8102   }
8103   for (interval_set<uint64_t>::iterator p = preleased->begin();
8104        p != preleased->end();
8105        ++p) {
8106     dout(20) << __func__ << " release 0x" << std::hex << p.get_start()
8107              << "~" << p.get_len() << std::dec << dendl;
8108     fm->release(p.get_start(), p.get_len(), t);
8109   }
8110
8111   _txc_update_store_statfs(txc);
8112 }
8113
8114 void BlueStore::_txc_applied_kv(TransContext *txc)
8115 {
8116   for (auto ls : { &txc->onodes, &txc->modified_objects }) {
8117     for (auto& o : *ls) {
8118       dout(20) << __func__ << " onode " << o << " had " << o->flushing_count
8119                << dendl;
8120       if (--o->flushing_count == 0) {
8121         std::lock_guard<std::mutex> l(o->flush_lock);
8122         o->flush_cond.notify_all();
8123       }
8124     }
8125   }
8126 }
8127
8128 void BlueStore::_txc_committed_kv(TransContext *txc)
8129 {
8130   dout(20) << __func__ << " txc " << txc << dendl;
8131
8132   // warning: we're calling onreadable_sync inside the sequencer lock
8133   if (txc->onreadable_sync) {
8134     txc->onreadable_sync->complete(0);
8135     txc->onreadable_sync = NULL;
8136   }
8137   unsigned n = txc->osr->parent->shard_hint.hash_to_shard(m_finisher_num);
8138   if (txc->oncommit) {
8139     logger->tinc(l_bluestore_commit_lat, ceph_clock_now() - txc->start);
8140     finishers[n]->queue(txc->oncommit);
8141     txc->oncommit = NULL;
8142   }
8143   if (txc->onreadable) {
8144     finishers[n]->queue(txc->onreadable);
8145     txc->onreadable = NULL;
8146   }
8147
8148   if (!txc->oncommits.empty()) {
8149     finishers[n]->queue(txc->oncommits);
8150   }
8151 }
8152
8153 void BlueStore::_txc_finish(TransContext *txc)
8154 {
8155   dout(20) << __func__ << " " << txc << " onodes " << txc->onodes << dendl;
8156   assert(txc->state == TransContext::STATE_FINISHING);
8157
8158   for (auto& sb : txc->shared_blobs_written) {
8159     sb->bc.finish_write(sb->get_cache(), txc->seq);
8160   }
8161   txc->shared_blobs_written.clear();
8162
8163   while (!txc->removed_collections.empty()) {
8164     _queue_reap_collection(txc->removed_collections.front());
8165     txc->removed_collections.pop_front();
8166   }
8167
8168   OpSequencerRef osr = txc->osr;
8169   bool empty = false;
8170   bool submit_deferred = false;
8171   OpSequencer::q_list_t releasing_txc;
8172   {
8173     std::lock_guard<std::mutex> l(osr->qlock);
8174     txc->state = TransContext::STATE_DONE;
8175     bool notify = false;
8176     while (!osr->q.empty()) {
8177       TransContext *txc = &osr->q.front();
8178       dout(20) << __func__ << "  txc " << txc << " " << txc->get_state_name()
8179                << dendl;
8180       if (txc->state != TransContext::STATE_DONE) {
8181         if (txc->state == TransContext::STATE_PREPARE &&
8182           deferred_aggressive) {
8183           // for _osr_drain_preceding()
8184           notify = true;
8185         }
8186         if (txc->state == TransContext::STATE_DEFERRED_QUEUED &&
8187             osr->q.size() > g_conf->bluestore_max_deferred_txc) {
8188           submit_deferred = true;
8189         }
8190         break;
8191       }
8192
8193       osr->q.pop_front();
8194       releasing_txc.push_back(*txc);
8195       notify = true;
8196     }
8197     if (notify) {
8198       osr->qcond.notify_all();
8199     }
8200     if (osr->q.empty()) {
8201       dout(20) << __func__ << " osr " << osr << " q now empty" << dendl;
8202       empty = true;
8203     }
8204   }
8205   while (!releasing_txc.empty()) {
8206     // release to allocator only after all preceding txc's have also
8207     // finished any deferred writes that potentially land in these
8208     // blocks
8209     auto txc = &releasing_txc.front();
8210     _txc_release_alloc(txc);
8211     releasing_txc.pop_front();
8212     txc->log_state_latency(logger, l_bluestore_state_done_lat);
8213     delete txc;
8214   }
8215
8216   if (submit_deferred) {
8217     // we're pinning memory; flush!  we could be more fine-grained here but
8218     // i'm not sure it's worth the bother.
8219     deferred_try_submit();
8220   }
8221
8222   if (empty && osr->zombie) {
8223     dout(10) << __func__ << " reaping empty zombie osr " << osr << dendl;
8224     osr->_unregister();
8225   }
8226 }
8227
8228 void BlueStore::_txc_release_alloc(TransContext *txc)
8229 {
8230   // update allocator with full released set
8231   if (!cct->_conf->bluestore_debug_no_reuse_blocks) {
8232     dout(10) << __func__ << " " << txc << " " << txc->released << dendl;
8233     for (interval_set<uint64_t>::iterator p = txc->released.begin();
8234          p != txc->released.end();
8235          ++p) {
8236       alloc->release(p.get_start(), p.get_len());
8237     }
8238   }
8239
8240   txc->allocated.clear();
8241   txc->released.clear();
8242 }
8243
8244 void BlueStore::_osr_drain_preceding(TransContext *txc)
8245 {
8246   OpSequencer *osr = txc->osr.get();
8247   dout(10) << __func__ << " " << txc << " osr " << osr << dendl;
8248   ++deferred_aggressive; // FIXME: maybe osr-local aggressive flag?
8249   {
8250     // submit anything pending
8251     deferred_lock.lock();
8252     if (osr->deferred_pending) {
8253       _deferred_submit_unlock(osr);
8254     } else {
8255       deferred_lock.unlock();
8256     }
8257   }
8258   {
8259     // wake up any previously finished deferred events
8260     std::lock_guard<std::mutex> l(kv_lock);
8261     kv_cond.notify_one();
8262   }
8263   osr->drain_preceding(txc);
8264   --deferred_aggressive;
8265   dout(10) << __func__ << " " << osr << " done" << dendl;
8266 }
8267
8268 void BlueStore::_osr_drain_all()
8269 {
8270   dout(10) << __func__ << dendl;
8271
8272   set<OpSequencerRef> s;
8273   {
8274     std::lock_guard<std::mutex> l(osr_lock);
8275     s = osr_set;
8276   }
8277   dout(20) << __func__ << " osr_set " << s << dendl;
8278
8279   ++deferred_aggressive;
8280   {
8281     // submit anything pending
8282     deferred_try_submit();
8283   }
8284   {
8285     // wake up any previously finished deferred events
8286     std::lock_guard<std::mutex> l(kv_lock);
8287     kv_cond.notify_one();
8288   }
8289   {
8290     std::lock_guard<std::mutex> l(kv_finalize_lock);
8291     kv_finalize_cond.notify_one();
8292   }
8293   for (auto osr : s) {
8294     dout(20) << __func__ << " drain " << osr << dendl;
8295     osr->drain();
8296   }
8297   --deferred_aggressive;
8298
8299   dout(10) << __func__ << " done" << dendl;
8300 }
8301
8302 void BlueStore::_osr_unregister_all()
8303 {
8304   set<OpSequencerRef> s;
8305   {
8306     std::lock_guard<std::mutex> l(osr_lock);
8307     s = osr_set;
8308   }
8309   dout(10) << __func__ << " " << s << dendl;
8310   for (auto osr : s) {
8311     osr->_unregister();
8312
8313     if (!osr->zombie) {
8314       // break link from Sequencer to us so that this OpSequencer
8315       // instance can die with this mount/umount cycle.  note that
8316       // we assume umount() will not race against ~Sequencer.
8317       assert(osr->parent);
8318       osr->parent->p.reset();
8319     }
8320   }
8321   // nobody should be creating sequencers during umount either.
8322   {
8323     std::lock_guard<std::mutex> l(osr_lock);
8324     assert(osr_set.empty());
8325   }
8326 }
8327
8328 void BlueStore::_kv_start()
8329 {
8330   dout(10) << __func__ << dendl;
8331
8332   if (cct->_conf->bluestore_shard_finishers) {
8333     if (cct->_conf->osd_op_num_shards) {
8334       m_finisher_num = cct->_conf->osd_op_num_shards;
8335     } else {
8336       assert(bdev);
8337       if (bdev->is_rotational()) {
8338         m_finisher_num = cct->_conf->osd_op_num_shards_hdd;
8339       } else {
8340         m_finisher_num = cct->_conf->osd_op_num_shards_ssd;
8341       }
8342     }
8343   }
8344
8345   assert(m_finisher_num != 0);
8346
8347   for (int i = 0; i < m_finisher_num; ++i) {
8348     ostringstream oss;
8349     oss << "finisher-" << i;
8350     Finisher *f = new Finisher(cct, oss.str(), "finisher");
8351     finishers.push_back(f);
8352   }
8353
8354   deferred_finisher.start();
8355   for (auto f : finishers) {
8356     f->start();
8357   }
8358   kv_sync_thread.create("bstore_kv_sync");
8359   kv_finalize_thread.create("bstore_kv_final");
8360 }
8361
8362 void BlueStore::_kv_stop()
8363 {
8364   dout(10) << __func__ << dendl;
8365   {
8366     std::unique_lock<std::mutex> l(kv_lock);
8367     while (!kv_sync_started) {
8368       kv_cond.wait(l);
8369     }
8370     kv_stop = true;
8371     kv_cond.notify_all();
8372   }
8373   {
8374     std::unique_lock<std::mutex> l(kv_finalize_lock);
8375     while (!kv_finalize_started) {
8376       kv_finalize_cond.wait(l);
8377     }
8378     kv_finalize_stop = true;
8379     kv_finalize_cond.notify_all();
8380   }
8381   kv_sync_thread.join();
8382   kv_finalize_thread.join();
8383   {
8384     std::lock_guard<std::mutex> l(kv_lock);
8385     kv_stop = false;
8386   }
8387   {
8388     std::lock_guard<std::mutex> l(kv_finalize_lock);
8389     kv_finalize_stop = false;
8390   }
8391   dout(10) << __func__ << " stopping finishers" << dendl;
8392   deferred_finisher.wait_for_empty();
8393   deferred_finisher.stop();
8394   for (auto f : finishers) {
8395     f->wait_for_empty();
8396     f->stop();
8397   }
8398   dout(10) << __func__ << " stopped" << dendl;
8399 }
8400
8401 void BlueStore::_kv_sync_thread()
8402 {
8403   dout(10) << __func__ << " start" << dendl;
8404   std::unique_lock<std::mutex> l(kv_lock);
8405   assert(!kv_sync_started);
8406   kv_sync_started = true;
8407   kv_cond.notify_all();
8408   while (true) {
8409     assert(kv_committing.empty());
8410     if (kv_queue.empty() &&
8411         ((deferred_done_queue.empty() && deferred_stable_queue.empty()) ||
8412          !deferred_aggressive)) {
8413       if (kv_stop)
8414         break;
8415       dout(20) << __func__ << " sleep" << dendl;
8416       kv_cond.wait(l);
8417       dout(20) << __func__ << " wake" << dendl;
8418     } else {
8419       deque<TransContext*> kv_submitting;
8420       deque<DeferredBatch*> deferred_done, deferred_stable;
8421       uint64_t aios = 0, costs = 0;
8422
8423       dout(20) << __func__ << " committing " << kv_queue.size()
8424                << " submitting " << kv_queue_unsubmitted.size()
8425                << " deferred done " << deferred_done_queue.size()
8426                << " stable " << deferred_stable_queue.size()
8427                << dendl;
8428       kv_committing.swap(kv_queue);
8429       kv_submitting.swap(kv_queue_unsubmitted);
8430       deferred_done.swap(deferred_done_queue);
8431       deferred_stable.swap(deferred_stable_queue);
8432       aios = kv_ios;
8433       costs = kv_throttle_costs;
8434       kv_ios = 0;
8435       kv_throttle_costs = 0;
8436       utime_t start = ceph_clock_now();
8437       l.unlock();
8438
8439       dout(30) << __func__ << " committing " << kv_committing << dendl;
8440       dout(30) << __func__ << " submitting " << kv_submitting << dendl;
8441       dout(30) << __func__ << " deferred_done " << deferred_done << dendl;
8442       dout(30) << __func__ << " deferred_stable " << deferred_stable << dendl;
8443
8444       bool force_flush = false;
8445       // if bluefs is sharing the same device as data (only), then we
8446       // can rely on the bluefs commit to flush the device and make
8447       // deferred aios stable.  that means that if we do have done deferred
8448       // txcs AND we are not on a single device, we need to force a flush.
8449       if (bluefs_single_shared_device && bluefs) {
8450         if (aios) {
8451           force_flush = true;
8452         } else if (kv_committing.empty() && kv_submitting.empty() &&
8453                    deferred_stable.empty()) {
8454           force_flush = true;  // there's nothing else to commit!
8455         } else if (deferred_aggressive) {
8456           force_flush = true;
8457         }
8458       } else
8459         force_flush = true;
8460
8461       if (force_flush) {
8462         dout(20) << __func__ << " num_aios=" << aios
8463                  << " force_flush=" << (int)force_flush
8464                  << ", flushing, deferred done->stable" << dendl;
8465         // flush/barrier on block device
8466         bdev->flush();
8467
8468         // if we flush then deferred done are now deferred stable
8469         deferred_stable.insert(deferred_stable.end(), deferred_done.begin(),
8470                                deferred_done.end());
8471         deferred_done.clear();
8472       }
8473       utime_t after_flush = ceph_clock_now();
8474
8475       // we will use one final transaction to force a sync
8476       KeyValueDB::Transaction synct = db->get_transaction();
8477
8478       // increase {nid,blobid}_max?  note that this covers both the
8479       // case where we are approaching the max and the case we passed
8480       // it.  in either case, we increase the max in the earlier txn
8481       // we submit.
8482       uint64_t new_nid_max = 0, new_blobid_max = 0;
8483       if (nid_last + cct->_conf->bluestore_nid_prealloc/2 > nid_max) {
8484         KeyValueDB::Transaction t =
8485           kv_submitting.empty() ? synct : kv_submitting.front()->t;
8486         new_nid_max = nid_last + cct->_conf->bluestore_nid_prealloc;
8487         bufferlist bl;
8488         ::encode(new_nid_max, bl);
8489         t->set(PREFIX_SUPER, "nid_max", bl);
8490         dout(10) << __func__ << " new_nid_max " << new_nid_max << dendl;
8491       }
8492       if (blobid_last + cct->_conf->bluestore_blobid_prealloc/2 > blobid_max) {
8493         KeyValueDB::Transaction t =
8494           kv_submitting.empty() ? synct : kv_submitting.front()->t;
8495         new_blobid_max = blobid_last + cct->_conf->bluestore_blobid_prealloc;
8496         bufferlist bl;
8497         ::encode(new_blobid_max, bl);
8498         t->set(PREFIX_SUPER, "blobid_max", bl);
8499         dout(10) << __func__ << " new_blobid_max " << new_blobid_max << dendl;
8500       }
8501
8502       for (auto txc : kv_committing) {
8503         if (txc->state == TransContext::STATE_KV_QUEUED) {
8504           txc->log_state_latency(logger, l_bluestore_state_kv_queued_lat);
8505           int r = cct->_conf->bluestore_debug_omit_kv_commit ? 0 : db->submit_transaction(txc->t);
8506           assert(r == 0);
8507           _txc_applied_kv(txc);
8508           --txc->osr->kv_committing_serially;
8509           txc->state = TransContext::STATE_KV_SUBMITTED;
8510           if (txc->osr->kv_submitted_waiters) {
8511             std::lock_guard<std::mutex> l(txc->osr->qlock);
8512             if (txc->osr->_is_all_kv_submitted()) {
8513               txc->osr->qcond.notify_all();
8514             }
8515           }
8516
8517         } else {
8518           assert(txc->state == TransContext::STATE_KV_SUBMITTED);
8519           txc->log_state_latency(logger, l_bluestore_state_kv_queued_lat);
8520         }
8521         if (txc->had_ios) {
8522           --txc->osr->txc_with_unstable_io;
8523         }
8524       }
8525
8526       // release throttle *before* we commit.  this allows new ops
8527       // to be prepared and enter pipeline while we are waiting on
8528       // the kv commit sync/flush.  then hopefully on the next
8529       // iteration there will already be ops awake.  otherwise, we
8530       // end up going to sleep, and then wake up when the very first
8531       // transaction is ready for commit.
8532       throttle_bytes.put(costs);
8533
8534       PExtentVector bluefs_gift_extents;
8535       if (bluefs &&
8536           after_flush - bluefs_last_balance >
8537           cct->_conf->bluestore_bluefs_balance_interval) {
8538         bluefs_last_balance = after_flush;
8539         int r = _balance_bluefs_freespace(&bluefs_gift_extents);
8540         assert(r >= 0);
8541         if (r > 0) {
8542           for (auto& p : bluefs_gift_extents) {
8543             bluefs_extents.insert(p.offset, p.length);
8544           }
8545           bufferlist bl;
8546           ::encode(bluefs_extents, bl);
8547           dout(10) << __func__ << " bluefs_extents now 0x" << std::hex
8548                    << bluefs_extents << std::dec << dendl;
8549           synct->set(PREFIX_SUPER, "bluefs_extents", bl);
8550         }
8551       }
8552
8553       // cleanup sync deferred keys
8554       for (auto b : deferred_stable) {
8555         for (auto& txc : b->txcs) {
8556           bluestore_deferred_transaction_t& wt = *txc.deferred_txn;
8557           if (!wt.released.empty()) {
8558             // kraken replay compat only
8559             txc.released = wt.released;
8560             dout(10) << __func__ << " deferred txn has released "
8561                      << txc.released
8562                      << " (we just upgraded from kraken) on " << &txc << dendl;
8563             _txc_finalize_kv(&txc, synct);
8564           }
8565           // cleanup the deferred
8566           string key;
8567           get_deferred_key(wt.seq, &key);
8568           synct->rm_single_key(PREFIX_DEFERRED, key);
8569         }
8570       }
8571
8572       // submit synct synchronously (block and wait for it to commit)
8573       int r = cct->_conf->bluestore_debug_omit_kv_commit ? 0 : db->submit_transaction_sync(synct);
8574       assert(r == 0);
8575
8576       if (new_nid_max) {
8577         nid_max = new_nid_max;
8578         dout(10) << __func__ << " nid_max now " << nid_max << dendl;
8579       }
8580       if (new_blobid_max) {
8581         blobid_max = new_blobid_max;
8582         dout(10) << __func__ << " blobid_max now " << blobid_max << dendl;
8583       }
8584
8585       {
8586         utime_t finish = ceph_clock_now();
8587         utime_t dur_flush = after_flush - start;
8588         utime_t dur_kv = finish - after_flush;
8589         utime_t dur = finish - start;
8590         dout(20) << __func__ << " committed " << kv_committing.size()
8591           << " cleaned " << deferred_stable.size()
8592           << " in " << dur
8593           << " (" << dur_flush << " flush + " << dur_kv << " kv commit)"
8594           << dendl;
8595         logger->tinc(l_bluestore_kv_flush_lat, dur_flush);
8596         logger->tinc(l_bluestore_kv_commit_lat, dur_kv);
8597         logger->tinc(l_bluestore_kv_lat, dur);
8598       }
8599
8600       if (bluefs) {
8601         if (!bluefs_gift_extents.empty()) {
8602           _commit_bluefs_freespace(bluefs_gift_extents);
8603         }
8604         for (auto p = bluefs_extents_reclaiming.begin();
8605              p != bluefs_extents_reclaiming.end();
8606              ++p) {
8607           dout(20) << __func__ << " releasing old bluefs 0x" << std::hex
8608                    << p.get_start() << "~" << p.get_len() << std::dec
8609                    << dendl;
8610           alloc->release(p.get_start(), p.get_len());
8611         }
8612         bluefs_extents_reclaiming.clear();
8613       }
8614
8615       {
8616         std::unique_lock<std::mutex> m(kv_finalize_lock);
8617         if (kv_committing_to_finalize.empty()) {
8618           kv_committing_to_finalize.swap(kv_committing);
8619         } else {
8620           kv_committing_to_finalize.insert(
8621             kv_committing_to_finalize.end(),
8622             kv_committing.begin(),
8623             kv_committing.end());
8624           kv_committing.clear();
8625         }
8626         if (deferred_stable_to_finalize.empty()) {
8627           deferred_stable_to_finalize.swap(deferred_stable);
8628         } else {
8629           deferred_stable_to_finalize.insert(
8630             deferred_stable_to_finalize.end(),
8631             deferred_stable.begin(),
8632             deferred_stable.end());
8633           deferred_stable.clear();
8634         }
8635         kv_finalize_cond.notify_one();
8636       }
8637
8638       l.lock();
8639       // previously deferred "done" are now "stable" by virtue of this
8640       // commit cycle.
8641       deferred_stable_queue.swap(deferred_done);
8642     }
8643   }
8644   dout(10) << __func__ << " finish" << dendl;
8645   kv_sync_started = false;
8646 }
8647
8648 void BlueStore::_kv_finalize_thread()
8649 {
8650   deque<TransContext*> kv_committed;
8651   deque<DeferredBatch*> deferred_stable;
8652   dout(10) << __func__ << " start" << dendl;
8653   std::unique_lock<std::mutex> l(kv_finalize_lock);
8654   assert(!kv_finalize_started);
8655   kv_finalize_started = true;
8656   kv_finalize_cond.notify_all();
8657   while (true) {
8658     assert(kv_committed.empty());
8659     assert(deferred_stable.empty());
8660     if (kv_committing_to_finalize.empty() &&
8661         deferred_stable_to_finalize.empty()) {
8662       if (kv_finalize_stop)
8663         break;
8664       dout(20) << __func__ << " sleep" << dendl;
8665       kv_finalize_cond.wait(l);
8666       dout(20) << __func__ << " wake" << dendl;
8667     } else {
8668       kv_committed.swap(kv_committing_to_finalize);
8669       deferred_stable.swap(deferred_stable_to_finalize);
8670       l.unlock();
8671       dout(20) << __func__ << " kv_committed " << kv_committed << dendl;
8672       dout(20) << __func__ << " deferred_stable " << deferred_stable << dendl;
8673
8674       while (!kv_committed.empty()) {
8675         TransContext *txc = kv_committed.front();
8676         assert(txc->state == TransContext::STATE_KV_SUBMITTED);
8677         _txc_state_proc(txc);
8678         kv_committed.pop_front();
8679       }
8680
8681       for (auto b : deferred_stable) {
8682         auto p = b->txcs.begin();
8683         while (p != b->txcs.end()) {
8684           TransContext *txc = &*p;
8685           p = b->txcs.erase(p); // unlink here because
8686           _txc_state_proc(txc); // this may destroy txc
8687         }
8688         delete b;
8689       }
8690       deferred_stable.clear();
8691
8692       if (!deferred_aggressive) {
8693         if (deferred_queue_size >= deferred_batch_ops.load() ||
8694             throttle_deferred_bytes.past_midpoint()) {
8695           deferred_try_submit();
8696         }
8697       }
8698
8699       // this is as good a place as any ...
8700       _reap_collections();
8701
8702       l.lock();
8703     }
8704   }
8705   dout(10) << __func__ << " finish" << dendl;
8706   kv_finalize_started = false;
8707 }
8708
8709 bluestore_deferred_op_t *BlueStore::_get_deferred_op(
8710   TransContext *txc, OnodeRef o)
8711 {
8712   if (!txc->deferred_txn) {
8713     txc->deferred_txn = new bluestore_deferred_transaction_t;
8714   }
8715   txc->deferred_txn->ops.push_back(bluestore_deferred_op_t());
8716   return &txc->deferred_txn->ops.back();
8717 }
8718
8719 void BlueStore::_deferred_queue(TransContext *txc)
8720 {
8721   dout(20) << __func__ << " txc " << txc << " osr " << txc->osr << dendl;
8722   deferred_lock.lock();
8723   if (!txc->osr->deferred_pending &&
8724       !txc->osr->deferred_running) {
8725     deferred_queue.push_back(*txc->osr);
8726   }
8727   if (!txc->osr->deferred_pending) {
8728     txc->osr->deferred_pending = new DeferredBatch(cct, txc->osr.get());
8729   }
8730   ++deferred_queue_size;
8731   txc->osr->deferred_pending->txcs.push_back(*txc);
8732   bluestore_deferred_transaction_t& wt = *txc->deferred_txn;
8733   for (auto opi = wt.ops.begin(); opi != wt.ops.end(); ++opi) {
8734     const auto& op = *opi;
8735     assert(op.op == bluestore_deferred_op_t::OP_WRITE);
8736     bufferlist::const_iterator p = op.data.begin();
8737     for (auto e : op.extents) {
8738       txc->osr->deferred_pending->prepare_write(
8739         cct, wt.seq, e.offset, e.length, p);
8740     }
8741   }
8742   if (deferred_aggressive &&
8743       !txc->osr->deferred_running) {
8744     _deferred_submit_unlock(txc->osr.get());
8745   } else {
8746     deferred_lock.unlock();
8747   }
8748 }
8749
8750 void BlueStore::deferred_try_submit()
8751 {
8752   dout(20) << __func__ << " " << deferred_queue.size() << " osrs, "
8753            << deferred_queue_size << " txcs" << dendl;
8754   std::lock_guard<std::mutex> l(deferred_lock);
8755   vector<OpSequencerRef> osrs;
8756   osrs.reserve(deferred_queue.size());
8757   for (auto& osr : deferred_queue) {
8758     osrs.push_back(&osr);
8759   }
8760   for (auto& osr : osrs) {
8761     if (osr->deferred_pending) {
8762       if (!osr->deferred_running) {
8763         _deferred_submit_unlock(osr.get());
8764         deferred_lock.lock();
8765       } else {
8766         dout(20) << __func__ << "  osr " << osr << " already has running"
8767                  << dendl;
8768       }
8769     } else {
8770       dout(20) << __func__ << "  osr " << osr << " has no pending" << dendl;
8771     }
8772   }
8773 }
8774
8775 void BlueStore::_deferred_submit_unlock(OpSequencer *osr)
8776 {
8777   dout(10) << __func__ << " osr " << osr
8778            << " " << osr->deferred_pending->iomap.size() << " ios pending "
8779            << dendl;
8780   assert(osr->deferred_pending);
8781   assert(!osr->deferred_running);
8782
8783   auto b = osr->deferred_pending;
8784   deferred_queue_size -= b->seq_bytes.size();
8785   assert(deferred_queue_size >= 0);
8786
8787   osr->deferred_running = osr->deferred_pending;
8788   osr->deferred_pending = nullptr;
8789
8790   uint64_t start = 0, pos = 0;
8791   bufferlist bl;
8792   auto i = b->iomap.begin();
8793   while (true) {
8794     if (i == b->iomap.end() || i->first != pos) {
8795       if (bl.length()) {
8796         dout(20) << __func__ << " write 0x" << std::hex
8797                  << start << "~" << bl.length()
8798                  << " crc " << bl.crc32c(-1) << std::dec << dendl;
8799         if (!g_conf->bluestore_debug_omit_block_device_write) {
8800           logger->inc(l_bluestore_deferred_write_ops);
8801           logger->inc(l_bluestore_deferred_write_bytes, bl.length());
8802           int r = bdev->aio_write(start, bl, &b->ioc, false);
8803           assert(r == 0);
8804         }
8805       }
8806       if (i == b->iomap.end()) {
8807         break;
8808       }
8809       start = 0;
8810       pos = i->first;
8811       bl.clear();
8812     }
8813     dout(20) << __func__ << "   seq " << i->second.seq << " 0x"
8814              << std::hex << pos << "~" << i->second.bl.length() << std::dec
8815              << dendl;
8816     if (!bl.length()) {
8817       start = pos;
8818     }
8819     pos += i->second.bl.length();
8820     bl.claim_append(i->second.bl);
8821     ++i;
8822   }
8823
8824   deferred_lock.unlock();
8825   bdev->aio_submit(&b->ioc);
8826 }
8827
8828 struct C_DeferredTrySubmit : public Context {
8829   BlueStore *store;
8830   C_DeferredTrySubmit(BlueStore *s) : store(s) {}
8831   void finish(int r) {
8832     store->deferred_try_submit();
8833   }
8834 };
8835
8836 void BlueStore::_deferred_aio_finish(OpSequencer *osr)
8837 {
8838   dout(10) << __func__ << " osr " << osr << dendl;
8839   assert(osr->deferred_running);
8840   DeferredBatch *b = osr->deferred_running;
8841
8842   {
8843     std::lock_guard<std::mutex> l(deferred_lock);
8844     assert(osr->deferred_running == b);
8845     osr->deferred_running = nullptr;
8846     if (!osr->deferred_pending) {
8847       dout(20) << __func__ << " dequeueing" << dendl;
8848       auto q = deferred_queue.iterator_to(*osr);
8849       deferred_queue.erase(q);
8850     } else if (deferred_aggressive) {
8851       dout(20) << __func__ << " queuing async deferred_try_submit" << dendl;
8852       deferred_finisher.queue(new C_DeferredTrySubmit(this));
8853     } else {
8854       dout(20) << __func__ << " leaving queued, more pending" << dendl;
8855     }
8856   }
8857
8858   {
8859     uint64_t costs = 0;
8860     std::lock_guard<std::mutex> l2(osr->qlock);
8861     for (auto& i : b->txcs) {
8862       TransContext *txc = &i;
8863       txc->state = TransContext::STATE_DEFERRED_CLEANUP;
8864       costs += txc->cost;
8865     }
8866     osr->qcond.notify_all();
8867     throttle_deferred_bytes.put(costs);
8868     std::lock_guard<std::mutex> l(kv_lock);
8869     deferred_done_queue.emplace_back(b);
8870   }
8871
8872   // in the normal case, do not bother waking up the kv thread; it will
8873   // catch us on the next commit anyway.
8874   if (deferred_aggressive) {
8875     std::lock_guard<std::mutex> l(kv_lock);
8876     kv_cond.notify_one();
8877   }
8878 }
8879
8880 int BlueStore::_deferred_replay()
8881 {
8882   dout(10) << __func__ << " start" << dendl;
8883   OpSequencerRef osr = new OpSequencer(cct, this);
8884   int count = 0;
8885   int r = 0;
8886   KeyValueDB::Iterator it = db->get_iterator(PREFIX_DEFERRED);
8887   for (it->lower_bound(string()); it->valid(); it->next(), ++count) {
8888     dout(20) << __func__ << " replay " << pretty_binary_string(it->key())
8889              << dendl;
8890     bluestore_deferred_transaction_t *deferred_txn =
8891       new bluestore_deferred_transaction_t;
8892     bufferlist bl = it->value();
8893     bufferlist::iterator p = bl.begin();
8894     try {
8895       ::decode(*deferred_txn, p);
8896     } catch (buffer::error& e) {
8897       derr << __func__ << " failed to decode deferred txn "
8898            << pretty_binary_string(it->key()) << dendl;
8899       delete deferred_txn;
8900       r = -EIO;
8901       goto out;
8902     }
8903     TransContext *txc = _txc_create(osr.get());
8904     txc->deferred_txn = deferred_txn;
8905     txc->state = TransContext::STATE_KV_DONE;
8906     _txc_state_proc(txc);
8907   }
8908  out:
8909   dout(20) << __func__ << " draining osr" << dendl;
8910   _osr_drain_all();
8911   osr->discard();
8912   dout(10) << __func__ << " completed " << count << " events" << dendl;
8913   return r;
8914 }
8915
8916 // ---------------------------
8917 // transactions
8918
8919 int BlueStore::queue_transactions(
8920     Sequencer *posr,
8921     vector<Transaction>& tls,
8922     TrackedOpRef op,
8923     ThreadPool::TPHandle *handle)
8924 {
8925   FUNCTRACE();
8926   Context *onreadable;
8927   Context *ondisk;
8928   Context *onreadable_sync;
8929   ObjectStore::Transaction::collect_contexts(
8930     tls, &onreadable, &ondisk, &onreadable_sync);
8931
8932   if (cct->_conf->objectstore_blackhole) {
8933     dout(0) << __func__ << " objectstore_blackhole = TRUE, dropping transaction"
8934             << dendl;
8935     delete ondisk;
8936     delete onreadable;
8937     delete onreadable_sync;
8938     return 0;
8939   }
8940   utime_t start = ceph_clock_now();
8941   // set up the sequencer
8942   OpSequencer *osr;
8943   assert(posr);
8944   if (posr->p) {
8945     osr = static_cast<OpSequencer *>(posr->p.get());
8946     dout(10) << __func__ << " existing " << osr << " " << *osr << dendl;
8947   } else {
8948     osr = new OpSequencer(cct, this);
8949     osr->parent = posr;
8950     posr->p = osr;
8951     dout(10) << __func__ << " new " << osr << " " << *osr << dendl;
8952   }
8953
8954   // prepare
8955   TransContext *txc = _txc_create(osr);
8956   txc->onreadable = onreadable;
8957   txc->onreadable_sync = onreadable_sync;
8958   txc->oncommit = ondisk;
8959
8960   for (vector<Transaction>::iterator p = tls.begin(); p != tls.end(); ++p) {
8961     (*p).set_osr(osr);
8962     txc->bytes += (*p).get_num_bytes();
8963     _txc_add_transaction(txc, &(*p));
8964   }
8965   _txc_calc_cost(txc);
8966
8967   _txc_write_nodes(txc, txc->t);
8968
8969   // journal deferred items
8970   if (txc->deferred_txn) {
8971     txc->deferred_txn->seq = ++deferred_seq;
8972     bufferlist bl;
8973     ::encode(*txc->deferred_txn, bl);
8974     string key;
8975     get_deferred_key(txc->deferred_txn->seq, &key);
8976     txc->t->set(PREFIX_DEFERRED, key, bl);
8977   }
8978
8979   _txc_finalize_kv(txc, txc->t);
8980   if (handle)
8981     handle->suspend_tp_timeout();
8982
8983   utime_t tstart = ceph_clock_now();
8984   throttle_bytes.get(txc->cost);
8985   if (txc->deferred_txn) {
8986     // ensure we do not block here because of deferred writes
8987     if (!throttle_deferred_bytes.get_or_fail(txc->cost)) {
8988       dout(10) << __func__ << " failed get throttle_deferred_bytes, aggressive"
8989                << dendl;
8990       ++deferred_aggressive;
8991       deferred_try_submit();
8992       {
8993         // wake up any previously finished deferred events
8994         std::lock_guard<std::mutex> l(kv_lock);
8995         kv_cond.notify_one();
8996       }
8997       throttle_deferred_bytes.get(txc->cost);
8998       --deferred_aggressive;
8999    }
9000   }
9001   utime_t tend = ceph_clock_now();
9002
9003   if (handle)
9004     handle->reset_tp_timeout();
9005
9006   logger->inc(l_bluestore_txc);
9007
9008   // execute (start)
9009   _txc_state_proc(txc);
9010
9011   logger->tinc(l_bluestore_submit_lat, ceph_clock_now() - start);
9012   logger->tinc(l_bluestore_throttle_lat, tend - tstart);
9013   return 0;
9014 }
9015
9016 void BlueStore::_txc_aio_submit(TransContext *txc)
9017 {
9018   dout(10) << __func__ << " txc " << txc << dendl;
9019   bdev->aio_submit(&txc->ioc);
9020 }
9021
9022 void BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t)
9023 {
9024   Transaction::iterator i = t->begin();
9025
9026   _dump_transaction(t);
9027
9028   vector<CollectionRef> cvec(i.colls.size());
9029   unsigned j = 0;
9030   for (vector<coll_t>::iterator p = i.colls.begin(); p != i.colls.end();
9031        ++p, ++j) {
9032     cvec[j] = _get_collection(*p);
9033   }
9034   vector<OnodeRef> ovec(i.objects.size());
9035
9036   for (int pos = 0; i.have_op(); ++pos) {
9037     Transaction::Op *op = i.decode_op();
9038     int r = 0;
9039
9040     // no coll or obj
9041     if (op->op == Transaction::OP_NOP)
9042       continue;
9043
9044     // collection operations
9045     CollectionRef &c = cvec[op->cid];
9046     switch (op->op) {
9047     case Transaction::OP_RMCOLL:
9048       {
9049         const coll_t &cid = i.get_cid(op->cid);
9050         r = _remove_collection(txc, cid, &c);
9051         if (!r)
9052           continue;
9053       }
9054       break;
9055
9056     case Transaction::OP_MKCOLL:
9057       {
9058         assert(!c);
9059         const coll_t &cid = i.get_cid(op->cid);
9060         r = _create_collection(txc, cid, op->split_bits, &c);
9061         if (!r)
9062           continue;
9063       }
9064       break;
9065
9066     case Transaction::OP_SPLIT_COLLECTION:
9067       assert(0 == "deprecated");
9068       break;
9069
9070     case Transaction::OP_SPLIT_COLLECTION2:
9071       {
9072         uint32_t bits = op->split_bits;
9073         uint32_t rem = op->split_rem;
9074         r = _split_collection(txc, c, cvec[op->dest_cid], bits, rem);
9075         if (!r)
9076           continue;
9077       }
9078       break;
9079
9080     case Transaction::OP_COLL_HINT:
9081       {
9082         uint32_t type = op->hint_type;
9083         bufferlist hint;
9084         i.decode_bl(hint);
9085         bufferlist::iterator hiter = hint.begin();
9086         if (type == Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS) {
9087           uint32_t pg_num;
9088           uint64_t num_objs;
9089           ::decode(pg_num, hiter);
9090           ::decode(num_objs, hiter);
9091           dout(10) << __func__ << " collection hint objects is a no-op, "
9092                    << " pg_num " << pg_num << " num_objects " << num_objs
9093                    << dendl;
9094         } else {
9095           // Ignore the hint
9096           dout(10) << __func__ << " unknown collection hint " << type << dendl;
9097         }
9098         continue;
9099       }
9100       break;
9101
9102     case Transaction::OP_COLL_SETATTR:
9103       r = -EOPNOTSUPP;
9104       break;
9105
9106     case Transaction::OP_COLL_RMATTR:
9107       r = -EOPNOTSUPP;
9108       break;
9109
9110     case Transaction::OP_COLL_RENAME:
9111       assert(0 == "not implemented");
9112       break;
9113     }
9114     if (r < 0) {
9115       derr << __func__ << " error " << cpp_strerror(r)
9116            << " not handled on operation " << op->op
9117            << " (op " << pos << ", counting from 0)" << dendl;
9118       _dump_transaction(t, 0);
9119       assert(0 == "unexpected error");
9120     }
9121
9122     // these operations implicity create the object
9123     bool create = false;
9124     if (op->op == Transaction::OP_TOUCH ||
9125         op->op == Transaction::OP_WRITE ||
9126         op->op == Transaction::OP_ZERO) {
9127       create = true;
9128     }
9129
9130     // object operations
9131     RWLock::WLocker l(c->lock);
9132     OnodeRef &o = ovec[op->oid];
9133     if (!o) {
9134       ghobject_t oid = i.get_oid(op->oid);
9135       o = c->get_onode(oid, create);
9136     }
9137     if (!create && (!o || !o->exists)) {
9138       dout(10) << __func__ << " op " << op->op << " got ENOENT on "
9139                << i.get_oid(op->oid) << dendl;
9140       r = -ENOENT;
9141       goto endop;
9142     }
9143
9144     switch (op->op) {
9145     case Transaction::OP_TOUCH:
9146       r = _touch(txc, c, o);
9147       break;
9148
9149     case Transaction::OP_WRITE:
9150       {
9151         uint64_t off = op->off;
9152         uint64_t len = op->len;
9153         uint32_t fadvise_flags = i.get_fadvise_flags();
9154         bufferlist bl;
9155         i.decode_bl(bl);
9156         r = _write(txc, c, o, off, len, bl, fadvise_flags);
9157       }
9158       break;
9159
9160     case Transaction::OP_ZERO:
9161       {
9162         uint64_t off = op->off;
9163         uint64_t len = op->len;
9164         r = _zero(txc, c, o, off, len);
9165       }
9166       break;
9167
9168     case Transaction::OP_TRIMCACHE:
9169       {
9170         // deprecated, no-op
9171       }
9172       break;
9173
9174     case Transaction::OP_TRUNCATE:
9175       {
9176         uint64_t off = op->off;
9177         r = _truncate(txc, c, o, off);
9178       }
9179       break;
9180
9181     case Transaction::OP_REMOVE:
9182       {
9183         r = _remove(txc, c, o);
9184       }
9185       break;
9186
9187     case Transaction::OP_SETATTR:
9188       {
9189         string name = i.decode_string();
9190         bufferptr bp;
9191         i.decode_bp(bp);
9192         r = _setattr(txc, c, o, name, bp);
9193       }
9194       break;
9195
9196     case Transaction::OP_SETATTRS:
9197       {
9198         map<string, bufferptr> aset;
9199         i.decode_attrset(aset);
9200         r = _setattrs(txc, c, o, aset);
9201       }
9202       break;
9203
9204     case Transaction::OP_RMATTR:
9205       {
9206         string name = i.decode_string();
9207         r = _rmattr(txc, c, o, name);
9208       }
9209       break;
9210
9211     case Transaction::OP_RMATTRS:
9212       {
9213         r = _rmattrs(txc, c, o);
9214       }
9215       break;
9216
9217     case Transaction::OP_CLONE:
9218       {
9219         OnodeRef& no = ovec[op->dest_oid];
9220         if (!no) {
9221           const ghobject_t& noid = i.get_oid(op->dest_oid);
9222           no = c->get_onode(noid, true);
9223         }
9224         r = _clone(txc, c, o, no);
9225       }
9226       break;
9227
9228     case Transaction::OP_CLONERANGE:
9229       assert(0 == "deprecated");
9230       break;
9231
9232     case Transaction::OP_CLONERANGE2:
9233       {
9234         OnodeRef& no = ovec[op->dest_oid];
9235         if (!no) {
9236           const ghobject_t& noid = i.get_oid(op->dest_oid);
9237           no = c->get_onode(noid, true);
9238         }
9239         uint64_t srcoff = op->off;
9240         uint64_t len = op->len;
9241         uint64_t dstoff = op->dest_off;
9242         r = _clone_range(txc, c, o, no, srcoff, len, dstoff);
9243       }
9244       break;
9245
9246     case Transaction::OP_COLL_ADD:
9247       assert(0 == "not implemented");
9248       break;
9249
9250     case Transaction::OP_COLL_REMOVE:
9251       assert(0 == "not implemented");
9252       break;
9253
9254     case Transaction::OP_COLL_MOVE:
9255       assert(0 == "deprecated");
9256       break;
9257
9258     case Transaction::OP_COLL_MOVE_RENAME:
9259     case Transaction::OP_TRY_RENAME:
9260       {
9261         assert(op->cid == op->dest_cid);
9262         const ghobject_t& noid = i.get_oid(op->dest_oid);
9263         OnodeRef& no = ovec[op->dest_oid];
9264         if (!no) {
9265           no = c->get_onode(noid, false);
9266         }
9267         r = _rename(txc, c, o, no, noid);
9268       }
9269       break;
9270
9271     case Transaction::OP_OMAP_CLEAR:
9272       {
9273         r = _omap_clear(txc, c, o);
9274       }
9275       break;
9276     case Transaction::OP_OMAP_SETKEYS:
9277       {
9278         bufferlist aset_bl;
9279         i.decode_attrset_bl(&aset_bl);
9280         r = _omap_setkeys(txc, c, o, aset_bl);
9281       }
9282       break;
9283     case Transaction::OP_OMAP_RMKEYS:
9284       {
9285         bufferlist keys_bl;
9286         i.decode_keyset_bl(&keys_bl);
9287         r = _omap_rmkeys(txc, c, o, keys_bl);
9288       }
9289       break;
9290     case Transaction::OP_OMAP_RMKEYRANGE:
9291       {
9292         string first, last;
9293         first = i.decode_string();
9294         last = i.decode_string();
9295         r = _omap_rmkey_range(txc, c, o, first, last);
9296       }
9297       break;
9298     case Transaction::OP_OMAP_SETHEADER:
9299       {
9300         bufferlist bl;
9301         i.decode_bl(bl);
9302         r = _omap_setheader(txc, c, o, bl);
9303       }
9304       break;
9305
9306     case Transaction::OP_SETALLOCHINT:
9307       {
9308         r = _set_alloc_hint(txc, c, o,
9309                             op->expected_object_size,
9310                             op->expected_write_size,
9311                             op->alloc_hint_flags);
9312       }
9313       break;
9314
9315     default:
9316       derr << __func__ << "bad op " << op->op << dendl;
9317       ceph_abort();
9318     }
9319
9320   endop:
9321     if (r < 0) {
9322       bool ok = false;
9323
9324       if (r == -ENOENT && !(op->op == Transaction::OP_CLONERANGE ||
9325                             op->op == Transaction::OP_CLONE ||
9326                             op->op == Transaction::OP_CLONERANGE2 ||
9327                             op->op == Transaction::OP_COLL_ADD ||
9328                             op->op == Transaction::OP_SETATTR ||
9329                             op->op == Transaction::OP_SETATTRS ||
9330                             op->op == Transaction::OP_RMATTR ||
9331                             op->op == Transaction::OP_OMAP_SETKEYS ||
9332                             op->op == Transaction::OP_OMAP_RMKEYS ||
9333                             op->op == Transaction::OP_OMAP_RMKEYRANGE ||
9334                             op->op == Transaction::OP_OMAP_SETHEADER))
9335         // -ENOENT is usually okay
9336         ok = true;
9337       if (r == -ENODATA)
9338         ok = true;
9339
9340       if (!ok) {
9341         const char *msg = "unexpected error code";
9342
9343         if (r == -ENOENT && (op->op == Transaction::OP_CLONERANGE ||
9344                              op->op == Transaction::OP_CLONE ||
9345                              op->op == Transaction::OP_CLONERANGE2))
9346           msg = "ENOENT on clone suggests osd bug";
9347
9348         if (r == -ENOSPC)
9349           // For now, if we hit _any_ ENOSPC, crash, before we do any damage
9350           // by partially applying transactions.
9351           msg = "ENOSPC from bluestore, misconfigured cluster";
9352
9353         if (r == -ENOTEMPTY) {
9354           msg = "ENOTEMPTY suggests garbage data in osd data dir";
9355         }
9356
9357         derr << __func__ << " error " << cpp_strerror(r)
9358              << " not handled on operation " << op->op
9359              << " (op " << pos << ", counting from 0)"
9360              << dendl;
9361         derr << msg << dendl;
9362         _dump_transaction(t, 0);
9363         assert(0 == "unexpected error");
9364       }
9365     }
9366   }
9367 }
9368
9369
9370
9371 // -----------------
9372 // write operations
9373
9374 int BlueStore::_touch(TransContext *txc,
9375                       CollectionRef& c,
9376                       OnodeRef &o)
9377 {
9378   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
9379   int r = 0;
9380   _assign_nid(txc, o);
9381   txc->write_onode(o);
9382   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
9383   return r;
9384 }
9385
9386 void BlueStore::_dump_onode(OnodeRef o, int log_level)
9387 {
9388   if (!cct->_conf->subsys.should_gather(ceph_subsys_bluestore, log_level))
9389     return;
9390   dout(log_level) << __func__ << " " << o << " " << o->oid
9391                   << " nid " << o->onode.nid
9392                   << " size 0x" << std::hex << o->onode.size
9393                   << " (" << std::dec << o->onode.size << ")"
9394                   << " expected_object_size " << o->onode.expected_object_size
9395                   << " expected_write_size " << o->onode.expected_write_size
9396                   << " in " << o->onode.extent_map_shards.size() << " shards"
9397                   << ", " << o->extent_map.spanning_blob_map.size()
9398                   << " spanning blobs"
9399                   << dendl;
9400   for (auto p = o->onode.attrs.begin();
9401        p != o->onode.attrs.end();
9402        ++p) {
9403     dout(log_level) << __func__ << "  attr " << p->first
9404                     << " len " << p->second.length() << dendl;
9405   }
9406   _dump_extent_map(o->extent_map, log_level);
9407 }
9408
9409 void BlueStore::_dump_extent_map(ExtentMap &em, int log_level)
9410 {
9411   uint64_t pos = 0;
9412   for (auto& s : em.shards) {
9413     dout(log_level) << __func__ << "  shard " << *s.shard_info
9414                     << (s.loaded ? " (loaded)" : "")
9415                     << (s.dirty ? " (dirty)" : "")
9416                     << dendl;
9417   }
9418   for (auto& e : em.extent_map) {
9419     dout(log_level) << __func__ << "  " << e << dendl;
9420     assert(e.logical_offset >= pos);
9421     pos = e.logical_offset + e.length;
9422     const bluestore_blob_t& blob = e.blob->get_blob();
9423     if (blob.has_csum()) {
9424       vector<uint64_t> v;
9425       unsigned n = blob.get_csum_count();
9426       for (unsigned i = 0; i < n; ++i)
9427         v.push_back(blob.get_csum_item(i));
9428       dout(log_level) << __func__ << "      csum: " << std::hex << v << std::dec
9429                       << dendl;
9430     }
9431     std::lock_guard<std::recursive_mutex> l(e.blob->shared_blob->get_cache()->lock);
9432     for (auto& i : e.blob->shared_blob->bc.buffer_map) {
9433       dout(log_level) << __func__ << "       0x" << std::hex << i.first
9434                       << "~" << i.second->length << std::dec
9435                       << " " << *i.second << dendl;
9436     }
9437   }
9438 }
9439
9440 void BlueStore::_dump_transaction(Transaction *t, int log_level)
9441 {
9442   dout(log_level) << " transaction dump:\n";
9443   JSONFormatter f(true);
9444   f.open_object_section("transaction");
9445   t->dump(&f);
9446   f.close_section();
9447   f.flush(*_dout);
9448   *_dout << dendl;
9449 }
9450
9451 void BlueStore::_pad_zeros(
9452   bufferlist *bl, uint64_t *offset,
9453   uint64_t chunk_size)
9454 {
9455   auto length = bl->length();
9456   dout(30) << __func__ << " 0x" << std::hex << *offset << "~" << length
9457            << " chunk_size 0x" << chunk_size << std::dec << dendl;
9458   dout(40) << "before:\n";
9459   bl->hexdump(*_dout);
9460   *_dout << dendl;
9461   // front
9462   size_t front_pad = *offset % chunk_size;
9463   size_t back_pad = 0;
9464   size_t pad_count = 0;
9465   if (front_pad) {
9466     size_t front_copy = MIN(chunk_size - front_pad, length);
9467     bufferptr z = buffer::create_page_aligned(chunk_size);
9468     z.zero(0, front_pad, false);
9469     pad_count += front_pad;
9470     bl->copy(0, front_copy, z.c_str() + front_pad);
9471     if (front_copy + front_pad < chunk_size) {
9472       back_pad = chunk_size - (length + front_pad);
9473       z.zero(front_pad + length, back_pad, false);
9474       pad_count += back_pad;
9475     }
9476     bufferlist old, t;
9477     old.swap(*bl);
9478     t.substr_of(old, front_copy, length - front_copy);
9479     bl->append(z);
9480     bl->claim_append(t);
9481     *offset -= front_pad;
9482     length += pad_count;
9483   }
9484
9485   // back
9486   uint64_t end = *offset + length;
9487   unsigned back_copy = end % chunk_size;
9488   if (back_copy) {
9489     assert(back_pad == 0);
9490     back_pad = chunk_size - back_copy;
9491     assert(back_copy <= length);
9492     bufferptr tail(chunk_size);
9493     bl->copy(length - back_copy, back_copy, tail.c_str());
9494     tail.zero(back_copy, back_pad, false);
9495     bufferlist old;
9496     old.swap(*bl);
9497     bl->substr_of(old, 0, length - back_copy);
9498     bl->append(tail);
9499     length += back_pad;
9500     pad_count += back_pad;
9501   }
9502   dout(20) << __func__ << " pad 0x" << std::hex << front_pad << " + 0x"
9503            << back_pad << " on front/back, now 0x" << *offset << "~"
9504            << length << std::dec << dendl;
9505   dout(40) << "after:\n";
9506   bl->hexdump(*_dout);
9507   *_dout << dendl;
9508   if (pad_count)
9509     logger->inc(l_bluestore_write_pad_bytes, pad_count);
9510   assert(bl->length() == length);
9511 }
9512
9513 void BlueStore::_do_write_small(
9514     TransContext *txc,
9515     CollectionRef &c,
9516     OnodeRef o,
9517     uint64_t offset, uint64_t length,
9518     bufferlist::iterator& blp,
9519     WriteContext *wctx)
9520 {
9521   dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
9522            << std::dec << dendl;
9523   assert(length < min_alloc_size);
9524   uint64_t end_offs = offset + length;
9525
9526   logger->inc(l_bluestore_write_small);
9527   logger->inc(l_bluestore_write_small_bytes, length);
9528
9529   bufferlist bl;
9530   blp.copy(length, bl);
9531
9532   // Look for an existing mutable blob we can use.
9533   auto begin = o->extent_map.extent_map.begin();
9534   auto end = o->extent_map.extent_map.end();
9535   auto ep = o->extent_map.seek_lextent(offset);
9536   if (ep != begin) {
9537     --ep;
9538     if (ep->blob_end() <= offset) {
9539       ++ep;
9540     }
9541   }
9542   auto prev_ep = ep;
9543   if (prev_ep != begin) {
9544     --prev_ep;
9545   } else {
9546     prev_ep = end; // to avoid this extent check as it's a duplicate
9547   }
9548
9549   auto max_bsize = MAX(wctx->target_blob_size, min_alloc_size);
9550   auto min_off = offset >= max_bsize ? offset - max_bsize : 0;
9551   uint32_t alloc_len = min_alloc_size;
9552   auto offset0 = P2ALIGN(offset, alloc_len);
9553
9554   bool any_change;
9555
9556   // search suitable extent in both forward and reverse direction in
9557   // [offset - target_max_blob_size, offset + target_max_blob_size] range
9558   // then check if blob can be reused via can_reuse_blob func or apply
9559   // direct/deferred write (the latter for extents including or higher
9560   // than 'offset' only).
9561   do {
9562     any_change = false;
9563
9564     if (ep != end && ep->logical_offset < offset + max_bsize) {
9565       BlobRef b = ep->blob;
9566       auto bstart = ep->blob_start();
9567       dout(20) << __func__ << " considering " << *b
9568                << " bstart 0x" << std::hex << bstart << std::dec << dendl;
9569       if (bstart >= end_offs) {
9570         dout(20) << __func__ << " ignoring distant " << *b << dendl;
9571       } else if (!b->get_blob().is_mutable()) {
9572         dout(20) << __func__ << " ignoring immutable " << *b << dendl;
9573       } else if (ep->logical_offset % min_alloc_size !=
9574                   ep->blob_offset % min_alloc_size) {
9575         dout(20) << __func__ << " ignoring offset-skewed " << *b << dendl;
9576       } else {
9577         uint64_t chunk_size = b->get_blob().get_chunk_size(block_size);
9578         // can we pad our head/tail out with zeros?
9579         uint64_t head_pad, tail_pad;
9580         head_pad = P2PHASE(offset, chunk_size);
9581         tail_pad = P2NPHASE(end_offs, chunk_size);
9582         if (head_pad || tail_pad) {
9583           o->extent_map.fault_range(db, offset - head_pad,
9584                                     end_offs - offset + head_pad + tail_pad);
9585         }
9586         if (head_pad &&
9587             o->extent_map.has_any_lextents(offset - head_pad, chunk_size)) {
9588           head_pad = 0;
9589         }
9590         if (tail_pad && o->extent_map.has_any_lextents(end_offs, tail_pad)) {
9591           tail_pad = 0;
9592         }
9593
9594         uint64_t b_off = offset - head_pad - bstart;
9595         uint64_t b_len = length + head_pad + tail_pad;
9596
9597         // direct write into unused blocks of an existing mutable blob?
9598         if ((b_off % chunk_size == 0 && b_len % chunk_size == 0) &&
9599             b->get_blob().get_ondisk_length() >= b_off + b_len &&
9600             b->get_blob().is_unused(b_off, b_len) &&
9601             b->get_blob().is_allocated(b_off, b_len)) {
9602           _apply_padding(head_pad, tail_pad, bl);
9603
9604           dout(20) << __func__ << "  write to unused 0x" << std::hex
9605                    << b_off << "~" << b_len
9606                    << " pad 0x" << head_pad << " + 0x" << tail_pad
9607                    << std::dec << " of mutable " << *b << dendl;
9608           _buffer_cache_write(txc, b, b_off, bl,
9609                               wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
9610
9611           if (!g_conf->bluestore_debug_omit_block_device_write) {
9612             if (b_len <= prefer_deferred_size) {
9613               dout(20) << __func__ << " deferring small 0x" << std::hex
9614                        << b_len << std::dec << " unused write via deferred" << dendl;
9615               bluestore_deferred_op_t *op = _get_deferred_op(txc, o);
9616               op->op = bluestore_deferred_op_t::OP_WRITE;
9617               b->get_blob().map(
9618                 b_off, b_len,
9619                 [&](uint64_t offset, uint64_t length) {
9620                   op->extents.emplace_back(bluestore_pextent_t(offset, length));
9621                   return 0;
9622                 });
9623               op->data = bl;
9624             } else {
9625               b->get_blob().map_bl(
9626                 b_off, bl,
9627                 [&](uint64_t offset, bufferlist& t) {
9628                   bdev->aio_write(offset, t,
9629                                   &txc->ioc, wctx->buffered);
9630                 });
9631             }
9632           }
9633           b->dirty_blob().calc_csum(b_off, bl);
9634           dout(20) << __func__ << "  lex old " << *ep << dendl;
9635           Extent *le = o->extent_map.set_lextent(c, offset, b_off + head_pad, length,
9636                                                  b,
9637                                                  &wctx->old_extents);
9638           b->dirty_blob().mark_used(le->blob_offset, le->length);
9639           txc->statfs_delta.stored() += le->length;
9640           dout(20) << __func__ << "  lex " << *le << dendl;
9641           logger->inc(l_bluestore_write_small_unused);
9642           return;
9643         }
9644         // read some data to fill out the chunk?
9645         uint64_t head_read = P2PHASE(b_off, chunk_size);
9646         uint64_t tail_read = P2NPHASE(b_off + b_len, chunk_size);
9647         if ((head_read || tail_read) &&
9648             (b->get_blob().get_ondisk_length() >= b_off + b_len + tail_read) &&
9649             head_read + tail_read < min_alloc_size) {
9650           b_off -= head_read;
9651           b_len += head_read + tail_read;
9652
9653         } else {
9654           head_read = tail_read = 0;
9655         }
9656
9657         // chunk-aligned deferred overwrite?
9658         if (b->get_blob().get_ondisk_length() >= b_off + b_len &&
9659             b_off % chunk_size == 0 &&
9660             b_len % chunk_size == 0 &&
9661             b->get_blob().is_allocated(b_off, b_len)) {
9662
9663           _apply_padding(head_pad, tail_pad, bl);
9664
9665           dout(20) << __func__ << "  reading head 0x" << std::hex << head_read
9666                    << " and tail 0x" << tail_read << std::dec << dendl;
9667           if (head_read) {
9668             bufferlist head_bl;
9669             int r = _do_read(c.get(), o, offset - head_pad - head_read, head_read,
9670                              head_bl, 0);
9671             assert(r >= 0 && r <= (int)head_read);
9672             size_t zlen = head_read - r;
9673             if (zlen) {
9674               head_bl.append_zero(zlen);
9675               logger->inc(l_bluestore_write_pad_bytes, zlen);
9676             }
9677             bl.claim_prepend(head_bl);
9678             logger->inc(l_bluestore_write_penalty_read_ops);
9679           }
9680           if (tail_read) {
9681             bufferlist tail_bl;
9682             int r = _do_read(c.get(), o, offset + length + tail_pad, tail_read,
9683                              tail_bl, 0);
9684             assert(r >= 0 && r <= (int)tail_read);
9685             size_t zlen = tail_read - r;
9686             if (zlen) {
9687               tail_bl.append_zero(zlen);
9688               logger->inc(l_bluestore_write_pad_bytes, zlen);
9689             }
9690             bl.claim_append(tail_bl);
9691             logger->inc(l_bluestore_write_penalty_read_ops);
9692           }
9693           logger->inc(l_bluestore_write_small_pre_read);
9694
9695           bluestore_deferred_op_t *op = _get_deferred_op(txc, o);
9696           op->op = bluestore_deferred_op_t::OP_WRITE;
9697           _buffer_cache_write(txc, b, b_off, bl,
9698                               wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
9699
9700           int r = b->get_blob().map(
9701             b_off, b_len,
9702             [&](uint64_t offset, uint64_t length) {
9703               op->extents.emplace_back(bluestore_pextent_t(offset, length));
9704               return 0;
9705             });
9706           assert(r == 0);
9707           if (b->get_blob().csum_type) {
9708             b->dirty_blob().calc_csum(b_off, bl);
9709           }
9710           op->data.claim(bl);
9711           dout(20) << __func__ << "  deferred write 0x" << std::hex << b_off << "~"
9712                    << b_len << std::dec << " of mutable " << *b
9713                    << " at " << op->extents << dendl;
9714           Extent *le = o->extent_map.set_lextent(c, offset, offset - bstart, length,
9715                                                  b, &wctx->old_extents);
9716           b->dirty_blob().mark_used(le->blob_offset, le->length);
9717           txc->statfs_delta.stored() += le->length;
9718           dout(20) << __func__ << "  lex " << *le << dendl;
9719           logger->inc(l_bluestore_write_small_deferred);
9720           return;
9721         }
9722         // try to reuse blob if we can
9723         if (b->can_reuse_blob(min_alloc_size,
9724                               max_bsize,
9725                               offset0 - bstart,
9726                               &alloc_len)) {
9727           assert(alloc_len == min_alloc_size); // expecting data always
9728                                                // fit into reused blob
9729           // Need to check for pending writes desiring to
9730           // reuse the same pextent. The rationale is that during GC two chunks
9731           // from garbage blobs(compressed?) can share logical space within the same
9732           // AU. That's in turn might be caused by unaligned len in clone_range2.
9733           // Hence the second write will fail in an attempt to reuse blob at
9734           // do_alloc_write().
9735           if (!wctx->has_conflict(b,
9736                                   offset0,
9737                                   offset0 + alloc_len, 
9738                                   min_alloc_size)) {
9739
9740             // we can't reuse pad_head/pad_tail since they might be truncated 
9741             // due to existent extents
9742             uint64_t b_off = offset - bstart;
9743             uint64_t b_off0 = b_off;
9744             _pad_zeros(&bl, &b_off0, chunk_size);
9745
9746             dout(20) << __func__ << " reuse blob " << *b << std::hex
9747                      << " (0x" << b_off0 << "~" << bl.length() << ")"
9748                      << " (0x" << b_off << "~" << length << ")"
9749                      << std::dec << dendl;
9750
9751             o->extent_map.punch_hole(c, offset, length, &wctx->old_extents);
9752             wctx->write(offset, b, alloc_len, b_off0, bl, b_off, length,
9753                         false, false);
9754             logger->inc(l_bluestore_write_small_unused);
9755             return;
9756           }
9757         }
9758       }
9759       ++ep;
9760       any_change = true;
9761     } // if (ep != end && ep->logical_offset < offset + max_bsize)
9762
9763     // check extent for reuse in reverse order
9764     if (prev_ep != end && prev_ep->logical_offset >= min_off) {
9765       BlobRef b = prev_ep->blob;
9766       auto bstart = prev_ep->blob_start();
9767       dout(20) << __func__ << " considering " << *b
9768                << " bstart 0x" << std::hex << bstart << std::dec << dendl;
9769       if (b->can_reuse_blob(min_alloc_size,
9770                             max_bsize,
9771                             offset0 - bstart,
9772                             &alloc_len)) {
9773         assert(alloc_len == min_alloc_size); // expecting data always
9774                                              // fit into reused blob
9775         // Need to check for pending writes desiring to
9776         // reuse the same pextent. The rationale is that during GC two chunks
9777         // from garbage blobs(compressed?) can share logical space within the same
9778         // AU. That's in turn might be caused by unaligned len in clone_range2.
9779         // Hence the second write will fail in an attempt to reuse blob at
9780         // do_alloc_write().
9781         if (!wctx->has_conflict(b,
9782                                 offset0,
9783                                 offset0 + alloc_len, 
9784                                 min_alloc_size)) {
9785
9786           uint64_t chunk_size = b->get_blob().get_chunk_size(block_size);
9787           uint64_t b_off = offset - bstart;
9788           uint64_t b_off0 = b_off;
9789           _pad_zeros(&bl, &b_off0, chunk_size);
9790
9791           dout(20) << __func__ << " reuse blob " << *b << std::hex
9792                     << " (0x" << b_off0 << "~" << bl.length() << ")"
9793                     << " (0x" << b_off << "~" << length << ")"
9794                     << std::dec << dendl;
9795
9796           o->extent_map.punch_hole(c, offset, length, &wctx->old_extents);
9797           wctx->write(offset, b, alloc_len, b_off0, bl, b_off, length,
9798                       false, false);
9799           logger->inc(l_bluestore_write_small_unused);
9800           return;
9801         }
9802       } 
9803       if (prev_ep != begin) {
9804         --prev_ep;
9805         any_change = true;
9806       } else {
9807         prev_ep = end; // to avoid useless first extent re-check
9808       }
9809     } // if (prev_ep != end && prev_ep->logical_offset >= min_off) 
9810   } while (any_change);
9811
9812   // new blob.
9813   
9814   BlobRef b = c->new_blob();
9815   uint64_t b_off = P2PHASE(offset, alloc_len);
9816   uint64_t b_off0 = b_off;
9817   _pad_zeros(&bl, &b_off0, block_size);
9818   o->extent_map.punch_hole(c, offset, length, &wctx->old_extents);
9819   wctx->write(offset, b, alloc_len, b_off0, bl, b_off, length, true, true);
9820   logger->inc(l_bluestore_write_small_new);
9821
9822   return;
9823 }
9824
9825 void BlueStore::_do_write_big(
9826     TransContext *txc,
9827     CollectionRef &c,
9828     OnodeRef o,
9829     uint64_t offset, uint64_t length,
9830     bufferlist::iterator& blp,
9831     WriteContext *wctx)
9832 {
9833   dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
9834            << " target_blob_size 0x" << wctx->target_blob_size << std::dec
9835            << " compress " << (int)wctx->compress
9836            << dendl;
9837   logger->inc(l_bluestore_write_big);
9838   logger->inc(l_bluestore_write_big_bytes, length);
9839   o->extent_map.punch_hole(c, offset, length, &wctx->old_extents);
9840   auto max_bsize = MAX(wctx->target_blob_size, min_alloc_size);
9841   while (length > 0) {
9842     bool new_blob = false;
9843     uint32_t l = MIN(max_bsize, length);
9844     BlobRef b;
9845     uint32_t b_off = 0;
9846
9847     //attempting to reuse existing blob
9848     if (!wctx->compress) {
9849       // look for an existing mutable blob we can reuse
9850       auto begin = o->extent_map.extent_map.begin();
9851       auto end = o->extent_map.extent_map.end();
9852       auto ep = o->extent_map.seek_lextent(offset);
9853       auto prev_ep = ep;
9854       if (prev_ep != begin) {
9855         --prev_ep;
9856       } else {
9857         prev_ep = end; // to avoid this extent check as it's a duplicate
9858       }
9859       auto min_off = offset >= max_bsize ? offset - max_bsize : 0;
9860       // search suitable extent in both forward and reverse direction in
9861       // [offset - target_max_blob_size, offset + target_max_blob_size] range
9862       // then check if blob can be reused via can_reuse_blob func.
9863       bool any_change;
9864       do {
9865         any_change = false;
9866         if (ep != end && ep->logical_offset < offset + max_bsize) {
9867           if (offset >= ep->blob_start() &&
9868               ep->blob->can_reuse_blob(min_alloc_size, max_bsize,
9869                                        offset - ep->blob_start(),
9870                                        &l)) {
9871             b = ep->blob;
9872             b_off = offset - ep->blob_start();
9873             prev_ep = end; // to avoid check below
9874             dout(20) << __func__ << " reuse blob " << *b << std::hex
9875                      << " (0x" << b_off << "~" << l << ")" << std::dec << dendl;
9876           } else {
9877             ++ep;
9878             any_change = true;
9879           }
9880         }
9881
9882         if (prev_ep != end && prev_ep->logical_offset >= min_off) {
9883           if (prev_ep->blob->can_reuse_blob(min_alloc_size, max_bsize,
9884                                             offset - prev_ep->blob_start(),
9885                                             &l)) {
9886             b = prev_ep->blob;
9887             b_off = offset - prev_ep->blob_start();
9888             dout(20) << __func__ << " reuse blob " << *b << std::hex
9889                      << " (0x" << b_off << "~" << l << ")" << std::dec << dendl;
9890           } else if (prev_ep != begin) {
9891             --prev_ep;
9892             any_change = true;
9893           } else {
9894             prev_ep = end; // to avoid useless first extent re-check
9895           }
9896         }
9897       } while (b == nullptr && any_change);
9898     }
9899     if (b == nullptr) {
9900       b = c->new_blob();
9901       b_off = 0;
9902       new_blob = true;
9903     }
9904
9905     bufferlist t;
9906     blp.copy(l, t);
9907     wctx->write(offset, b, l, b_off, t, b_off, l, false, new_blob);
9908     offset += l;
9909     length -= l;
9910     logger->inc(l_bluestore_write_big_blobs);
9911   }
9912 }
9913
9914 int BlueStore::_do_alloc_write(
9915   TransContext *txc,
9916   CollectionRef coll,
9917   OnodeRef o,
9918   WriteContext *wctx)
9919 {
9920   dout(20) << __func__ << " txc " << txc
9921            << " " << wctx->writes.size() << " blobs"
9922            << dendl;
9923   if (wctx->writes.empty()) {
9924     return 0;
9925   }
9926
9927   CompressorRef c;
9928   double crr = 0;
9929   if (wctx->compress) {
9930     c = select_option(
9931       "compression_algorithm",
9932       compressor,
9933       [&]() {
9934         string val;
9935         if (coll->pool_opts.get(pool_opts_t::COMPRESSION_ALGORITHM, &val)) {
9936           CompressorRef cp = compressor;
9937           if (!cp || cp->get_type_name() != val) {
9938             cp = Compressor::create(cct, val);
9939           }
9940           return boost::optional<CompressorRef>(cp);
9941         }
9942         return boost::optional<CompressorRef>();
9943       }
9944     );
9945
9946     crr = select_option(
9947       "compression_required_ratio",
9948       cct->_conf->bluestore_compression_required_ratio,
9949       [&]() {
9950         double val;
9951         if (coll->pool_opts.get(pool_opts_t::COMPRESSION_REQUIRED_RATIO, &val)) {
9952           return boost::optional<double>(val);
9953         }
9954         return boost::optional<double>();
9955       }
9956     );
9957   }
9958
9959   // checksum
9960   int csum = csum_type.load();
9961   csum = select_option(
9962     "csum_type",
9963     csum,
9964     [&]() {
9965       int val;
9966       if (coll->pool_opts.get(pool_opts_t::CSUM_TYPE, &val)) {
9967         return  boost::optional<int>(val);
9968       }
9969       return boost::optional<int>();
9970     }
9971   );
9972
9973   // compress (as needed) and calc needed space
9974   uint64_t need = 0;
9975   auto max_bsize = MAX(wctx->target_blob_size, min_alloc_size);
9976   for (auto& wi : wctx->writes) {
9977     if (c && wi.blob_length > min_alloc_size) {
9978       utime_t start = ceph_clock_now();
9979
9980       // compress
9981       assert(wi.b_off == 0);
9982       assert(wi.blob_length == wi.bl.length());
9983
9984       // FIXME: memory alignment here is bad
9985       bufferlist t;
9986       int r = c->compress(wi.bl, t);
9987       assert(r == 0);
9988
9989       bluestore_compression_header_t chdr;
9990       chdr.type = c->get_type();
9991       chdr.length = t.length();
9992       ::encode(chdr, wi.compressed_bl);
9993       wi.compressed_bl.claim_append(t);
9994
9995       wi.compressed_len = wi.compressed_bl.length();
9996       uint64_t newlen = P2ROUNDUP(wi.compressed_len, min_alloc_size);
9997       uint64_t want_len_raw = wi.blob_length * crr;
9998       uint64_t want_len = P2ROUNDUP(want_len_raw, min_alloc_size);
9999       if (newlen <= want_len && newlen < wi.blob_length) {
10000         // Cool. We compressed at least as much as we were hoping to.
10001         // pad out to min_alloc_size
10002         wi.compressed_bl.append_zero(newlen - wi.compressed_len);
10003         logger->inc(l_bluestore_write_pad_bytes, newlen - wi.compressed_len);
10004         dout(20) << __func__ << std::hex << "  compressed 0x" << wi.blob_length
10005                  << " -> 0x" << wi.compressed_len << " => 0x" << newlen
10006                  << " with " << c->get_type()
10007                  << std::dec << dendl;
10008         txc->statfs_delta.compressed() += wi.compressed_len;
10009         txc->statfs_delta.compressed_original() += wi.blob_length;
10010         txc->statfs_delta.compressed_allocated() += newlen;
10011         logger->inc(l_bluestore_compress_success_count);
10012         wi.compressed = true;
10013         need += newlen;
10014       } else {
10015         dout(20) << __func__ << std::hex << "  0x" << wi.blob_length
10016                  << " compressed to 0x" << wi.compressed_len << " -> 0x" << newlen
10017                  << " with " << c->get_type()
10018                  << ", which is more than required 0x" << want_len_raw
10019                  << " -> 0x" << want_len
10020                  << ", leaving uncompressed"
10021                  << std::dec << dendl;
10022         logger->inc(l_bluestore_compress_rejected_count);
10023         need += wi.blob_length;
10024       }
10025       logger->tinc(l_bluestore_compress_lat,
10026                    ceph_clock_now() - start);
10027     } else {
10028       need += wi.blob_length;
10029     }
10030   }
10031   int r = alloc->reserve(need);
10032   if (r < 0) {
10033     derr << __func__ << " failed to reserve 0x" << std::hex << need << std::dec
10034          << dendl;
10035     return r;
10036   }
10037   AllocExtentVector prealloc;
10038   prealloc.reserve(2 * wctx->writes.size());;
10039   int prealloc_left = 0;
10040   prealloc_left = alloc->allocate(
10041     need, min_alloc_size, need,
10042     0, &prealloc);
10043   assert(prealloc_left == (int64_t)need);
10044   dout(20) << __func__ << " prealloc " << prealloc << dendl;
10045   auto prealloc_pos = prealloc.begin();
10046
10047   for (auto& wi : wctx->writes) {
10048     BlobRef b = wi.b;
10049     bluestore_blob_t& dblob = b->dirty_blob();
10050     uint64_t b_off = wi.b_off;
10051     bufferlist *l = &wi.bl;
10052     uint64_t final_length = wi.blob_length;
10053     uint64_t csum_length = wi.blob_length;
10054     unsigned csum_order = block_size_order;
10055     if (wi.compressed) {
10056       final_length = wi.compressed_bl.length();
10057       csum_length = final_length;
10058       csum_order = ctz(csum_length);
10059       l = &wi.compressed_bl;
10060       dblob.set_compressed(wi.blob_length, wi.compressed_len);
10061     } else if (wi.new_blob) {
10062       // initialize newly created blob only
10063       assert(dblob.is_mutable());
10064       if (l->length() != wi.blob_length) {
10065         // hrm, maybe we could do better here, but let's not bother.
10066         dout(20) << __func__ << " forcing csum_order to block_size_order "
10067                 << block_size_order << dendl;
10068         csum_order = block_size_order;
10069       } else {
10070         csum_order = std::min(wctx->csum_order, ctz(l->length()));
10071       }
10072       // try to align blob with max_blob_size to improve
10073       // its reuse ratio, e.g. in case of reverse write
10074       uint32_t suggested_boff =
10075        (wi.logical_offset - (wi.b_off0 - wi.b_off)) % max_bsize;
10076       if ((suggested_boff % (1 << csum_order)) == 0 &&
10077            suggested_boff + final_length <= max_bsize &&
10078            suggested_boff > b_off) {
10079         dout(20) << __func__ << " forcing blob_offset to 0x"
10080                  << std::hex << suggested_boff << std::dec << dendl;
10081         assert(suggested_boff >= b_off);
10082         csum_length += suggested_boff - b_off;
10083         b_off = suggested_boff;
10084       }
10085       if (csum != Checksummer::CSUM_NONE) {
10086         dout(20) << __func__ << " initialize csum setting for new blob " << *b
10087                  << " csum_type " << Checksummer::get_csum_type_string(csum)
10088                  << " csum_order " << csum_order
10089                  << " csum_length 0x" << std::hex << csum_length << std::dec
10090                  << dendl;
10091         dblob.init_csum(csum, csum_order, csum_length);
10092       }
10093     }
10094
10095     AllocExtentVector extents;
10096     int64_t left = final_length;
10097     while (left > 0) {
10098       assert(prealloc_left > 0);
10099       if (prealloc_pos->length <= left) {
10100         prealloc_left -= prealloc_pos->length;
10101         left -= prealloc_pos->length;
10102         txc->statfs_delta.allocated() += prealloc_pos->length;
10103         extents.push_back(*prealloc_pos);
10104         ++prealloc_pos;
10105       } else {
10106         extents.emplace_back(prealloc_pos->offset, left);
10107         prealloc_pos->offset += left;
10108         prealloc_pos->length -= left;
10109         prealloc_left -= left;
10110         txc->statfs_delta.allocated() += left;
10111         left = 0;
10112         break;
10113       }
10114     }
10115     for (auto& p : extents) {
10116       txc->allocated.insert(p.offset, p.length);
10117     }
10118     dblob.allocated(P2ALIGN(b_off, min_alloc_size), final_length, extents);
10119
10120     dout(20) << __func__ << " blob " << *b << dendl;
10121     if (dblob.has_csum()) {
10122       dblob.calc_csum(b_off, *l);
10123     }
10124
10125     if (wi.mark_unused) {
10126       auto b_end = b_off + wi.bl.length();
10127       if (b_off) {
10128         dblob.add_unused(0, b_off);
10129       }
10130       if (b_end < wi.blob_length) {
10131         dblob.add_unused(b_end, wi.blob_length - b_end);
10132       }
10133     }
10134
10135     Extent *le = o->extent_map.set_lextent(coll, wi.logical_offset,
10136                                            b_off + (wi.b_off0 - wi.b_off),
10137                                            wi.length0,
10138                                            wi.b,
10139                                            nullptr);
10140     wi.b->dirty_blob().mark_used(le->blob_offset, le->length);
10141     txc->statfs_delta.stored() += le->length;
10142     dout(20) << __func__ << "  lex " << *le << dendl;
10143     _buffer_cache_write(txc, wi.b, b_off, wi.bl,
10144                         wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
10145
10146     // queue io
10147     if (!g_conf->bluestore_debug_omit_block_device_write) {
10148       if (l->length() <= prefer_deferred_size.load()) {
10149         dout(20) << __func__ << " deferring small 0x" << std::hex
10150                  << l->length() << std::dec << " write via deferred" << dendl;
10151         bluestore_deferred_op_t *op = _get_deferred_op(txc, o);
10152         op->op = bluestore_deferred_op_t::OP_WRITE;
10153         int r = b->get_blob().map(
10154           b_off, l->length(),
10155           [&](uint64_t offset, uint64_t length) {
10156             op->extents.emplace_back(bluestore_pextent_t(offset, length));
10157             return 0;
10158           });
10159         assert(r == 0);
10160         op->data = *l;
10161       } else {
10162         b->get_blob().map_bl(
10163           b_off, *l,
10164           [&](uint64_t offset, bufferlist& t) {
10165             bdev->aio_write(offset, t, &txc->ioc, false);
10166           });
10167       }
10168     }
10169   }
10170   assert(prealloc_pos == prealloc.end());
10171   assert(prealloc_left == 0);
10172   return 0;
10173 }
10174
10175 void BlueStore::_wctx_finish(
10176   TransContext *txc,
10177   CollectionRef& c,
10178   OnodeRef o,
10179   WriteContext *wctx,
10180   set<SharedBlob*> *maybe_unshared_blobs)
10181 {
10182   auto oep = wctx->old_extents.begin();
10183   while (oep != wctx->old_extents.end()) {
10184     auto &lo = *oep;
10185     oep = wctx->old_extents.erase(oep);
10186     dout(20) << __func__ << " lex_old " << lo.e << dendl;
10187     BlobRef b = lo.e.blob;
10188     const bluestore_blob_t& blob = b->get_blob();
10189     if (blob.is_compressed()) {
10190       if (lo.blob_empty) {
10191         txc->statfs_delta.compressed() -= blob.get_compressed_payload_length();
10192       }
10193       txc->statfs_delta.compressed_original() -= lo.e.length;
10194     }
10195     auto& r = lo.r;
10196     txc->statfs_delta.stored() -= lo.e.length;
10197     if (!r.empty()) {
10198       dout(20) << __func__ << "  blob release " << r << dendl;
10199       if (blob.is_shared()) {
10200         PExtentVector final;
10201         c->load_shared_blob(b->shared_blob);
10202         for (auto e : r) {
10203           b->shared_blob->put_ref(
10204             e.offset, e.length, &final,
10205             b->is_referenced() ? nullptr : maybe_unshared_blobs);
10206         }
10207         dout(20) << __func__ << "  shared_blob release " << final
10208                  << " from " << *b->shared_blob << dendl;
10209         txc->write_shared_blob(b->shared_blob);
10210         r.clear();
10211         r.swap(final);
10212       }
10213     }
10214     // we can't invalidate our logical extents as we drop them because
10215     // other lextents (either in our onode or others) may still
10216     // reference them.  but we can throw out anything that is no
10217     // longer allocated.  Note that this will leave behind edge bits
10218     // that are no longer referenced but not deallocated (until they
10219     // age out of the cache naturally).
10220     b->discard_unallocated(c.get());
10221     for (auto e : r) {
10222       dout(20) << __func__ << "  release " << e << dendl;
10223       txc->released.insert(e.offset, e.length);
10224       txc->statfs_delta.allocated() -= e.length;
10225       if (blob.is_compressed()) {
10226         txc->statfs_delta.compressed_allocated() -= e.length;
10227       }
10228     }
10229     delete &lo;
10230     if (b->is_spanning() && !b->is_referenced()) {
10231       dout(20) << __func__ << "  spanning_blob_map removing empty " << *b
10232                << dendl;
10233       o->extent_map.spanning_blob_map.erase(b->id);
10234     }
10235   }
10236 }
10237
10238 void BlueStore::_do_write_data(
10239   TransContext *txc,
10240   CollectionRef& c,
10241   OnodeRef o,
10242   uint64_t offset,
10243   uint64_t length,
10244   bufferlist& bl,
10245   WriteContext *wctx)
10246 {
10247   uint64_t end = offset + length;
10248   bufferlist::iterator p = bl.begin();
10249
10250   if (offset / min_alloc_size == (end - 1) / min_alloc_size &&
10251       (length != min_alloc_size)) {
10252     // we fall within the same block
10253     _do_write_small(txc, c, o, offset, length, p, wctx);
10254   } else {
10255     uint64_t head_offset, head_length;
10256     uint64_t middle_offset, middle_length;
10257     uint64_t tail_offset, tail_length;
10258
10259     head_offset = offset;
10260     head_length = P2NPHASE(offset, min_alloc_size);
10261
10262     tail_offset = P2ALIGN(end, min_alloc_size);
10263     tail_length = P2PHASE(end, min_alloc_size);
10264
10265     middle_offset = head_offset + head_length;
10266     middle_length = length - head_length - tail_length;
10267
10268     if (head_length) {
10269       _do_write_small(txc, c, o, head_offset, head_length, p, wctx);
10270     }
10271
10272     if (middle_length) {
10273       _do_write_big(txc, c, o, middle_offset, middle_length, p, wctx);
10274     }
10275
10276     if (tail_length) {
10277       _do_write_small(txc, c, o, tail_offset, tail_length, p, wctx);
10278     }
10279   }
10280 }
10281
10282 void BlueStore::_choose_write_options(
10283    CollectionRef& c,
10284    OnodeRef o,
10285    uint32_t fadvise_flags,
10286    WriteContext *wctx)
10287 {
10288   if (fadvise_flags & CEPH_OSD_OP_FLAG_FADVISE_WILLNEED) {
10289     dout(20) << __func__ << " will do buffered write" << dendl;
10290     wctx->buffered = true;
10291   } else if (cct->_conf->bluestore_default_buffered_write &&
10292              (fadvise_flags & (CEPH_OSD_OP_FLAG_FADVISE_DONTNEED |
10293                                CEPH_OSD_OP_FLAG_FADVISE_NOCACHE)) == 0) {
10294     dout(20) << __func__ << " defaulting to buffered write" << dendl;
10295     wctx->buffered = true;
10296   }
10297
10298   // apply basic csum block size
10299   wctx->csum_order = block_size_order;
10300
10301   // compression parameters
10302   unsigned alloc_hints = o->onode.alloc_hint_flags;
10303   auto cm = select_option(
10304     "compression_mode",
10305     comp_mode.load(),
10306     [&]() {
10307       string val;
10308       if(c->pool_opts.get(pool_opts_t::COMPRESSION_MODE, &val)) {
10309         return boost::optional<Compressor::CompressionMode>(
10310           Compressor::get_comp_mode_type(val));
10311       }
10312       return boost::optional<Compressor::CompressionMode>();
10313     }
10314   );
10315
10316   wctx->compress = (cm != Compressor::COMP_NONE) &&
10317     ((cm == Compressor::COMP_FORCE) ||
10318      (cm == Compressor::COMP_AGGRESSIVE &&
10319       (alloc_hints & CEPH_OSD_ALLOC_HINT_FLAG_INCOMPRESSIBLE) == 0) ||
10320      (cm == Compressor::COMP_PASSIVE &&
10321       (alloc_hints & CEPH_OSD_ALLOC_HINT_FLAG_COMPRESSIBLE)));
10322
10323   if ((alloc_hints & CEPH_OSD_ALLOC_HINT_FLAG_SEQUENTIAL_READ) &&
10324       (alloc_hints & CEPH_OSD_ALLOC_HINT_FLAG_RANDOM_READ) == 0 &&
10325       (alloc_hints & (CEPH_OSD_ALLOC_HINT_FLAG_IMMUTABLE |
10326                       CEPH_OSD_ALLOC_HINT_FLAG_APPEND_ONLY)) &&
10327       (alloc_hints & CEPH_OSD_ALLOC_HINT_FLAG_RANDOM_WRITE) == 0) {
10328
10329     dout(20) << __func__ << " will prefer large blob and csum sizes" << dendl;
10330
10331     if (o->onode.expected_write_size) {
10332       wctx->csum_order = std::max(min_alloc_size_order,
10333                                   (uint8_t)ctz(o->onode.expected_write_size));
10334     } else {
10335       wctx->csum_order = min_alloc_size_order;
10336     }
10337
10338     if (wctx->compress) {
10339       wctx->target_blob_size = select_option(
10340         "compression_max_blob_size",
10341         comp_max_blob_size.load(),
10342         [&]() {
10343           int val;
10344           if(c->pool_opts.get(pool_opts_t::COMPRESSION_MAX_BLOB_SIZE, &val)) {
10345             return boost::optional<uint64_t>((uint64_t)val);
10346           }
10347           return boost::optional<uint64_t>();
10348         }
10349       );
10350     }
10351   } else {
10352     if (wctx->compress) {
10353       wctx->target_blob_size = select_option(
10354         "compression_min_blob_size",
10355         comp_min_blob_size.load(),
10356         [&]() {
10357           int val;
10358           if(c->pool_opts.get(pool_opts_t::COMPRESSION_MIN_BLOB_SIZE, &val)) {
10359             return boost::optional<uint64_t>((uint64_t)val);
10360           }
10361           return boost::optional<uint64_t>();
10362         }
10363       );
10364     }
10365   }
10366
10367   uint64_t max_bsize = max_blob_size.load();
10368   if (wctx->target_blob_size == 0 || wctx->target_blob_size > max_bsize) {
10369     wctx->target_blob_size = max_bsize;
10370   }
10371
10372   // set the min blob size floor at 2x the min_alloc_size, or else we
10373   // won't be able to allocate a smaller extent for the compressed
10374   // data.
10375   if (wctx->compress &&
10376       wctx->target_blob_size < min_alloc_size * 2) {
10377     wctx->target_blob_size = min_alloc_size * 2;
10378   }
10379
10380   dout(20) << __func__ << " prefer csum_order " << wctx->csum_order
10381            << " target_blob_size 0x" << std::hex << wctx->target_blob_size
10382            << std::dec << dendl;
10383 }
10384
10385 int BlueStore::_do_gc(
10386   TransContext *txc,
10387   CollectionRef& c,
10388   OnodeRef o,
10389   const GarbageCollector& gc,
10390   const WriteContext& wctx,
10391   uint64_t *dirty_start,
10392   uint64_t *dirty_end)
10393 {
10394   auto& extents_to_collect = gc.get_extents_to_collect();
10395
10396   WriteContext wctx_gc;
10397   wctx_gc.fork(wctx); // make a clone for garbage collection
10398
10399   for (auto it = extents_to_collect.begin();
10400        it != extents_to_collect.end();
10401        ++it) {
10402     bufferlist bl;
10403     int r = _do_read(c.get(), o, it->offset, it->length, bl, 0);
10404     assert(r == (int)it->length);
10405
10406     o->extent_map.fault_range(db, it->offset, it->length);
10407     _do_write_data(txc, c, o, it->offset, it->length, bl, &wctx_gc);
10408     logger->inc(l_bluestore_gc_merged, it->length);
10409
10410     if (*dirty_start > it->offset) {
10411       *dirty_start = it->offset;
10412     }
10413
10414     if (*dirty_end < it->offset + it->length) {
10415       *dirty_end = it->offset + it->length;
10416     }
10417   }
10418
10419   dout(30) << __func__ << " alloc write" << dendl;
10420   int r = _do_alloc_write(txc, c, o, &wctx_gc);
10421   if (r < 0) {
10422     derr << __func__ << " _do_alloc_write failed with " << cpp_strerror(r)
10423          << dendl;
10424     return r;
10425   }
10426
10427   _wctx_finish(txc, c, o, &wctx_gc);
10428   return 0;
10429 }
10430
10431 int BlueStore::_do_write(
10432   TransContext *txc,
10433   CollectionRef& c,
10434   OnodeRef o,
10435   uint64_t offset,
10436   uint64_t length,
10437   bufferlist& bl,
10438   uint32_t fadvise_flags)
10439 {
10440   int r = 0;
10441
10442   dout(20) << __func__
10443            << " " << o->oid
10444            << " 0x" << std::hex << offset << "~" << length
10445            << " - have 0x" << o->onode.size
10446            << " (" << std::dec << o->onode.size << ")"
10447            << " bytes"
10448            << " fadvise_flags 0x" << std::hex << fadvise_flags << std::dec
10449            << dendl;
10450   _dump_onode(o);
10451
10452   if (length == 0) {
10453     return 0;
10454   }
10455
10456   uint64_t end = offset + length;
10457
10458   GarbageCollector gc(c->store->cct);
10459   int64_t benefit;
10460   auto dirty_start = offset;
10461   auto dirty_end = end;
10462
10463   WriteContext wctx;
10464   _choose_write_options(c, o, fadvise_flags, &wctx);
10465   o->extent_map.fault_range(db, offset, length);
10466   _do_write_data(txc, c, o, offset, length, bl, &wctx);
10467   r = _do_alloc_write(txc, c, o, &wctx);
10468   if (r < 0) {
10469     derr << __func__ << " _do_alloc_write failed with " << cpp_strerror(r)
10470          << dendl;
10471     goto out;
10472   }
10473
10474   // NB: _wctx_finish() will empty old_extents
10475   // so we must do gc estimation before that
10476   benefit = gc.estimate(offset,
10477                         length,
10478                         o->extent_map,
10479                         wctx.old_extents,
10480                         min_alloc_size);
10481
10482   _wctx_finish(txc, c, o, &wctx);
10483   if (end > o->onode.size) {
10484     dout(20) << __func__ << " extending size to 0x" << std::hex << end
10485              << std::dec << dendl;
10486     o->onode.size = end;
10487   }
10488
10489   if (benefit >= g_conf->bluestore_gc_enable_total_threshold) {
10490     if (!gc.get_extents_to_collect().empty()) {
10491       dout(20) << __func__ << " perform garbage collection, "
10492                << "expected benefit = " << benefit << " AUs" << dendl;
10493       r = _do_gc(txc, c, o, gc, wctx, &dirty_start, &dirty_end);
10494       if (r < 0) {
10495         derr << __func__ << " _do_gc failed with " << cpp_strerror(r)
10496              << dendl;
10497         goto out;
10498       }
10499     }
10500   }
10501
10502   o->extent_map.compress_extent_map(dirty_start, dirty_end - dirty_start);
10503   o->extent_map.dirty_range(dirty_start, dirty_end - dirty_start);
10504
10505   r = 0;
10506
10507  out:
10508   return r;
10509 }
10510
10511 int BlueStore::_write(TransContext *txc,
10512                       CollectionRef& c,
10513                       OnodeRef& o,
10514                       uint64_t offset, size_t length,
10515                       bufferlist& bl,
10516                       uint32_t fadvise_flags)
10517 {
10518   dout(15) << __func__ << " " << c->cid << " " << o->oid
10519            << " 0x" << std::hex << offset << "~" << length << std::dec
10520            << dendl;
10521   int r = 0;
10522   if (offset + length >= OBJECT_MAX_SIZE) {
10523     r = -E2BIG;
10524   } else {
10525     _assign_nid(txc, o);
10526     r = _do_write(txc, c, o, offset, length, bl, fadvise_flags);
10527     txc->write_onode(o);
10528   }
10529   dout(10) << __func__ << " " << c->cid << " " << o->oid
10530            << " 0x" << std::hex << offset << "~" << length << std::dec
10531            << " = " << r << dendl;
10532   return r;
10533 }
10534
10535 int BlueStore::_zero(TransContext *txc,
10536                      CollectionRef& c,
10537                      OnodeRef& o,
10538                      uint64_t offset, size_t length)
10539 {
10540   dout(15) << __func__ << " " << c->cid << " " << o->oid
10541            << " 0x" << std::hex << offset << "~" << length << std::dec
10542            << dendl;
10543   int r = 0;
10544   if (offset + length >= OBJECT_MAX_SIZE) {
10545     r = -E2BIG;
10546   } else {
10547     _assign_nid(txc, o);
10548     r = _do_zero(txc, c, o, offset, length);
10549   }
10550   dout(10) << __func__ << " " << c->cid << " " << o->oid
10551            << " 0x" << std::hex << offset << "~" << length << std::dec
10552            << " = " << r << dendl;
10553   return r;
10554 }
10555
10556 int BlueStore::_do_zero(TransContext *txc,
10557                         CollectionRef& c,
10558                         OnodeRef& o,
10559                         uint64_t offset, size_t length)
10560 {
10561   dout(15) << __func__ << " " << c->cid << " " << o->oid
10562            << " 0x" << std::hex << offset << "~" << length << std::dec
10563            << dendl;
10564   int r = 0;
10565
10566   _dump_onode(o);
10567
10568   WriteContext wctx;
10569   o->extent_map.fault_range(db, offset, length);
10570   o->extent_map.punch_hole(c, offset, length, &wctx.old_extents);
10571   o->extent_map.dirty_range(offset, length);
10572   _wctx_finish(txc, c, o, &wctx);
10573
10574   if (offset + length > o->onode.size) {
10575     o->onode.size = offset + length;
10576     dout(20) << __func__ << " extending size to " << offset + length
10577              << dendl;
10578   }
10579   txc->write_onode(o);
10580
10581   dout(10) << __func__ << " " << c->cid << " " << o->oid
10582            << " 0x" << std::hex << offset << "~" << length << std::dec
10583            << " = " << r << dendl;
10584   return r;
10585 }
10586
10587 void BlueStore::_do_truncate(
10588   TransContext *txc, CollectionRef& c, OnodeRef o, uint64_t offset,
10589   set<SharedBlob*> *maybe_unshared_blobs)
10590 {
10591   dout(15) << __func__ << " " << c->cid << " " << o->oid
10592            << " 0x" << std::hex << offset << std::dec << dendl;
10593
10594   _dump_onode(o, 30);
10595
10596   if (offset == o->onode.size)
10597     return;
10598
10599   if (offset < o->onode.size) {
10600     WriteContext wctx;
10601     uint64_t length = o->onode.size - offset;
10602     o->extent_map.fault_range(db, offset, length);
10603     o->extent_map.punch_hole(c, offset, length, &wctx.old_extents);
10604     o->extent_map.dirty_range(offset, length);
10605     _wctx_finish(txc, c, o, &wctx, maybe_unshared_blobs);
10606
10607     // if we have shards past EOF, ask for a reshard
10608     if (!o->onode.extent_map_shards.empty() &&
10609         o->onode.extent_map_shards.back().offset >= offset) {
10610       dout(10) << __func__ << "  request reshard past EOF" << dendl;
10611       if (offset) {
10612         o->extent_map.request_reshard(offset - 1, offset + length);
10613       } else {
10614         o->extent_map.request_reshard(0, length);
10615       }
10616     }
10617   }
10618
10619   o->onode.size = offset;
10620
10621   txc->write_onode(o);
10622 }
10623
10624 int BlueStore::_truncate(TransContext *txc,
10625                          CollectionRef& c,
10626                          OnodeRef& o,
10627                          uint64_t offset)
10628 {
10629   dout(15) << __func__ << " " << c->cid << " " << o->oid
10630            << " 0x" << std::hex << offset << std::dec
10631            << dendl;
10632   int r = 0;
10633   if (offset >= OBJECT_MAX_SIZE) {
10634     r = -E2BIG;
10635   } else {
10636     _do_truncate(txc, c, o, offset);
10637   }
10638   dout(10) << __func__ << " " << c->cid << " " << o->oid
10639            << " 0x" << std::hex << offset << std::dec
10640            << " = " << r << dendl;
10641   return r;
10642 }
10643
10644 int BlueStore::_do_remove(
10645   TransContext *txc,
10646   CollectionRef& c,
10647   OnodeRef o)
10648 {
10649   set<SharedBlob*> maybe_unshared_blobs;
10650   bool is_gen = !o->oid.is_no_gen();
10651   _do_truncate(txc, c, o, 0, is_gen ? &maybe_unshared_blobs : nullptr);
10652   if (o->onode.has_omap()) {
10653     o->flush();
10654     _do_omap_clear(txc, o->onode.nid);
10655   }
10656   o->exists = false;
10657   string key;
10658   for (auto &s : o->extent_map.shards) {
10659     dout(20) << __func__ << "  removing shard 0x" << std::hex
10660              << s.shard_info->offset << std::dec << dendl;
10661     generate_extent_shard_key_and_apply(o->key, s.shard_info->offset, &key,
10662       [&](const string& final_key) {
10663         txc->t->rmkey(PREFIX_OBJ, final_key);
10664       }
10665     );
10666   }
10667   txc->t->rmkey(PREFIX_OBJ, o->key.c_str(), o->key.size());
10668   txc->removed(o);
10669   o->extent_map.clear();
10670   o->onode = bluestore_onode_t();
10671   _debug_obj_on_delete(o->oid);
10672
10673   if (!is_gen || maybe_unshared_blobs.empty()) {
10674     return 0;
10675   }
10676
10677   // see if we can unshare blobs still referenced by the head
10678   dout(10) << __func__ << " gen and maybe_unshared_blobs "
10679            << maybe_unshared_blobs << dendl;
10680   ghobject_t nogen = o->oid;
10681   nogen.generation = ghobject_t::NO_GEN;
10682   OnodeRef h = c->onode_map.lookup(nogen);
10683
10684   if (!h || !h->exists) {
10685     return 0;
10686   }
10687
10688   dout(20) << __func__ << " checking for unshareable blobs on " << h
10689            << " " << h->oid << dendl;
10690   map<SharedBlob*,bluestore_extent_ref_map_t> expect;
10691   for (auto& e : h->extent_map.extent_map) {
10692     const bluestore_blob_t& b = e.blob->get_blob();
10693     SharedBlob *sb = e.blob->shared_blob.get();
10694     if (b.is_shared() &&
10695         sb->loaded &&
10696         maybe_unshared_blobs.count(sb)) {
10697       if (b.is_compressed()) {
10698         expect[sb].get(0, b.get_ondisk_length());
10699       } else {
10700         b.map(e.blob_offset, e.length, [&](uint64_t off, uint64_t len) {
10701             expect[sb].get(off, len);
10702             return 0;
10703           });
10704       }
10705     }
10706   }
10707
10708   vector<SharedBlob*> unshared_blobs;
10709   unshared_blobs.reserve(maybe_unshared_blobs.size());
10710   for (auto& p : expect) {
10711     dout(20) << " ? " << *p.first << " vs " << p.second << dendl;
10712     if (p.first->persistent->ref_map == p.second) {
10713       SharedBlob *sb = p.first;
10714       dout(20) << __func__ << "  unsharing " << *sb << dendl;
10715       unshared_blobs.push_back(sb);
10716       txc->unshare_blob(sb);
10717       uint64_t sbid = c->make_blob_unshared(sb);
10718       string key;
10719       get_shared_blob_key(sbid, &key);
10720       txc->t->rmkey(PREFIX_SHARED_BLOB, key);
10721     }
10722   }
10723
10724   if (unshared_blobs.empty()) {
10725     return 0;
10726   }
10727
10728   for (auto& e : h->extent_map.extent_map) {
10729     const bluestore_blob_t& b = e.blob->get_blob();
10730     SharedBlob *sb = e.blob->shared_blob.get();
10731     if (b.is_shared() &&
10732         std::find(unshared_blobs.begin(), unshared_blobs.end(),
10733                   sb) != unshared_blobs.end()) {
10734       dout(20) << __func__ << "  unsharing " << e << dendl;
10735       bluestore_blob_t& blob = e.blob->dirty_blob();
10736       blob.clear_flag(bluestore_blob_t::FLAG_SHARED);
10737       h->extent_map.dirty_range(e.logical_offset, 1);
10738     }
10739   }
10740   txc->write_onode(h);
10741
10742   return 0;
10743 }
10744
10745 int BlueStore::_remove(TransContext *txc,
10746                        CollectionRef& c,
10747                        OnodeRef &o)
10748 {
10749   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
10750   int r = _do_remove(txc, c, o);
10751   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
10752   return r;
10753 }
10754
10755 int BlueStore::_setattr(TransContext *txc,
10756                         CollectionRef& c,
10757                         OnodeRef& o,
10758                         const string& name,
10759                         bufferptr& val)
10760 {
10761   dout(15) << __func__ << " " << c->cid << " " << o->oid
10762            << " " << name << " (" << val.length() << " bytes)"
10763            << dendl;
10764   int r = 0;
10765   if (val.is_partial()) {
10766     auto& b = o->onode.attrs[name.c_str()] = bufferptr(val.c_str(),
10767                                                        val.length());
10768     b.reassign_to_mempool(mempool::mempool_bluestore_cache_other);
10769   } else {
10770     auto& b = o->onode.attrs[name.c_str()] = val;
10771     b.reassign_to_mempool(mempool::mempool_bluestore_cache_other);
10772   }
10773   txc->write_onode(o);
10774   dout(10) << __func__ << " " << c->cid << " " << o->oid
10775            << " " << name << " (" << val.length() << " bytes)"
10776            << " = " << r << dendl;
10777   return r;
10778 }
10779
10780 int BlueStore::_setattrs(TransContext *txc,
10781                          CollectionRef& c,
10782                          OnodeRef& o,
10783                          const map<string,bufferptr>& aset)
10784 {
10785   dout(15) << __func__ << " " << c->cid << " " << o->oid
10786            << " " << aset.size() << " keys"
10787            << dendl;
10788   int r = 0;
10789   for (map<string,bufferptr>::const_iterator p = aset.begin();
10790        p != aset.end(); ++p) {
10791     if (p->second.is_partial()) {
10792       auto& b = o->onode.attrs[p->first.c_str()] =
10793         bufferptr(p->second.c_str(), p->second.length());
10794       b.reassign_to_mempool(mempool::mempool_bluestore_cache_other);
10795     } else {
10796       auto& b = o->onode.attrs[p->first.c_str()] = p->second;
10797       b.reassign_to_mempool(mempool::mempool_bluestore_cache_other);
10798     }
10799   }
10800   txc->write_onode(o);
10801   dout(10) << __func__ << " " << c->cid << " " << o->oid
10802            << " " << aset.size() << " keys"
10803            << " = " << r << dendl;
10804   return r;
10805 }
10806
10807
10808 int BlueStore::_rmattr(TransContext *txc,
10809                        CollectionRef& c,
10810                        OnodeRef& o,
10811                        const string& name)
10812 {
10813   dout(15) << __func__ << " " << c->cid << " " << o->oid
10814            << " " << name << dendl;
10815   int r = 0;
10816   auto it = o->onode.attrs.find(name.c_str());
10817   if (it == o->onode.attrs.end())
10818     goto out;
10819
10820   o->onode.attrs.erase(it);
10821   txc->write_onode(o);
10822
10823  out:
10824   dout(10) << __func__ << " " << c->cid << " " << o->oid
10825            << " " << name << " = " << r << dendl;
10826   return r;
10827 }
10828
10829 int BlueStore::_rmattrs(TransContext *txc,
10830                         CollectionRef& c,
10831                         OnodeRef& o)
10832 {
10833   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
10834   int r = 0;
10835
10836   if (o->onode.attrs.empty())
10837     goto out;
10838
10839   o->onode.attrs.clear();
10840   txc->write_onode(o);
10841
10842  out:
10843   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
10844   return r;
10845 }
10846
10847 void BlueStore::_do_omap_clear(TransContext *txc, uint64_t id)
10848 {
10849   KeyValueDB::Iterator it = db->get_iterator(PREFIX_OMAP);
10850   string prefix, tail;
10851   get_omap_header(id, &prefix);
10852   get_omap_tail(id, &tail);
10853   it->lower_bound(prefix);
10854   while (it->valid()) {
10855     if (it->key() >= tail) {
10856       dout(30) << __func__ << "  stop at " << pretty_binary_string(tail)
10857                << dendl;
10858       break;
10859     }
10860     txc->t->rmkey(PREFIX_OMAP, it->key());
10861     dout(30) << __func__ << "  rm " << pretty_binary_string(it->key()) << dendl;
10862     it->next();
10863   }
10864 }
10865
10866 int BlueStore::_omap_clear(TransContext *txc,
10867                            CollectionRef& c,
10868                            OnodeRef& o)
10869 {
10870   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
10871   int r = 0;
10872   if (o->onode.has_omap()) {
10873     o->flush();
10874     _do_omap_clear(txc, o->onode.nid);
10875     o->onode.clear_omap_flag();
10876     txc->write_onode(o);
10877   }
10878   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
10879   return r;
10880 }
10881
10882 int BlueStore::_omap_setkeys(TransContext *txc,
10883                              CollectionRef& c,
10884                              OnodeRef& o,
10885                              bufferlist &bl)
10886 {
10887   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
10888   int r;
10889   bufferlist::iterator p = bl.begin();
10890   __u32 num;
10891   if (!o->onode.has_omap()) {
10892     o->onode.set_omap_flag();
10893     txc->write_onode(o);
10894   } else {
10895     txc->note_modified_object(o);
10896   }
10897   string final_key;
10898   _key_encode_u64(o->onode.nid, &final_key);
10899   final_key.push_back('.');
10900   ::decode(num, p);
10901   while (num--) {
10902     string key;
10903     bufferlist value;
10904     ::decode(key, p);
10905     ::decode(value, p);
10906     final_key.resize(9); // keep prefix
10907     final_key += key;
10908     dout(30) << __func__ << "  " << pretty_binary_string(final_key)
10909              << " <- " << key << dendl;
10910     txc->t->set(PREFIX_OMAP, final_key, value);
10911   }
10912   r = 0;
10913   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
10914   return r;
10915 }
10916
10917 int BlueStore::_omap_setheader(TransContext *txc,
10918                                CollectionRef& c,
10919                                OnodeRef &o,
10920                                bufferlist& bl)
10921 {
10922   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
10923   int r;
10924   string key;
10925   if (!o->onode.has_omap()) {
10926     o->onode.set_omap_flag();
10927     txc->write_onode(o);
10928   } else {
10929     txc->note_modified_object(o);
10930   }
10931   get_omap_header(o->onode.nid, &key);
10932   txc->t->set(PREFIX_OMAP, key, bl);
10933   r = 0;
10934   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
10935   return r;
10936 }
10937
10938 int BlueStore::_omap_rmkeys(TransContext *txc,
10939                             CollectionRef& c,
10940                             OnodeRef& o,
10941                             bufferlist& bl)
10942 {
10943   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
10944   int r = 0;
10945   bufferlist::iterator p = bl.begin();
10946   __u32 num;
10947   string final_key;
10948
10949   if (!o->onode.has_omap()) {
10950     goto out;
10951   }
10952   _key_encode_u64(o->onode.nid, &final_key);
10953   final_key.push_back('.');
10954   ::decode(num, p);
10955   while (num--) {
10956     string key;
10957     ::decode(key, p);
10958     final_key.resize(9); // keep prefix
10959     final_key += key;
10960     dout(30) << __func__ << "  rm " << pretty_binary_string(final_key)
10961              << " <- " << key << dendl;
10962     txc->t->rmkey(PREFIX_OMAP, final_key);
10963   }
10964   txc->note_modified_object(o);
10965
10966  out:
10967   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
10968   return r;
10969 }
10970
10971 int BlueStore::_omap_rmkey_range(TransContext *txc,
10972                                  CollectionRef& c,
10973                                  OnodeRef& o,
10974                                  const string& first, const string& last)
10975 {
10976   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
10977   KeyValueDB::Iterator it;
10978   string key_first, key_last;
10979   int r = 0;
10980   if (!o->onode.has_omap()) {
10981     goto out;
10982   }
10983   o->flush();
10984   it = db->get_iterator(PREFIX_OMAP);
10985   get_omap_key(o->onode.nid, first, &key_first);
10986   get_omap_key(o->onode.nid, last, &key_last);
10987   it->lower_bound(key_first);
10988   while (it->valid()) {
10989     if (it->key() >= key_last) {
10990       dout(30) << __func__ << "  stop at " << pretty_binary_string(key_last)
10991                << dendl;
10992       break;
10993     }
10994     txc->t->rmkey(PREFIX_OMAP, it->key());
10995     dout(30) << __func__ << "  rm " << pretty_binary_string(it->key()) << dendl;
10996     it->next();
10997   }
10998   txc->note_modified_object(o);
10999
11000  out:
11001   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
11002   return r;
11003 }
11004
11005 int BlueStore::_set_alloc_hint(
11006   TransContext *txc,
11007   CollectionRef& c,
11008   OnodeRef& o,
11009   uint64_t expected_object_size,
11010   uint64_t expected_write_size,
11011   uint32_t flags)
11012 {
11013   dout(15) << __func__ << " " << c->cid << " " << o->oid
11014            << " object_size " << expected_object_size
11015            << " write_size " << expected_write_size
11016            << " flags " << ceph_osd_alloc_hint_flag_string(flags)
11017            << dendl;
11018   int r = 0;
11019   o->onode.expected_object_size = expected_object_size;
11020   o->onode.expected_write_size = expected_write_size;
11021   o->onode.alloc_hint_flags = flags;
11022   txc->write_onode(o);
11023   dout(10) << __func__ << " " << c->cid << " " << o->oid
11024            << " object_size " << expected_object_size
11025            << " write_size " << expected_write_size
11026            << " flags " << ceph_osd_alloc_hint_flag_string(flags)
11027            << " = " << r << dendl;
11028   return r;
11029 }
11030
11031 int BlueStore::_clone(TransContext *txc,
11032                       CollectionRef& c,
11033                       OnodeRef& oldo,
11034                       OnodeRef& newo)
11035 {
11036   dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
11037            << newo->oid << dendl;
11038   int r = 0;
11039   if (oldo->oid.hobj.get_hash() != newo->oid.hobj.get_hash()) {
11040     derr << __func__ << " mismatched hash on " << oldo->oid
11041          << " and " << newo->oid << dendl;
11042     return -EINVAL;
11043   }
11044
11045   _assign_nid(txc, newo);
11046
11047   // clone data
11048   oldo->flush();
11049   _do_truncate(txc, c, newo, 0);
11050   if (cct->_conf->bluestore_clone_cow) {
11051     _do_clone_range(txc, c, oldo, newo, 0, oldo->onode.size, 0);
11052   } else {
11053     bufferlist bl;
11054     r = _do_read(c.get(), oldo, 0, oldo->onode.size, bl, 0);
11055     if (r < 0)
11056       goto out;
11057     r = _do_write(txc, c, newo, 0, oldo->onode.size, bl, 0);
11058     if (r < 0)
11059       goto out;
11060   }
11061
11062   // clone attrs
11063   newo->onode.attrs = oldo->onode.attrs;
11064
11065   // clone omap
11066   if (newo->onode.has_omap()) {
11067     dout(20) << __func__ << " clearing old omap data" << dendl;
11068     newo->flush();
11069     _do_omap_clear(txc, newo->onode.nid);
11070   }
11071   if (oldo->onode.has_omap()) {
11072     dout(20) << __func__ << " copying omap data" << dendl;
11073     if (!newo->onode.has_omap()) {
11074       newo->onode.set_omap_flag();
11075     }
11076     KeyValueDB::Iterator it = db->get_iterator(PREFIX_OMAP);
11077     string head, tail;
11078     get_omap_header(oldo->onode.nid, &head);
11079     get_omap_tail(oldo->onode.nid, &tail);
11080     it->lower_bound(head);
11081     while (it->valid()) {
11082       if (it->key() >= tail) {
11083         dout(30) << __func__ << "  reached tail" << dendl;
11084         break;
11085       } else {
11086         dout(30) << __func__ << "  got header/data "
11087                  << pretty_binary_string(it->key()) << dendl;
11088         string key;
11089         rewrite_omap_key(newo->onode.nid, it->key(), &key);
11090         txc->t->set(PREFIX_OMAP, key, it->value());
11091       }
11092       it->next();
11093     }
11094   } else {
11095     newo->onode.clear_omap_flag();
11096   }
11097
11098   txc->write_onode(newo);
11099   r = 0;
11100
11101  out:
11102   dout(10) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
11103            << newo->oid << " = " << r << dendl;
11104   return r;
11105 }
11106
11107 int BlueStore::_do_clone_range(
11108   TransContext *txc,
11109   CollectionRef& c,
11110   OnodeRef& oldo,
11111   OnodeRef& newo,
11112   uint64_t srcoff,
11113   uint64_t length,
11114   uint64_t dstoff)
11115 {
11116   dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
11117            << newo->oid
11118            << " 0x" << std::hex << srcoff << "~" << length << " -> "
11119            << " 0x" << dstoff << "~" << length << std::dec << dendl;
11120   oldo->extent_map.fault_range(db, srcoff, length);
11121   newo->extent_map.fault_range(db, dstoff, length);
11122   _dump_onode(oldo);
11123   _dump_onode(newo);
11124
11125   // hmm, this could go into an ExtentMap::dup() method.
11126   vector<BlobRef> id_to_blob(oldo->extent_map.extent_map.size());
11127   for (auto &e : oldo->extent_map.extent_map) {
11128     e.blob->last_encoded_id = -1;
11129   }
11130   int n = 0;
11131   uint64_t end = srcoff + length;
11132   uint32_t dirty_range_begin = 0;
11133   uint32_t dirty_range_end = 0;
11134   bool src_dirty = false;
11135   for (auto ep = oldo->extent_map.seek_lextent(srcoff);
11136        ep != oldo->extent_map.extent_map.end();
11137        ++ep) {
11138     auto& e = *ep;
11139     if (e.logical_offset >= end) {
11140       break;
11141     }
11142     dout(20) << __func__ << "  src " << e << dendl;
11143     BlobRef cb;
11144     bool blob_duped = true;
11145     if (e.blob->last_encoded_id >= 0) {
11146       // blob is already duped
11147       cb = id_to_blob[e.blob->last_encoded_id];
11148       blob_duped = false;
11149     } else {
11150       // dup the blob
11151       const bluestore_blob_t& blob = e.blob->get_blob();
11152       // make sure it is shared
11153       if (!blob.is_shared()) {
11154         c->make_blob_shared(_assign_blobid(txc), e.blob);
11155         if (!src_dirty) {
11156           src_dirty = true;
11157           dirty_range_begin = e.logical_offset;
11158         }
11159         assert(e.logical_end() > 0);
11160         // -1 to exclude next potential shard
11161         dirty_range_end = e.logical_end() - 1;
11162       } else {
11163         c->load_shared_blob(e.blob->shared_blob);
11164       }
11165       cb = new Blob();
11166       e.blob->last_encoded_id = n;
11167       id_to_blob[n] = cb;
11168       e.blob->dup(*cb);
11169       // bump the extent refs on the copied blob's extents
11170       for (auto p : blob.get_extents()) {
11171         if (p.is_valid()) {
11172           e.blob->shared_blob->get_ref(p.offset, p.length);
11173         }
11174       }
11175       txc->write_shared_blob(e.blob->shared_blob);
11176       dout(20) << __func__ << "    new " << *cb << dendl;
11177     }
11178     // dup extent
11179     int skip_front, skip_back;
11180     if (e.logical_offset < srcoff) {
11181       skip_front = srcoff - e.logical_offset;
11182     } else {
11183       skip_front = 0;
11184     }
11185     if (e.logical_end() > end) {
11186       skip_back = e.logical_end() - end;
11187     } else {
11188       skip_back = 0;
11189     }
11190     Extent *ne = new Extent(e.logical_offset + skip_front + dstoff - srcoff,
11191                             e.blob_offset + skip_front,
11192                             e.length - skip_front - skip_back, cb);
11193     newo->extent_map.extent_map.insert(*ne);
11194     ne->blob->get_ref(c.get(), ne->blob_offset, ne->length);
11195     // fixme: we may leave parts of new blob unreferenced that could
11196     // be freed (relative to the shared_blob).
11197     txc->statfs_delta.stored() += ne->length;
11198     if (e.blob->get_blob().is_compressed()) {
11199       txc->statfs_delta.compressed_original() += ne->length;
11200       if (blob_duped){
11201         txc->statfs_delta.compressed() +=
11202           cb->get_blob().get_compressed_payload_length();
11203       }
11204     }
11205     dout(20) << __func__ << "  dst " << *ne << dendl;
11206     ++n;
11207   }
11208   if (src_dirty) {
11209     oldo->extent_map.dirty_range(dirty_range_begin,
11210       dirty_range_end - dirty_range_begin);
11211     txc->write_onode(oldo);
11212   }
11213   txc->write_onode(newo);
11214
11215   if (dstoff + length > newo->onode.size) {
11216     newo->onode.size = dstoff + length;
11217   }
11218   newo->extent_map.dirty_range(dstoff, length);
11219   _dump_onode(oldo);
11220   _dump_onode(newo);
11221   return 0;
11222 }
11223
11224 int BlueStore::_clone_range(TransContext *txc,
11225                             CollectionRef& c,
11226                             OnodeRef& oldo,
11227                             OnodeRef& newo,
11228                             uint64_t srcoff, uint64_t length, uint64_t dstoff)
11229 {
11230   dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
11231            << newo->oid << " from 0x" << std::hex << srcoff << "~" << length
11232            << " to offset 0x" << dstoff << std::dec << dendl;
11233   int r = 0;
11234
11235   if (srcoff + length >= OBJECT_MAX_SIZE ||
11236       dstoff + length >= OBJECT_MAX_SIZE) {
11237     r = -E2BIG;
11238     goto out;
11239   }
11240   if (srcoff + length > oldo->onode.size) {
11241     r = -EINVAL;
11242     goto out;
11243   }
11244
11245   _assign_nid(txc, newo);
11246
11247   if (length > 0) {
11248     if (cct->_conf->bluestore_clone_cow) {
11249       _do_zero(txc, c, newo, dstoff, length);
11250       _do_clone_range(txc, c, oldo, newo, srcoff, length, dstoff);
11251     } else {
11252       bufferlist bl;
11253       r = _do_read(c.get(), oldo, srcoff, length, bl, 0);
11254       if (r < 0)
11255         goto out;
11256       r = _do_write(txc, c, newo, dstoff, bl.length(), bl, 0);
11257       if (r < 0)
11258         goto out;
11259     }
11260   }
11261
11262   txc->write_onode(newo);
11263   r = 0;
11264
11265  out:
11266   dout(10) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
11267            << newo->oid << " from 0x" << std::hex << srcoff << "~" << length
11268            << " to offset 0x" << dstoff << std::dec
11269            << " = " << r << dendl;
11270   return r;
11271 }
11272
11273 int BlueStore::_rename(TransContext *txc,
11274                        CollectionRef& c,
11275                        OnodeRef& oldo,
11276                        OnodeRef& newo,
11277                        const ghobject_t& new_oid)
11278 {
11279   dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
11280            << new_oid << dendl;
11281   int r;
11282   ghobject_t old_oid = oldo->oid;
11283   mempool::bluestore_cache_other::string new_okey;
11284
11285   if (newo) {
11286     if (newo->exists) {
11287       r = -EEXIST;
11288       goto out;
11289     }
11290     assert(txc->onodes.count(newo) == 0);
11291   }
11292
11293   txc->t->rmkey(PREFIX_OBJ, oldo->key.c_str(), oldo->key.size());
11294
11295   // rewrite shards
11296   {
11297     oldo->extent_map.fault_range(db, 0, oldo->onode.size);
11298     get_object_key(cct, new_oid, &new_okey);
11299     string key;
11300     for (auto &s : oldo->extent_map.shards) {
11301       generate_extent_shard_key_and_apply(oldo->key, s.shard_info->offset, &key,
11302         [&](const string& final_key) {
11303           txc->t->rmkey(PREFIX_OBJ, final_key);
11304         }
11305       );
11306       s.dirty = true;
11307     }
11308   }
11309
11310   newo = oldo;
11311   txc->write_onode(newo);
11312
11313   // this adjusts oldo->{oid,key}, and reset oldo to a fresh empty
11314   // Onode in the old slot
11315   c->onode_map.rename(oldo, old_oid, new_oid, new_okey);
11316   r = 0;
11317
11318  out:
11319   dout(10) << __func__ << " " << c->cid << " " << old_oid << " -> "
11320            << new_oid << " = " << r << dendl;
11321   return r;
11322 }
11323
11324 // collections
11325
11326 int BlueStore::_create_collection(
11327   TransContext *txc,
11328   const coll_t &cid,
11329   unsigned bits,
11330   CollectionRef *c)
11331 {
11332   dout(15) << __func__ << " " << cid << " bits " << bits << dendl;
11333   int r;
11334   bufferlist bl;
11335
11336   {
11337     RWLock::WLocker l(coll_lock);
11338     if (*c) {
11339       r = -EEXIST;
11340       goto out;
11341     }
11342     c->reset(
11343       new Collection(
11344         this,
11345         cache_shards[cid.hash_to_shard(cache_shards.size())],
11346         cid));
11347     (*c)->cnode.bits = bits;
11348     coll_map[cid] = *c;
11349   }
11350   ::encode((*c)->cnode, bl);
11351   txc->t->set(PREFIX_COLL, stringify(cid), bl);
11352   r = 0;
11353
11354  out:
11355   dout(10) << __func__ << " " << cid << " bits " << bits << " = " << r << dendl;
11356   return r;
11357 }
11358
11359 int BlueStore::_remove_collection(TransContext *txc, const coll_t &cid,
11360                                   CollectionRef *c)
11361 {
11362   dout(15) << __func__ << " " << cid << dendl;
11363   int r;
11364
11365   {
11366     RWLock::WLocker l(coll_lock);
11367     if (!*c) {
11368       r = -ENOENT;
11369       goto out;
11370     }
11371     size_t nonexistent_count = 0;
11372     assert((*c)->exists);
11373     if ((*c)->onode_map.map_any([&](OnodeRef o) {
11374         if (o->exists) {
11375           dout(10) << __func__ << " " << o->oid << " " << o
11376                    << " exists in onode_map" << dendl;
11377           return true;
11378         }
11379         ++nonexistent_count;
11380         return false;
11381         })) {
11382       r = -ENOTEMPTY;
11383       goto out;
11384     }
11385
11386     vector<ghobject_t> ls;
11387     ghobject_t next;
11388     // Enumerate onodes in db, up to nonexistent_count + 1
11389     // then check if all of them are marked as non-existent.
11390     // Bypass the check if returned number is greater than nonexistent_count
11391     r = _collection_list(c->get(), ghobject_t(), ghobject_t::get_max(),
11392                          nonexistent_count + 1, &ls, &next);
11393     if (r >= 0) {
11394       bool exists = false; //ls.size() > nonexistent_count;
11395       for (auto it = ls.begin(); !exists && it < ls.end(); ++it) {
11396         dout(10) << __func__ << " oid " << *it << dendl;
11397         auto onode = (*c)->onode_map.lookup(*it);
11398         exists = !onode || onode->exists;
11399         if (exists) {
11400           dout(10) << __func__ << " " << *it
11401                    << " exists in db" << dendl;
11402         }
11403       }
11404       if (!exists) {
11405         coll_map.erase(cid);
11406         txc->removed_collections.push_back(*c);
11407         (*c)->exists = false;
11408         c->reset();
11409         txc->t->rmkey(PREFIX_COLL, stringify(cid));
11410         r = 0;
11411       } else {
11412         dout(10) << __func__ << " " << cid
11413                  << " is non-empty" << dendl;
11414         r = -ENOTEMPTY;
11415       }
11416     }
11417   }
11418
11419  out:
11420   dout(10) << __func__ << " " << cid << " = " << r << dendl;
11421   return r;
11422 }
11423
11424 int BlueStore::_split_collection(TransContext *txc,
11425                                 CollectionRef& c,
11426                                 CollectionRef& d,
11427                                 unsigned bits, int rem)
11428 {
11429   dout(15) << __func__ << " " << c->cid << " to " << d->cid << " "
11430            << " bits " << bits << dendl;
11431   RWLock::WLocker l(c->lock);
11432   RWLock::WLocker l2(d->lock);
11433   int r;
11434
11435   // flush all previous deferred writes on this sequencer.  this is a bit
11436   // heavyweight, but we need to make sure all deferred writes complete
11437   // before we split as the new collection's sequencer may need to order
11438   // this after those writes, and we don't bother with the complexity of
11439   // moving those TransContexts over to the new osr.
11440   _osr_drain_preceding(txc);
11441
11442   // move any cached items (onodes and referenced shared blobs) that will
11443   // belong to the child collection post-split.  leave everything else behind.
11444   // this may include things that don't strictly belong to the now-smaller
11445   // parent split, but the OSD will always send us a split for every new
11446   // child.
11447
11448   spg_t pgid, dest_pgid;
11449   bool is_pg = c->cid.is_pg(&pgid);
11450   assert(is_pg);
11451   is_pg = d->cid.is_pg(&dest_pgid);
11452   assert(is_pg);
11453
11454   // the destination should initially be empty.
11455   assert(d->onode_map.empty());
11456   assert(d->shared_blob_set.empty());
11457   assert(d->cnode.bits == bits);
11458
11459   c->split_cache(d.get());
11460
11461   // adjust bits.  note that this will be redundant for all but the first
11462   // split call for this parent (first child).
11463   c->cnode.bits = bits;
11464   assert(d->cnode.bits == bits);
11465   r = 0;
11466
11467   bufferlist bl;
11468   ::encode(c->cnode, bl);
11469   txc->t->set(PREFIX_COLL, stringify(c->cid), bl);
11470
11471   dout(10) << __func__ << " " << c->cid << " to " << d->cid << " "
11472            << " bits " << bits << " = " << r << dendl;
11473   return r;
11474 }
11475
11476 // DB key value Histogram
11477 #define KEY_SLAB 32
11478 #define VALUE_SLAB 64
11479
11480 const string prefix_onode = "o";
11481 const string prefix_onode_shard = "x";
11482 const string prefix_other = "Z";
11483
11484 int BlueStore::DBHistogram::get_key_slab(size_t sz)
11485 {
11486   return (sz/KEY_SLAB);
11487 }
11488
11489 string BlueStore::DBHistogram::get_key_slab_to_range(int slab)
11490 {
11491   int lower_bound = slab * KEY_SLAB;
11492   int upper_bound = (slab + 1) * KEY_SLAB;
11493   string ret = "[" + stringify(lower_bound) + "," + stringify(upper_bound) + ")";
11494   return ret;
11495 }
11496
11497 int BlueStore::DBHistogram::get_value_slab(size_t sz)
11498 {
11499   return (sz/VALUE_SLAB);
11500 }
11501
11502 string BlueStore::DBHistogram::get_value_slab_to_range(int slab)
11503 {
11504   int lower_bound = slab * VALUE_SLAB;
11505   int upper_bound = (slab + 1) * VALUE_SLAB;
11506   string ret = "[" + stringify(lower_bound) + "," + stringify(upper_bound) + ")";
11507   return ret;
11508 }
11509
11510 void BlueStore::DBHistogram::update_hist_entry(map<string, map<int, struct key_dist> > &key_hist,
11511                       const string &prefix, size_t key_size, size_t value_size)
11512 {
11513     uint32_t key_slab = get_key_slab(key_size);
11514     uint32_t value_slab = get_value_slab(value_size);
11515     key_hist[prefix][key_slab].count++;
11516     key_hist[prefix][key_slab].max_len = MAX(key_size, key_hist[prefix][key_slab].max_len);
11517     key_hist[prefix][key_slab].val_map[value_slab].count++;
11518     key_hist[prefix][key_slab].val_map[value_slab].max_len =
11519                   MAX(value_size, key_hist[prefix][key_slab].val_map[value_slab].max_len);
11520 }
11521
11522 void BlueStore::DBHistogram::dump(Formatter *f)
11523 {
11524   f->open_object_section("rocksdb_value_distribution");
11525   for (auto i : value_hist) {
11526     f->dump_unsigned(get_value_slab_to_range(i.first).data(), i.second);
11527   }
11528   f->close_section();
11529
11530   f->open_object_section("rocksdb_key_value_histogram");
11531   for (auto i : key_hist) {
11532     f->dump_string("prefix", i.first);
11533     f->open_object_section("key_hist");
11534     for ( auto k : i.second) {
11535       f->dump_unsigned(get_key_slab_to_range(k.first).data(), k.second.count);
11536       f->dump_unsigned("max_len", k.second.max_len);
11537       f->open_object_section("value_hist");
11538       for ( auto j : k.second.val_map) {
11539         f->dump_unsigned(get_value_slab_to_range(j.first).data(), j.second.count);
11540         f->dump_unsigned("max_len", j.second.max_len);
11541       }
11542       f->close_section();
11543     }
11544     f->close_section();
11545   }
11546   f->close_section();
11547 }
11548
11549 //Itrerates through the db and collects the stats
11550 void BlueStore::generate_db_histogram(Formatter *f)
11551 {
11552   //globals
11553   uint64_t num_onodes = 0;
11554   uint64_t num_shards = 0;
11555   uint64_t num_super = 0;
11556   uint64_t num_coll = 0;
11557   uint64_t num_omap = 0;
11558   uint64_t num_deferred = 0;
11559   uint64_t num_alloc = 0;
11560   uint64_t num_stat = 0;
11561   uint64_t num_others = 0;
11562   uint64_t num_shared_shards = 0;
11563   size_t max_key_size =0, max_value_size = 0;
11564   uint64_t total_key_size = 0, total_value_size = 0;
11565   size_t key_size = 0, value_size = 0;
11566   DBHistogram hist;
11567
11568   utime_t start = ceph_clock_now();
11569
11570   KeyValueDB::WholeSpaceIterator iter = db->get_iterator();
11571   iter->seek_to_first();
11572   while (iter->valid()) {
11573     dout(30) << __func__ << " Key: " << iter->key() << dendl;
11574     key_size = iter->key_size();
11575     value_size = iter->value_size();
11576     hist.value_hist[hist.get_value_slab(value_size)]++;
11577     max_key_size = MAX(max_key_size, key_size);
11578     max_value_size = MAX(max_value_size, value_size);
11579     total_key_size += key_size;
11580     total_value_size += value_size;
11581
11582     pair<string,string> key(iter->raw_key());
11583
11584     if (key.first == PREFIX_SUPER) {
11585         hist.update_hist_entry(hist.key_hist, PREFIX_SUPER, key_size, value_size);
11586         num_super++;
11587     } else if (key.first == PREFIX_STAT) {
11588         hist.update_hist_entry(hist.key_hist, PREFIX_STAT, key_size, value_size);
11589         num_stat++;
11590     } else if (key.first == PREFIX_COLL) {
11591         hist.update_hist_entry(hist.key_hist, PREFIX_COLL, key_size, value_size);
11592         num_coll++;
11593     } else if (key.first == PREFIX_OBJ) {
11594       if (key.second.back() == ONODE_KEY_SUFFIX) {
11595         hist.update_hist_entry(hist.key_hist, prefix_onode, key_size, value_size);
11596         num_onodes++;
11597       } else {
11598         hist.update_hist_entry(hist.key_hist, prefix_onode_shard, key_size, value_size);
11599         num_shards++;
11600       }
11601     } else if (key.first == PREFIX_OMAP) {
11602         hist.update_hist_entry(hist.key_hist, PREFIX_OMAP, key_size, value_size);
11603         num_omap++;
11604     } else if (key.first == PREFIX_DEFERRED) {
11605         hist.update_hist_entry(hist.key_hist, PREFIX_DEFERRED, key_size, value_size);
11606         num_deferred++;
11607     } else if (key.first == PREFIX_ALLOC || key.first == "b" ) {
11608         hist.update_hist_entry(hist.key_hist, PREFIX_ALLOC, key_size, value_size);
11609         num_alloc++;
11610     } else if (key.first == PREFIX_SHARED_BLOB) {
11611         hist.update_hist_entry(hist.key_hist, PREFIX_SHARED_BLOB, key_size, value_size);
11612         num_shared_shards++;
11613     } else {
11614         hist.update_hist_entry(hist.key_hist, prefix_other, key_size, value_size);
11615         num_others++;
11616     }
11617     iter->next();
11618   }
11619
11620   utime_t duration = ceph_clock_now() - start;
11621   f->open_object_section("rocksdb_key_value_stats");
11622   f->dump_unsigned("num_onodes", num_onodes);
11623   f->dump_unsigned("num_shards", num_shards);
11624   f->dump_unsigned("num_super", num_super);
11625   f->dump_unsigned("num_coll", num_coll);
11626   f->dump_unsigned("num_omap", num_omap);
11627   f->dump_unsigned("num_deferred", num_deferred);
11628   f->dump_unsigned("num_alloc", num_alloc);
11629   f->dump_unsigned("num_stat", num_stat);
11630   f->dump_unsigned("num_shared_shards", num_shared_shards);
11631   f->dump_unsigned("num_others", num_others);
11632   f->dump_unsigned("max_key_size", max_key_size);
11633   f->dump_unsigned("max_value_size", max_value_size);
11634   f->dump_unsigned("total_key_size", total_key_size);
11635   f->dump_unsigned("total_value_size", total_value_size);
11636   f->close_section();
11637
11638   hist.dump(f);
11639
11640   dout(20) << __func__ << " finished in " << duration << " seconds" << dendl;
11641
11642 }
11643
11644 void BlueStore::_flush_cache()
11645 {
11646   dout(10) << __func__ << dendl;
11647   for (auto i : cache_shards) {
11648     i->trim_all();
11649     assert(i->empty());
11650   }
11651   for (auto& p : coll_map) {
11652     if (!p.second->onode_map.empty()) {
11653       derr << __func__ << "stray onodes on " << p.first << dendl;
11654       p.second->onode_map.dump(cct, 0);
11655     }
11656     if (!p.second->shared_blob_set.empty()) {
11657       derr << __func__ << " stray shared blobs on " << p.first << dendl;
11658       p.second->shared_blob_set.dump(cct, 0);
11659     }
11660     assert(p.second->onode_map.empty());
11661     assert(p.second->shared_blob_set.empty());
11662   }
11663   coll_map.clear();
11664 }
11665
11666 // For external caller.
11667 // We use a best-effort policy instead, e.g.,
11668 // we don't care if there are still some pinned onodes/data in the cache
11669 // after this command is completed.
11670 void BlueStore::flush_cache()
11671 {
11672   dout(10) << __func__ << dendl;
11673   for (auto i : cache_shards) {
11674     i->trim_all();
11675   }
11676 }
11677
11678 void BlueStore::_apply_padding(uint64_t head_pad,
11679                                uint64_t tail_pad,
11680                                bufferlist& padded)
11681 {
11682   if (head_pad) {
11683     padded.prepend_zero(head_pad);
11684   }
11685   if (tail_pad) {
11686     padded.append_zero(tail_pad);
11687   }
11688   if (head_pad || tail_pad) {
11689     dout(20) << __func__ << "  can pad head 0x" << std::hex << head_pad
11690               << " tail 0x" << tail_pad << std::dec << dendl;
11691     logger->inc(l_bluestore_write_pad_bytes, head_pad + tail_pad);
11692   }
11693 }
11694
11695 // ===========================================