~ubuntu-branches/ubuntu/precise/ceph/precise

« back to all changes in this revision

Viewing changes to src/osd/osd_types.h

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum, Clint Byrum, Micah Gersten
  • Date: 2011-02-12 22:50:26 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110212225026-yyyw4tk0msgql3ul
Tags: 0.24.2-0ubuntu1
[ Clint Byrum <clint@ubuntu.com> ]
* New upstream release. (LP: #658670, LP: #684011)
* debian/patches/fix-mkcephfs.patch: dropped (applied upstream)
* Removed .la files from libceph1-dev, libcrush1-dev and 
  librados1-dev (per Debian policy v3.9.1 10.2).
* debian/control: adding pkg-config as a build dependency
* debian/control: depend on libcrypto++-dev instead of libssl-dev
* debian/watch: added watch file

[ Micah Gersten <micahg@ubuntu.com> ]
* debian/control: add Homepage

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
#ifndef CEPH_OSD_TYPES_H
16
16
#define CEPH_OSD_TYPES_H
17
17
 
 
18
#include <sstream>
18
19
#include <stdio.h>
 
20
#include <stdexcept>
19
21
 
20
22
#include "msg/msg_types.h"
21
23
#include "include/types.h"
30
32
#define CEPH_OSD_FULL_RATIO .95
31
33
 
32
34
#define CEPH_OSD_FEATURE_INCOMPAT_BASE CompatSet::Feature(1, "initial feature set(~v.18)")
 
35
#define CEPH_OSD_FEATURE_INCOMPAT_PGINFO CompatSet::Feature(2, "pginfo object")
 
36
#define CEPH_OSD_FEATURE_INCOMPAT_OLOC CompatSet::Feature(3, "object locator")
 
37
#define CEPH_OSD_FEATURE_INCOMPAT_LEC  CompatSet::Feature(4, "last_epoch_clean")
33
38
 
34
39
 
35
40
/* osdreqid_t - caller name + incarnation# + tid to unique identify this request
139
144
    return coll_t(u.pg64, sn);
140
145
    }*/
141
146
 
142
 
  int print(char *o, int maxlen) {
 
147
  int print(char *o, int maxlen) const {
143
148
    if (preferred() >= 0)
144
149
      return snprintf(o, maxlen, "%d.%xp%d", pool(), ps(), preferred());
145
150
    else
201
206
}
202
207
 
203
208
 
204
 
inline ostream& operator<<(ostream& out, pg_t pg) 
 
209
inline ostream& operator<<(ostream& out, const pg_t &pg)
205
210
{
206
211
  out << pg.pool() << '.';
207
212
  out << hex << pg.ps() << dec;
227
232
 
228
233
// ----------------------
229
234
 
230
 
struct coll_t {
231
 
  enum type_t {
232
 
    TYPE_META = 0,
233
 
    TYPE_TEMP = 1,
234
 
    TYPE_PG = 2
235
 
  };
236
 
  __u8 type;
237
 
  pg_t pgid;
238
 
  snapid_t snap;
239
 
 
240
 
  coll_t() : type(TYPE_META), snap(0) {}
241
 
  coll_t(type_t t) : type(t), snap(0) {}
242
 
  coll_t(type_t t, pg_t p, snapid_t s) : type(t), pgid(p), snap(s) {}
243
 
  
244
 
  static coll_t build_pg_coll(pg_t p) {
245
 
    return coll_t(TYPE_PG, p, CEPH_NOSNAP);
246
 
  }
247
 
  static coll_t build_snap_pg_coll(pg_t p, snapid_t s) {
248
 
    return coll_t(TYPE_PG, p, s);
249
 
  }
250
 
 
251
 
  ostream& print(ostream& out) const {
252
 
    switch (type) {
253
 
    case TYPE_META:
254
 
      return out << "meta";
255
 
    case TYPE_TEMP:
256
 
      return out << "temp";
257
 
    case TYPE_PG:
258
 
      out << pgid << "_" << snap;
259
 
    default:
260
 
      return out << "???";
261
 
    }
262
 
  }
263
 
  int print(char *o, int maxlen) {
264
 
    switch (type) {
265
 
    case TYPE_META:
266
 
      return snprintf(o, maxlen, "meta");
267
 
    case TYPE_TEMP:
268
 
      return snprintf(o, maxlen, "temp");
269
 
    case TYPE_PG:
270
 
      {
271
 
        int len = pgid.print(o, maxlen);
272
 
        if (snap != CEPH_NOSNAP)
273
 
          len += snprintf(o + len, maxlen - len, "_%llx", (long long unsigned)snap);
274
 
        else {
275
 
          strncat(o + len, "_head", maxlen - len);
276
 
          len += 5;
 
235
class coll_t {
 
236
public:
 
237
  const static coll_t META_COLL;
 
238
  const static coll_t TEMP_COLL;
 
239
 
 
240
  coll_t()
 
241
    : str("meta")
 
242
  { }
 
243
 
 
244
  explicit coll_t(const std::string &str_)
 
245
    : str(str_)
 
246
  { }
 
247
 
 
248
  explicit coll_t(pg_t pgid, snapid_t snap = CEPH_NOSNAP)
 
249
    : str(pg_and_snap_to_str(pgid, snap))
 
250
  { }
 
251
 
 
252
  const std::string& to_str() const {
 
253
    return str;
 
254
  }
 
255
 
 
256
  const char* c_str() const {
 
257
    return str.c_str();
 
258
  }
 
259
 
 
260
  bool is_pg(pg_t& pgid, snapid_t& snap) const {
 
261
    const char *cstr(str.c_str());
 
262
 
 
263
    if (!pgid.parse(cstr))
 
264
      return false;
 
265
    const char *snap_start = strchr(cstr, '_');
 
266
    if (!snap_start)
 
267
      return false;
 
268
    if (strncmp(snap_start, "_head", 5) == 0)
 
269
      snap = CEPH_NOSNAP;
 
270
    else
 
271
      snap = strtoull(snap_start+1, 0, 16);
 
272
    return true;
 
273
  }
 
274
 
 
275
  void encode(bufferlist& bl) const {
 
276
    __u8 struct_v = 3;
 
277
    ::encode(struct_v, bl);
 
278
    ::encode(str, bl);
 
279
  }
 
280
 
 
281
  void decode(bufferlist::iterator& bl) {
 
282
    __u8 struct_v;
 
283
    ::decode(struct_v, bl);
 
284
    switch (struct_v) {
 
285
      case 1: {
 
286
        pg_t pgid;
 
287
        snapid_t snap;
 
288
 
 
289
        ::decode(pgid, bl);
 
290
        ::decode(snap, bl);
 
291
        // infer the type
 
292
        if (pgid == pg_t() && snap == 0)
 
293
          str = "meta";
 
294
        else
 
295
          str = pg_and_snap_to_str(pgid, snap);
 
296
        break;
 
297
      }
 
298
 
 
299
      case 2: {
 
300
        __u8 type;
 
301
        pg_t pgid;
 
302
        snapid_t snap;
 
303
 
 
304
        ::decode(type, bl);
 
305
        ::decode(pgid, bl);
 
306
        ::decode(snap, bl);
 
307
        switch (type) {
 
308
          case 0:
 
309
            str = "meta";
 
310
            break;
 
311
          case 1:
 
312
            str = "temp";
 
313
            break;
 
314
          case 2:
 
315
            str = pg_and_snap_to_str(pgid, snap);
 
316
            break;
 
317
          default: {
 
318
            ostringstream oss;
 
319
            oss << "coll_t::decode(): can't understand type " << type;
 
320
            throw std::domain_error(oss.str());
 
321
          }
277
322
        }
278
 
        return len;
279
 
      }
280
 
    default:
281
 
      return snprintf(o, maxlen, "???");
282
 
    }
283
 
  }
284
 
  bool parse(char *s) {
285
 
    if (strncmp(s, "meta", 4) == 0) {
286
 
      type = TYPE_META;
287
 
      pgid = pg_t();
288
 
      snap = 0;
289
 
      return true;
290
 
    }
291
 
    if (strncmp(s, "temp", 4) == 0) {
292
 
      type = TYPE_TEMP;
293
 
      pgid = pg_t();
294
 
      snap = 0;
295
 
      return true;
296
 
    }
297
 
    if (!pgid.parse(s))
298
 
      return false;
299
 
    char *sn = strchr(s, '_');
300
 
    if (!sn)
301
 
      return false;
302
 
    if (strncmp(sn, "_head", 5) == 0)
303
 
      snap = CEPH_NOSNAP;
304
 
    else
305
 
      snap = strtoull(sn+1, 0, 16);
306
 
    type = TYPE_PG;
307
 
    return true;
308
 
  }
309
 
 
310
 
  void encode(bufferlist& bl) const {
311
 
    __u8 struct_v = 2;
312
 
    ::encode(struct_v, bl);
313
 
    ::encode(type, bl);
314
 
    ::encode(pgid, bl);
315
 
    ::encode(snap, bl);
316
 
  }
317
 
  void decode(bufferlist::iterator& bl) {
318
 
    __u8 struct_v;
319
 
    ::decode(struct_v, bl);
320
 
    if (struct_v >= 2)
321
 
      ::decode(type, bl);
322
 
    ::decode(pgid, bl);
323
 
    ::decode(snap, bl);
324
 
    if (struct_v < 2) {
325
 
      // infer the type
326
 
      if (pgid == pg_t() && snap == 0)
327
 
        type = TYPE_META;
328
 
      else
329
 
        type = TYPE_PG;
330
 
    }
331
 
  }
 
323
        break;
 
324
      }
 
325
 
 
326
      case 3:
 
327
        ::decode(str, bl);
 
328
        break;
 
329
 
 
330
      default: {
 
331
        ostringstream oss;
 
332
        oss << "coll_t::decode(): don't know how to decode verison "
 
333
            << struct_v;
 
334
        throw std::domain_error(oss.str());
 
335
      }
 
336
    }
 
337
  }
 
338
  inline bool operator==(const coll_t& rhs) const {
 
339
    return str == rhs.str;
 
340
  }
 
341
  inline bool operator!=(const coll_t& rhs) const {
 
342
    return str != rhs.str;
 
343
  }
 
344
 
 
345
private:
 
346
  static std::string pg_and_snap_to_str(pg_t p, snapid_t s) {
 
347
    std::ostringstream oss;
 
348
    oss << p << "_" << s;
 
349
    return oss.str();
 
350
  }
 
351
 
 
352
  std::string str;
332
353
};
 
354
 
333
355
WRITE_CLASS_ENCODER(coll_t)
334
356
 
335
357
inline ostream& operator<<(ostream& out, const coll_t& c) {
336
 
  return c.print(out);
337
 
}
338
 
 
339
 
#define TRIPLE_EQ(l, r, a, b, c) \
340
 
  l.a == r.a && l.b == r.b && l.c == r.c;
341
 
#define TRIPLE_NE(l, r, a, b, c) \
342
 
  l.a != r.a && l.b != r.b && l.c != r.c;
343
 
#define TRIPLE_LT(l, r, a, b, c)                                \
344
 
  l.a < r.a || (l.a == r.a && (l.b < r.b ||                     \
345
 
                               (l.b == r.b && l.c < r.c)));
346
 
#define TRIPLE_LTE(l, r, a, b, c)                               \
347
 
  l.a < r.a || (l.a == r.a && (l.b < r.b ||                     \
348
 
                               (l.b == r.b && l.c <= r.c)));
349
 
#define TRIPLE_GT(l, r, a, b, c)                                \
350
 
  l.a > r.a || (l.a == r.a && (l.b > r.b ||                     \
351
 
                               (l.b == r.b && l.c > r.c)));
352
 
#define TRIPLE_GTE(l, r, a, b, c)                               \
353
 
  l.a > r.a || (l.a == r.a && (l.b > r.b ||                     \
354
 
                               (l.b == r.b && l.c >= r.c)));
355
 
 
356
 
inline bool operator<(const coll_t& l, const coll_t& r) {
357
 
  return TRIPLE_LT(l, r, type, pgid, snap);
358
 
}
359
 
inline bool operator<=(const coll_t& l, const coll_t& r) {
360
 
  return TRIPLE_LTE(l, r, type, pgid, snap);
361
 
}
362
 
inline bool operator==(const coll_t& l, const coll_t& r) {
363
 
  return TRIPLE_EQ(l, r, type, pgid, snap);
364
 
}
365
 
inline bool operator!=(const coll_t& l, const coll_t& r) {
366
 
  return TRIPLE_NE(l, r, type, pgid, snap);
367
 
}
368
 
inline bool operator>(const coll_t& l, const coll_t& r) {
369
 
  return TRIPLE_GT(l, r, type, pgid, snap);
370
 
}
371
 
inline bool operator>=(const coll_t& l, const coll_t& r) {
372
 
  return TRIPLE_GTE(l, r, type, pgid, snap);
 
358
  out << c.to_str();
 
359
  return out;
373
360
}
374
361
 
375
362
namespace __gnu_cxx {
376
363
  template<> struct hash<coll_t> {
377
364
    size_t operator()(const coll_t &c) const { 
378
 
      static hash<pg_t> H;
379
 
      static rjhash<uint64_t> I;
380
 
      return H(c.pgid) ^ I(c.snap + c.type);
 
365
      size_t hash = 0;
 
366
      string str(c.to_str());
 
367
      std::string::const_iterator end(str.end());
 
368
      for (std::string::const_iterator s = str.begin(); s != end; ++s) {
 
369
        hash += *s;
 
370
        hash += (hash << 10);
 
371
        hash ^= (hash >> 6);
 
372
      }
 
373
      hash += (hash << 3);
 
374
      hash ^= (hash >> 11);
 
375
      hash += (hash << 15);
 
376
      return hash;
381
377
    }
382
378
  };
383
379
}
384
380
 
385
 
 
386
 
 
387
381
inline ostream& operator<<(ostream& out, const ceph_object_layout &ol)
388
382
{
389
383
  out << pg_t(ol.ol_pgid);
557
551
#define PG_STATE_REPAIR       (1<<13) // pg should repair on next scrub
558
552
#define PG_STATE_SCANNING     (1<<14) // scanning content to generate backlog
559
553
 
560
 
static inline std::string pg_state_string(int state) {
561
 
  std::string st;
562
 
  if (state & PG_STATE_CREATING) st += "creating+";
563
 
  if (state & PG_STATE_ACTIVE) st += "active+";
564
 
  if (state & PG_STATE_CLEAN) st += "clean+";
565
 
  if (state & PG_STATE_CRASHED) st += "crashed+";
566
 
  if (state & PG_STATE_DOWN) st += "down+";
567
 
  if (state & PG_STATE_REPLAY) st += "replay+";
568
 
  if (state & PG_STATE_STRAY) st += "stray+";
569
 
  if (state & PG_STATE_SPLITTING) st += "splitting+";
570
 
  if (state & PG_STATE_DEGRADED) st += "degraded+";
571
 
  if (state & PG_STATE_SCRUBBING) st += "scrubbing+";
572
 
  if (state & PG_STATE_SCRUBQ) st += "scrubq+";
573
 
  if (state & PG_STATE_INCONSISTENT) st += "inconsistent+";
574
 
  if (state & PG_STATE_PEERING) st += "peering+";
575
 
  if (state & PG_STATE_REPAIR) st += "repair+";
576
 
  if (state & PG_STATE_SCANNING) st += "scanning+";
577
 
  if (!st.length()) 
578
 
    st = "inactive";
579
 
  else 
580
 
    st.resize(st.length()-1);
581
 
  return st;
 
554
static inline std::string pg_state_string(int state)
 
555
{
 
556
  ostringstream oss;
 
557
  if (state & PG_STATE_CREATING)
 
558
    oss << "creating+";
 
559
  if (state & PG_STATE_ACTIVE)
 
560
    oss << "active+";
 
561
  if (state & PG_STATE_CLEAN)
 
562
    oss << "clean+";
 
563
  if (state & PG_STATE_CRASHED)
 
564
    oss << "crashed+";
 
565
  if (state & PG_STATE_DOWN)
 
566
    oss << "down+";
 
567
  if (state & PG_STATE_REPLAY)
 
568
    oss << "replay+";
 
569
  if (state & PG_STATE_STRAY)
 
570
    oss << "stray+";
 
571
  if (state & PG_STATE_SPLITTING)
 
572
    oss << "splitting+";
 
573
  if (state & PG_STATE_DEGRADED)
 
574
    oss << "degraded+";
 
575
  if (state & PG_STATE_SCRUBBING)
 
576
    oss << "scrubbing+";
 
577
  if (state & PG_STATE_SCRUBQ)
 
578
    oss << "scrubq+";
 
579
  if (state & PG_STATE_INCONSISTENT)
 
580
    oss << "inconsistent+";
 
581
  if (state & PG_STATE_PEERING)
 
582
    oss << "peering+";
 
583
  if (state & PG_STATE_REPAIR)
 
584
    oss << "repair+";
 
585
  if (state & PG_STATE_SCANNING)
 
586
    oss << "scanning+";
 
587
  string ret(oss.str());
 
588
  if (ret.length() > 0)
 
589
    ret.resize(ret.length() - 1);
 
590
  else
 
591
    ret = "inactive";
 
592
  return ret;
582
593
}
583
594
 
584
595
 
693
704
   * we know which mode we're using based on whether removed_snaps is empty.
694
705
   */
695
706
  bool is_pool_snaps_mode() const {
696
 
    return removed_snaps.empty();
 
707
    return removed_snaps.empty() && get_snap_seq() > 0;
697
708
  }
698
709
 
699
710
  bool is_removed_snap(snapid_t s) const {
789
800
    __u8 struct_v = CEPH_PG_POOL_VERSION;
790
801
    ::encode(struct_v, bl);
791
802
    v.num_snaps = snaps.size();
792
 
    v.num_removed_snap_intervals = removed_snaps.m.size();
 
803
    v.num_removed_snap_intervals = removed_snaps.num_intervals();
793
804
    ::encode(v, bl);
794
805
    ::encode_nohead(snaps, bl);
795
806
    removed_snaps.encode_nohead(bl);
797
808
  void decode(bufferlist::iterator& bl) {
798
809
    __u8 struct_v;
799
810
    ::decode(struct_v, bl);
800
 
    assert(struct_v <= CEPH_PG_POOL_VERSION);
 
811
    if (struct_v > CEPH_PG_POOL_VERSION)
 
812
      throw buffer::error();
801
813
    ::decode(v, bl);
802
814
    ::decode_nohead(v.num_snaps, snaps, bl);
803
815
    removed_snaps.decode_nohead(v.num_removed_snap_intervals, bl);
848
860
  uint64_t num_objects;
849
861
  uint64_t num_object_clones;
850
862
  uint64_t num_object_copies;  // num_objects * num_replicas
 
863
 
 
864
  // The number of objects missing on the primary OSD
851
865
  uint64_t num_objects_missing_on_primary;
 
866
 
852
867
  uint64_t num_objects_degraded;
853
868
  uint64_t log_size;
854
869
  uint64_t ondisk_log_size;    // >= active_log_size
855
870
 
856
871
  uint64_t num_rd, num_rd_kb;
857
872
  uint64_t num_wr, num_wr_kb;
 
873
 
 
874
  // The number of objects missing on the primary OSD
 
875
  uint64_t num_objects_unfound;
858
876
  
859
877
  vector<int> up, acting;
860
878
 
864
882
                num_objects(0), num_object_clones(0), num_object_copies(0),
865
883
                num_objects_missing_on_primary(0), num_objects_degraded(0),
866
884
                log_size(0), ondisk_log_size(0),
867
 
                num_rd(0), num_rd_kb(0), num_wr(0), num_wr_kb(0)
 
885
                num_rd(0), num_rd_kb(0), num_wr(0), num_wr_kb(0),
 
886
                num_objects_unfound(0)
868
887
  { }
869
888
 
870
889
  void encode(bufferlist &bl) const {
871
 
    __u8 v = 3;
 
890
    __u8 v = 4;
872
891
    ::encode(v, bl);
873
892
 
874
893
    ::encode(version, bl);
895
914
    ::encode(num_wr, bl);
896
915
    ::encode(num_wr_kb, bl);
897
916
    ::encode(up, bl);
 
917
    ::encode(num_objects_unfound, bl);
898
918
    ::encode(acting, bl);
899
919
  }
900
920
  void decode(bufferlist::iterator &bl) {
926
946
      ::decode(num_wr, bl);
927
947
      ::decode(num_wr_kb, bl);
928
948
    }
929
 
    if (v >= 3)
 
949
    if (v >= 3) {
930
950
      ::decode(up, bl);
 
951
    }
 
952
    if (v >= 4) {
 
953
      ::decode(num_objects_unfound, bl);
 
954
    }
931
955
    ::decode(acting, bl);
932
956
  }
933
957
 
945
969
    num_rd_kb += o.num_rd_kb;
946
970
    num_wr += o.num_wr;
947
971
    num_wr_kb += o.num_wr_kb;
 
972
    num_objects_unfound += o.num_objects_unfound;
948
973
  }
949
974
  void sub(const pg_stat_t& o) {
950
975
    num_bytes -= o.num_bytes;
960
985
    num_rd_kb -= o.num_rd_kb;
961
986
    num_wr -= o.num_wr;
962
987
    num_wr_kb -= o.num_wr_kb;
 
988
    num_objects_unfound -= o.num_objects_unfound;
963
989
  }
964
990
};
965
991
WRITE_CLASS_ENCODER(pg_stat_t)
980
1006
  uint64_t num_rd, num_rd_kb;
981
1007
  uint64_t num_wr, num_wr_kb;
982
1008
 
 
1009
  // The number of logical objects that are still unfound
 
1010
  uint64_t num_objects_unfound;
 
1011
 
983
1012
  pool_stat_t() : num_bytes(0), num_kb(0), 
984
1013
                  num_objects(0), num_object_clones(0), num_object_copies(0),
985
1014
                  num_objects_missing_on_primary(0), num_objects_degraded(0),
986
1015
                  log_size(0), ondisk_log_size(0),
987
 
                  num_rd(0), num_rd_kb(0), num_wr(0), num_wr_kb(0)
 
1016
                  num_rd(0), num_rd_kb(0), num_wr(0), num_wr_kb(0),
 
1017
                  num_objects_unfound(0)
988
1018
  { }
989
1019
 
990
1020
  void encode(bufferlist &bl) const {
991
 
    __u8 v = 2;
 
1021
    __u8 v = 3;
992
1022
    ::encode(v, bl);
993
1023
    ::encode(num_bytes, bl);
994
1024
    ::encode(num_kb, bl);
1003
1033
    ::encode(num_rd_kb, bl);
1004
1034
    ::encode(num_wr, bl);
1005
1035
    ::encode(num_wr_kb, bl);
 
1036
    ::encode(num_objects_unfound, bl);
1006
1037
 }
1007
1038
  void decode(bufferlist::iterator &bl) {
1008
1039
    __u8 v;
1022
1053
      ::decode(num_wr, bl);
1023
1054
      ::decode(num_wr_kb, bl);
1024
1055
    }
 
1056
    if (v >= 3) {
 
1057
      ::decode(num_objects_unfound, bl);
 
1058
    }
1025
1059
  }
1026
1060
 
1027
1061
  void add(const pg_stat_t& o) {
1038
1072
    num_rd_kb += o.num_rd_kb;
1039
1073
    num_wr += o.num_wr;
1040
1074
    num_wr_kb += o.num_wr_kb;
 
1075
    num_objects_unfound += o.num_objects_unfound;
1041
1076
  }
1042
1077
  void sub(const pg_stat_t& o) {
1043
1078
    num_bytes -= o.num_bytes;
1053
1088
    num_rd_kb -= o.num_rd_kb;
1054
1089
    num_wr -= o.num_wr;
1055
1090
    num_wr_kb -= o.num_wr_kb;
 
1091
    num_objects_unfound -= o.num_objects_unfound;
1056
1092
  }
1057
1093
};
1058
1094
WRITE_CLASS_ENCODER(pool_stat_t)
1096
1132
  __u32      offset;    // in object
1097
1133
  __u32      length;    // in object
1098
1134
 
1099
 
  ceph_object_layout layout;   // object layout (pgid, etc.)
 
1135
  object_locator_t oloc;   // object locator (pool etc)
1100
1136
 
1101
1137
  map<__u32, __u32>  buffer_extents;  // off -> len.  extents in buffer being mapped (may be fragmented bc of striping!)
1102
1138
  
1104
1140
  ObjectExtent(object_t o, __u32 off=0, __u32 l=0) : oid(o), offset(off), length(l) { }
1105
1141
};
1106
1142
 
1107
 
inline ostream& operator<<(ostream& out, ObjectExtent &ex)
 
1143
inline ostream& operator<<(ostream& out, const ObjectExtent &ex)
1108
1144
{
1109
1145
  return out << "extent(" 
1110
 
             << ex.oid << " in " << ex.layout
 
1146
             << ex.oid << " in " << ex.oloc
1111
1147
             << " " << ex.offset << "~" << ex.length
1112
1148
             << ")";
1113
1149
}
1178
1214
};
1179
1215
WRITE_CLASS_ENCODER(OSDSuperblock)
1180
1216
 
1181
 
inline ostream& operator<<(ostream& out, OSDSuperblock& sb)
 
1217
inline ostream& operator<<(ostream& out, const OSDSuperblock& sb)
1182
1218
{
1183
1219
  return out << "sb(" << sb.fsid
1184
1220
             << " osd" << sb.whoami
1251
1287
 
1252
1288
struct object_info_t {
1253
1289
  sobject_t soid;
 
1290
  object_locator_t oloc;
1254
1291
 
1255
1292
  eversion_t version, prior_version;
1256
1293
  osd_reqid_t last_reqid;
1257
1294
 
1258
1295
  uint64_t size;
1259
1296
  utime_t mtime;
 
1297
  bool lost;
1260
1298
 
1261
1299
  osd_reqid_t wrlock_by;   // [head]
1262
1300
  vector<snapid_t> snaps;  // [clone]
1263
1301
 
1264
1302
  uint64_t truncate_seq, truncate_size;
1265
1303
 
 
1304
  void copy_user_bits(const object_info_t& other) {
 
1305
    // these bits are copied from head->clone.
 
1306
    size = other.size;
 
1307
    mtime = other.mtime;
 
1308
    last_reqid = other.last_reqid;
 
1309
    truncate_seq = other.truncate_seq;
 
1310
    truncate_size = other.truncate_size;
 
1311
    lost = other.lost;
 
1312
  }
 
1313
 
1266
1314
  void encode(bufferlist& bl) const {
1267
 
    const __u8 v = 1;
 
1315
    const __u8 v = 3;
1268
1316
    ::encode(v, bl);
1269
1317
    ::encode(soid, bl);
 
1318
    ::encode(oloc, bl);
1270
1319
    ::encode(version, bl);
1271
1320
    ::encode(prior_version, bl);
1272
1321
    ::encode(last_reqid, bl);
1278
1327
      ::encode(snaps, bl);
1279
1328
    ::encode(truncate_seq, bl);
1280
1329
    ::encode(truncate_size, bl);
 
1330
    ::encode(lost, bl);
1281
1331
  }
1282
1332
  void decode(bufferlist::iterator& bl) {
1283
1333
    __u8 v;
1284
1334
    ::decode(v, bl);
1285
1335
    ::decode(soid, bl);
 
1336
    if (v >= 2)
 
1337
      ::decode(oloc, bl);
1286
1338
    ::decode(version, bl);
1287
1339
    ::decode(prior_version, bl);
1288
1340
    ::decode(last_reqid, bl);
1294
1346
      ::decode(snaps, bl);
1295
1347
    ::decode(truncate_seq, bl);
1296
1348
    ::decode(truncate_size, bl);
 
1349
    if (v >= 3)
 
1350
      ::decode(lost, bl);
 
1351
    else
 
1352
      lost = false;
1297
1353
  }
1298
1354
  void decode(bufferlist& bl) {
1299
1355
    bufferlist::iterator p = bl.begin();
1300
1356
    decode(p);
1301
1357
  }
1302
1358
 
1303
 
  object_info_t(sobject_t s) : soid(s), size(0),
1304
 
                               truncate_seq(0), truncate_size(0) {}
 
1359
  object_info_t(const sobject_t& s, const object_locator_t& o)
 
1360
    : soid(s), oloc(o), size(0),
 
1361
      lost(false), truncate_seq(0), truncate_size(0) {}
 
1362
 
1305
1363
  object_info_t(bufferlist& bl) {
1306
1364
    decode(bl);
1307
1365
  }
1316
1374
    out << " wrlock_by=" << oi.wrlock_by;
1317
1375
  else
1318
1376
    out << " " << oi.snaps;
 
1377
  if (oi.lost)
 
1378
    out << " LOST";
1319
1379
  out << ")";
1320
1380
  return out;
1321
1381
}
1327
1387
 */
1328
1388
struct ScrubMap {
1329
1389
  struct object {
1330
 
    sobject_t poid;
1331
1390
    uint64_t size;
 
1391
    bool negative;
1332
1392
    map<string,bufferptr> attrs;
1333
1393
 
 
1394
    object(): size(0),negative(0),attrs() {}
 
1395
 
1334
1396
    void encode(bufferlist& bl) const {
1335
1397
      __u8 struct_v = 1;
1336
1398
      ::encode(struct_v, bl);
1337
 
      ::encode(poid, bl);
1338
1399
      ::encode(size, bl);
 
1400
      ::encode(negative, bl);
1339
1401
      ::encode(attrs, bl);
1340
1402
    }
1341
1403
    void decode(bufferlist::iterator& bl) {
1342
1404
      __u8 struct_v;
1343
1405
      ::decode(struct_v, bl);
1344
 
      ::decode(poid, bl);
1345
1406
      ::decode(size, bl);
 
1407
      ::decode(negative, bl);
1346
1408
      ::decode(attrs, bl);
1347
1409
    }
1348
1410
  };
1349
1411
  WRITE_CLASS_ENCODER(object)
1350
1412
 
1351
 
  vector<object> objects;
 
1413
  map<sobject_t,object> objects;
1352
1414
  map<string,bufferptr> attrs;
1353
1415
  bufferlist logbl;
 
1416
  eversion_t valid_through;
 
1417
  eversion_t incr_since;
 
1418
 
 
1419
  void merge_incr(const ScrubMap &l) {
 
1420
    assert(valid_through == l.incr_since);
 
1421
    attrs = l.attrs;
 
1422
    logbl = l.logbl;
 
1423
    valid_through = l.valid_through;
 
1424
 
 
1425
    for (map<sobject_t,object>::const_iterator p = l.objects.begin();
 
1426
         p != l.objects.end();
 
1427
         p++){
 
1428
      if (p->second.negative) {
 
1429
        map<sobject_t,object>::iterator q = objects.find(p->first);
 
1430
        if (q != objects.end()) {
 
1431
          objects.erase(q);
 
1432
        }
 
1433
      } else {
 
1434
        objects[p->first] = p->second;
 
1435
      }
 
1436
    }
 
1437
  }
 
1438
          
1354
1439
 
1355
1440
  void encode(bufferlist& bl) const {
1356
1441
    __u8 struct_v = 1;
1358
1443
    ::encode(objects, bl);
1359
1444
    ::encode(attrs, bl);
1360
1445
    ::encode(logbl, bl);
 
1446
    ::encode(valid_through, bl);
 
1447
    ::encode(incr_since, bl);
1361
1448
  }
1362
1449
  void decode(bufferlist::iterator& bl) {
1363
1450
    __u8 struct_v;
1365
1452
    ::decode(objects, bl);
1366
1453
    ::decode(attrs, bl);
1367
1454
    ::decode(logbl, bl);
 
1455
    ::decode(valid_through, bl);
 
1456
    ::decode(incr_since, bl);
1368
1457
  }
1369
1458
};
1370
1459
WRITE_CLASS_ENCODER(ScrubMap::object)