From e822b6fd4d9fc785bb5601724a2dc8409b532f0e Mon Sep 17 00:00:00 2001 From: sageweil Date: Wed, 29 Nov 2006 22:52:02 +0000 Subject: [PATCH] some preliminary object revision stuff; ebofs reference counts allocated extents git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@970 29311d96-e01e-0410-9327-a35deaab8ce9 --- ceph/TODO | 16 ++ ceph/config.cc | 2 +- ceph/ebofs/Allocator.cc | 328 +++++++++++++++++++++++++++++++++++++-- ceph/ebofs/Allocator.h | 16 +- ceph/ebofs/Ebofs.cc | 57 ++++++- ceph/ebofs/Ebofs.h | 13 ++ ceph/ebofs/Table.h | 17 +- ceph/ebofs/mkfs.ebofs.cc | 3 +- ceph/ebofs/test.ebofs.cc | 10 +- ceph/include/buffer.h | 33 +++- ceph/include/object.h | 6 +- ceph/include/types.h | 13 -- ceph/messages/MOSDOp.h | 1 + ceph/osd/FakeStore.cc | 2 +- ceph/osd/FakeStore.h | 3 + ceph/osd/ObjectStore.h | 2 + 16 files changed, 475 insertions(+), 47 deletions(-) diff --git a/ceph/TODO b/ceph/TODO index 8b2ec0f774c93..d81114ecd7fc5 100644 --- a/ceph/TODO +++ b/ceph/TODO @@ -7,6 +7,22 @@ papers to read - johnson and colbrook's DE and DB-trees (maybe fewer locks?) +rados todo +- better experiments +- flush log only in response to subsequent read or write? +- better behaving recovery +- justify use of splay. + - dynamic replication +- snapshots + +rados snapshots +- write is tagged with current_rev. + - if latest object.rev != current_rev, we clone it before applying write. +- reads are tagged with readv. + - we read from newest object whose snapv >= readv. + + + - messenger lookup() and failure() upcalls diff --git a/ceph/config.cc b/ceph/config.cc index cae08dddccc91..80d016874332a 100644 --- a/ceph/config.cc +++ b/ceph/config.cc @@ -201,7 +201,7 @@ md_config_t g_conf = { osd_mkfs: false, osd_age: .8, osd_age_time: 0, - osd_heartbeat_interval: 10, + osd_heartbeat_interval: 1000, // shut up while i'm debugging osd_replay_window: 5, osd_max_pull: 2, osd_pad_pg_log: false, diff --git a/ceph/ebofs/Allocator.cc b/ceph/ebofs/Allocator.cc index bcd14f4ef6665..901a541449016 100644 --- a/ceph/ebofs/Allocator.cc +++ b/ceph/ebofs/Allocator.cc @@ -18,7 +18,7 @@ #undef dout -#define dout(x) if (x <= g_conf.debug_ebofs) cout << "ebofs.allocator." +#define dout(x) if (x <= g_conf.debug_ebofs) cout << "ebofs(" << fs->dev.get_device_name() << ").allocator." void Allocator::dump_freelist() @@ -160,6 +160,7 @@ int Allocator::allocate(Extent& ex, block_t num, block_t near) dout(20) << "allocate " << ex << " near " << near << endl; last_pos = ex.end(); dump_freelist(); + alloc_inc(ex); return num; } } @@ -180,6 +181,7 @@ int Allocator::allocate(Extent& ex, block_t num, block_t near) last_pos = ex.end(); dout(20) << "allocate partial " << ex << " (wanted " << num << ") near " << near << endl; dump_freelist(); + alloc_inc(ex); return ex.length; } } @@ -190,15 +192,21 @@ int Allocator::allocate(Extent& ex, block_t num, block_t near) return -1; } -int Allocator::release(Extent& ex) +int Allocator::_release_into_limbo(Extent& ex) { - dout(20) << "release " << ex << " (into limbo)" << endl; + dout(10) << "_release_into_limbo " << ex << endl; + dout(10) << "limbo is " << limbo << endl; assert(ex.length > 0); limbo.insert(ex.start, ex.length); fs->limbo_blocks += ex.length; return 0; } +int Allocator::release(Extent& ex) +{ + return alloc_dec(ex); +} + int Allocator::commit_limbo() { dout(20) << "commit_limbo" << endl; @@ -237,7 +245,8 @@ int Allocator::release_limbo() -int Allocator::_alloc_inc(Extent& ex) +/* +int Allocator::_alloc_loner_inc(Extent& ex) { Table >::Cursor cursor(fs->alloc_tab); @@ -246,18 +255,18 @@ int Allocator::_alloc_inc(Extent& ex) assert(cursor.current().value.first == ex.length); pair& v = cursor.dirty_current_value(); v.second++; - dout(10) << "_alloc_inc " << ex << " " + dout(10) << "_alloc_loner_inc " << ex << " " << (v.second-1) << " -> " << v.second << endl; } else { // insert it, @1 - //fs->alloc_tab->insert(ex.start, pair(ex.length,1)); - dout(10) << "_alloc_inc " << ex << " 0 -> 1" << endl; + fs->alloc_tab->insert(ex.start, pair(ex.length,1)); + dout(10) << "_alloc_loner_inc " << ex << " 0 -> 1" << endl; } return 0; } -int Allocator::_alloc_dec(Extent& ex) +int Allocator::_alloc_loner_dec(Extent& ex) { Table >::Cursor cursor(fs->alloc_tab); @@ -265,12 +274,12 @@ int Allocator::_alloc_dec(Extent& ex) == Table >::Cursor::MATCH) { assert(cursor.current().value.first == ex.length); if (cursor.current().value.second == 1) { - dout(10) << "_alloc_dec " << ex << " 1 -> 0" << endl; + dout(10) << "_alloc_loner_dec " << ex << " 1 -> 0" << endl; fs->alloc_tab->remove( cursor.current().key ); } else { pair& v = cursor.dirty_current_value(); --v.second; - dout(10) << "_alloc_dec " << ex << " " + dout(10) << "_alloc_loner_dec " << ex << " " << (v.second+1) << " -> " << v.second << endl; } @@ -279,6 +288,305 @@ int Allocator::_alloc_dec(Extent& ex) } return 0; } +*/ + + +int Allocator::alloc_inc(Extent ex) +{ + dout(10) << "alloc_inc " << ex << endl; + + // empty table? + if (fs->alloc_tab->get_num_keys() == 0) { + // easy. + fs->alloc_tab->insert(ex.start, pair(ex.length,1)); + dout(10) << "alloc_inc + " << ex << " 0 -> 1 (first entry)" << endl; + return 0; + } + + Table >::Cursor cursor(fs->alloc_tab); + + // try to move to left (to check for overlap) + int r = fs->alloc_tab->find( ex.start, cursor ); + if (r == Table >::Cursor::OOB || + cursor.current().key > ex.start) { + r = cursor.move_left(); + dout(10) << "alloc_inc move_left r = " << r << endl; + } + + while (1) { + dout(10) << "alloc_inc loop at " << cursor.current().key + << "~" << cursor.current().value.first + << " ref " << cursor.current().value.second + << endl; + + // too far left? + if (cursor.current().key < ex.start && + cursor.current().key + cursor.current().value.first <= ex.start) { + // no overlap. + r = cursor.move_right(); + dout(10) << "alloc_inc move_right r = " << r << endl; + + // at end? + if (r <= 0) { + // insert at end, finish. + fs->alloc_tab->insert(ex.start, pair(ex.length,1)); + dout(10) << "alloc_inc + " << ex << " 0 -> 1 (at end)" << endl; + return 0; + } + } + + if (cursor.current().key > ex.start) { + // gap. + // oooooo + // nnnnn..... + block_t l = MIN(ex.length, cursor.current().key - ex.start); + + fs->alloc_tab->insert(ex.start, pair(l,1)); + dout(10) << "alloc_inc + " << ex.start << "~" << l << " 0 -> 1" << endl; + ex.start += l; + ex.length -= l; + if (ex.length == 0) break; + fs->alloc_tab->find( ex.start, cursor ); + } + else if (cursor.current().key < ex.start) { + block_t end = cursor.current().value.first + cursor.current().key; + + if (end <= ex.end()) { + // single split + // oooooo + // nnnnn + pair& v = cursor.dirty_current_value(); + v.first = ex.start - cursor.current().key; + int ref = v.second; + + block_t l = end - ex.start; + fs->alloc_tab->insert(ex.start, pair(l, 1+ref)); + + dout(10) << "alloc_inc " << ex.start << "~" << l + << " " << ref << " -> " << ref+1 + << " (right split)" << endl; + + ex.start += l; + ex.length -= l; + if (ex.length == 0) break; + fs->alloc_tab->find( ex.start, cursor ); + + } else { + // double split, finish. + // ------------- + // ------ + pair& v = cursor.dirty_current_value(); + v.first = ex.start - cursor.current().key; + int ref = v.second; + + fs->alloc_tab->insert(ex.start, pair(ex.length, 1+ref)); + + int rl = end - ex.end(); + fs->alloc_tab->insert(ex.end(), pair(rl, ref)); + + dout(10) << "alloc_inc " << ex + << " " << ref << " -> " << ref+1 + << " (double split finish)" + << endl; + + break; + } + } + else { + assert(cursor.current().key == ex.start); + + if (cursor.current().value.first <= ex.length) { + // inc. + // oooooo + // nnnnnnnn + pair& v = cursor.dirty_current_value(); + v.second++; + dout(10) << "alloc_inc " << ex.start << "~" << cursor.current().value.first + << " " << cursor.current().value.second-1 << " -> " + << cursor.current().value.second + << " (left split)" << endl; + ex.start += v.first; + ex.length -= v.first; + if (ex.length == 0) break; + cursor.move_right(); + } else { + // single split, finish. + // oooooo + // nnn + block_t l = cursor.current().value.first - ex.length; + int ref = cursor.current().value.second; + + pair& v = cursor.dirty_current_value(); + v.first = ex.length; + v.second++; + + fs->alloc_tab->insert(ex.end(), pair(l, ref)); + + dout(10) << "alloc_inc " << ex + << " " << ref << " -> " << ref+1 + << " (left split finish)" + << endl; + + break; + } + } + } + + return 0; +} + + +int Allocator::alloc_dec(Extent ex) +{ + dout(10) << "alloc_dec " << ex << endl; + + assert(fs->alloc_tab->get_num_keys() >= 0); + + Table >::Cursor cursor(fs->alloc_tab); + + // try to move to left (to check for overlap) + int r = fs->alloc_tab->find( ex.start, cursor ); + if (r == Table >::Cursor::OOB || + cursor.current().key > ex.start) { + r = cursor.move_left(); + dout(10) << "alloc_dec move_left r = " << r << endl; + + // too far left? + if (cursor.current().key < ex.start && + cursor.current().key + cursor.current().value.first <= ex.start) { + // no overlap. + assert(0); + } + } + + while (1) { + dout(10) << "alloc_dec ? " << cursor.current().key + << "~" << cursor.current().value.first + << " " << cursor.current().value.second + << ", ex is " << ex + << endl; + + assert(cursor.current().key <= ex.start); // no gap allowed. + + if (cursor.current().key < ex.start) { + block_t end = cursor.current().value.first + cursor.current().key; + + if (end <= ex.end()) { + // single split + // oooooo + // ----- + pair& v = cursor.dirty_current_value(); + v.first = ex.start - cursor.current().key; + int ref = v.second; + dout(10) << "alloc_dec s " << cursor.current().key << "~" << cursor.current().value.first + << " " << ref + << " shortened left bit of single" << endl; + + block_t l = end - ex.start; + if (ref > 1) { + fs->alloc_tab->insert(ex.start, pair(l, ref-1)); + dout(10) << "alloc_dec . " << ex.start << "~" << l + << " " << ref << " -> " << ref-1 + << endl; + } else { + Extent r(ex.start, l); + _release_into_limbo(r); + } + + ex.start += l; + ex.length -= l; + if (ex.length == 0) break; + fs->alloc_tab->find( ex.start, cursor ); + + } else { + // double split, finish. + // ooooooooooooo + // ------ + pair& v = cursor.dirty_current_value(); + v.first = ex.start - cursor.current().key; + int ref = v.second; + dout(10) << "alloc_dec s " << cursor.current().key << "~" << cursor.current().value.first + << " " << ref + << " shorted left bit of double split" << endl; + + if (ref > 1) { + fs->alloc_tab->insert(ex.start, pair(ex.length, ref-1)); + dout(10) << "alloc_inc s " << ex + << " " << ref << " -> " << ref-1 + << " reinserted middle bit of double split" + << endl; + } else { + _release_into_limbo(ex); + } + + int rl = end - ex.end(); + fs->alloc_tab->insert(ex.end(), pair(rl, ref)); + dout(10) << "alloc_dec s " << ex.end() << "~" << rl + << " " << ref + << " reinserted right bit of double split" << endl; + break; + } + } + else { + assert(cursor.current().key == ex.start); + + if (cursor.current().value.first <= ex.length) { + // inc. + // oooooo + // nnnnnnnn + if (cursor.current().value.second > 1) { + pair& v = cursor.dirty_current_value(); + v.second--; + dout(10) << "alloc_dec s " << ex.start << "~" << cursor.current().value.first + << " " << cursor.current().value.second+1 << " -> " << cursor.current().value.second + << endl; + ex.start += v.first; + ex.length -= v.first; + if (ex.length == 0) break; + cursor.move_right(); + } else { + Extent r(cursor.current().key, cursor.current().value.first); + _release_into_limbo(r); + + ex.start += cursor.current().value.first; + ex.length -= cursor.current().value.first; + cursor.remove(); + + if (ex.length == 0) break; + fs->alloc_tab->find( ex.start, cursor ); + } + } else { + // single split, finish. + // oooooo + // nnn + block_t l = cursor.current().value.first - ex.length; + int ref = cursor.current().value.second; + + if (ref > 1) { + pair& v = cursor.dirty_current_value(); + v.first = ex.length; + v.second--; + dout(10) << "alloc_inc . " << ex + << " " << ref << " -> " << ref-1 + << endl; + } else { + _release_into_limbo(ex); + cursor.remove(); + } + + dout(10) << "alloc_dec s " << ex.end() << "~" << l + << " " << ref + << " reinserted right bit of single split" << endl; + fs->alloc_tab->insert(ex.end(), pair(l, ref)); + break; + } + } + + + } + + return 0; +} /* diff --git a/ceph/ebofs/Allocator.h b/ceph/ebofs/Allocator.h index 1fc595cddcf2a..c53ff2a69fba1 100644 --- a/ceph/ebofs/Allocator.h +++ b/ceph/ebofs/Allocator.h @@ -53,21 +53,29 @@ protected: void dump_freelist(); public: + int _release_into_limbo(Extent& ex); + int _release_loner(Extent& ex); // release loner extent int _release_merge(Extent& ex); // release any extent (searches for adjacent) - int _alloc_inc(Extent& ex); - int _alloc_dec(Extent& ex); + //int _alloc_loner_inc(Extent& ex); + //int _alloc_loner_dec(Extent& ex); + public: Allocator(Ebofs *f) : fs(f), last_pos(0) {} int allocate(Extent& ex, block_t num, block_t near=NEAR_LAST); - int release(Extent& ex); + int release(Extent& ex); // alias for alloc_dec + + int alloc_inc(Extent ex); + int alloc_dec(Extent ex); + - int unallocate(Extent& ex) { // skip limbo + /*int unallocate(Extent& ex) { // skip limbo return _release_merge(ex); } + */ int commit_limbo(); // limbo -> fs->limbo_tab int release_limbo(); // fs->limbo_tab -> free_tabs diff --git a/ceph/ebofs/Ebofs.cc b/ceph/ebofs/Ebofs.cc index 55239864e1d14..eab79e7756ff9 100644 --- a/ceph/ebofs/Ebofs.cc +++ b/ceph/ebofs/Ebofs.cc @@ -159,7 +159,7 @@ int Ebofs::mkfs() left.start = nodepool.usemap_odd.end(); left.length = num_blocks - left.start; dout(10) << "mkfs: free data blocks at " << left << endl; - allocator.release( left ); + allocator._release_into_limbo( left ); allocator.commit_limbo(); // -> limbo_tab allocator.release_limbo(); // -> free_tab @@ -1359,7 +1359,9 @@ void Ebofs::alloc_write(Onode *on, if (bc.bh_cancel_write(bh, super_epoch)) { if (bh->length() == 1) dout(10) << "alloc_write unallocated tx " << old[0] << ", canceled " << *bh << endl; - allocator.unallocate(old[0]); // release (into free) + // no, this isn't compatible with clone() and extent reference counting. + //allocator.unallocate(old[0]); // release (into free) + allocator.release(old[0]); alloc.insert(bh->start(), bh->length()); } else { if (bh->length() == 1) @@ -2367,7 +2369,11 @@ int Ebofs::_clone(object_t from, object_t to) // extents ton->extent_map = fon->extent_map; - //FIXME inc ref count + for (map::iterator p = ton->extent_map.begin(); + p != ton->extent_map.end(); + ++p) { + allocator.alloc_inc(p->second); + } return 0; } @@ -2375,6 +2381,51 @@ int Ebofs::_clone(object_t from, object_t to) +/* + * pick object revision with rev <= specified rev. + * (rev is essential a ctime.) + * + */ +int Ebofs::pick_object_revision(object_t& oid) +{ + int r = 0; + + ebofs_lock.Lock(); + object_t orig = oid; + + if (object_tab->get_num_keys() == 0) + r = -EEXIST; + else { + if (oid.rev == 0) oid.rev = object_t::MAXREV; + + Table::Cursor cursor(object_tab); + + object_tab->find(oid, cursor); + while (1) { + object_t t = cursor.current().key; + if (t.ino != oid.ino || + t.bno != oid.bno) { + r = -EEXIST; + break; + } + + if (t.rev <= oid.rev) { + oid = t; + break; + } + + if (cursor.move_left() <= 0) break; + } + } + + dout(8) << "find_object_revision " << orig << " -> " << oid << endl; + + ebofs_lock.Unlock(); + return r; +} + + + bool Ebofs::exists(object_t oid) { diff --git a/ceph/ebofs/Ebofs.h b/ceph/ebofs/Ebofs.h index 11a91524273c2..c89cd323f1d41 100644 --- a/ceph/ebofs/Ebofs.h +++ b/ceph/ebofs/Ebofs.h @@ -236,6 +236,8 @@ class Ebofs : public ObjectStore { // atomic transaction unsigned apply_transaction(Transaction& t, Context *onsafe=0); + int pick_object_revision(object_t& oid); + // object interface bool exists(object_t); int stat(object_t, struct stat*); @@ -275,6 +277,16 @@ class Ebofs : public ObjectStore { int collection_rmattr(coll_t cid, const char *name, Context *onsafe); int collection_listattr(coll_t oid, vector& attrs); + // maps + int map_lookup(object_t o, bufferlist& key, bufferlist& val); + int map_insert(object_t o, bufferlist& key, bufferlist& val); + int map_remove(object_t o, bufferlist& key); + int map_list(object_t o, list& keys); + int map_list(object_t o, map& vals); + int map_list(object_t o, + bufferlist& start, bufferlist& end, + map& vals); + // crap void _fake_writes(bool b) { fake_writes = b; } void _get_frag_stat(FragmentationStat& st); @@ -306,5 +318,6 @@ private: int _collection_remove(coll_t c, object_t o); int _collection_setattr(coll_t oid, const char *name, const void *value, size_t size); int _collection_rmattr(coll_t cid, const char *name); + }; diff --git a/ceph/ebofs/Table.h b/ceph/ebofs/Table.h index 84dac0d3b20da..e6b3fb39660e4 100644 --- a/ceph/ebofs/Table.h +++ b/ceph/ebofs/Table.h @@ -233,7 +233,7 @@ class Table { return -1; } - /* move left one */ + /* move right one */ assert( pos[l] < open[l].size() ); pos[l]++; @@ -510,12 +510,15 @@ class Table { // empty? if (nkeys == 0) { - // create a root node (leaf!) - assert(root == -1); - assert(depth == 0); - Nodeptr newroot( pool.new_node(Node::TYPE_LEAF) ); - root = newroot.get_id(); - depth++; + if (root == -1) { + // create a root node (leaf!) + assert(depth == 0); + Nodeptr newroot( pool.new_node(Node::TYPE_LEAF) ); + root = newroot.get_id(); + depth++; + } + assert(depth == 1); + assert(root >= 0); } // start at/near key diff --git a/ceph/ebofs/mkfs.ebofs.cc b/ceph/ebofs/mkfs.ebofs.cc index 597b27fa35178..af5f57842068a 100644 --- a/ceph/ebofs/mkfs.ebofs.cc +++ b/ceph/ebofs/mkfs.ebofs.cc @@ -40,7 +40,7 @@ int main(int argc, char **argv) Ebofs fs(filename); fs.mount(); - + /* if (1) { // partial write tests char crap[1024*1024]; @@ -285,6 +285,7 @@ int main(int argc, char **argv) } } + */ fs.sync(); fs.trim_buffer_cache(); diff --git a/ceph/ebofs/test.ebofs.cc b/ceph/ebofs/test.ebofs.cc index d4f9633bc6ec6..c6d2dfbd5d751 100644 --- a/ceph/ebofs/test.ebofs.cc +++ b/ceph/ebofs/test.ebofs.cc @@ -31,7 +31,8 @@ public: void *entry() { while (!stop) { - object_t oid = (rand() % 2) + 0x10000000; + object_t oid; + oid.ino = (rand() % 2) + 0x10000000; coll_t cid = rand() % 50; off_t off = rand() % 10000;//0;//rand() % 1000000; off_t len = 1+rand() % 100000; @@ -52,7 +53,7 @@ public: char *p = b; while (l--) { assert(*p == 0 || - *p == (char)(off ^ oid)); + *p == (char)(off ^ oid.ino)); off++; p++; } @@ -64,9 +65,10 @@ public: { cout << t << " write " << hex << oid << dec << " at " << off << " len " << len << endl; for (int j=0;j +#include #include +using std::cout; + #ifndef __CYGWIN__ # include #endif @@ -229,7 +231,7 @@ public: if (_raw) { _raw->lock.Lock(); if (--_raw->nref == 0) { - //std::cout << "hosing raw " << (void*)_raw << std::endl; + //cout << "hosing raw " << (void*)_raw << std::endl; _raw->lock.Unlock(); delete _raw; // dealloc old (if any) } else @@ -672,6 +674,33 @@ public: typedef buffer::ptr bufferptr; typedef buffer::list bufferlist; + +inline bool operator>(bufferlist& l, bufferlist& r) { + for (unsigned p = 0; ; p++) { + if (l.length() > p && r.length() == p) return true; + if (l.length() == p) return false; + if (l[p] > r[p]) return true; + if (l[p] < r[p]) return false; + p++; + } +} +inline bool operator>=(bufferlist& l, bufferlist& r) { + for (unsigned p = 0; ; p++) { + if (l.length() > p && r.length() == p) return true; + if (r.length() == p && l.length() == p) return true; + if (l[p] > r[p]) return true; + if (l[p] < r[p]) return false; + p++; + } +} +inline bool operator<(bufferlist& l, bufferlist& r) { + return r > l; +} +inline bool operator<=(bufferlist& l, bufferlist& r) { + return r >= l; +} + + inline std::ostream& operator<<(std::ostream& out, const buffer::raw &r) { return out << "buffer::raw(" << (void*)r.data << " len " << r.len << " nref " << r.nref << ")"; } diff --git a/ceph/include/object.h b/ceph/include/object.h index afeca3bfc36e6..cd24bcf0cfe04 100644 --- a/ceph/include/object.h +++ b/ceph/include/object.h @@ -19,10 +19,14 @@ using namespace std; +typedef __uint32_t objectrev_t; + struct object_t { + static const __uint32_t MAXREV = 0xffffffffU; + __uint64_t ino; // "file" identifier __uint32_t bno; // "block" in that "file" - __uint16_t rev; // revision. + objectrev_t rev; // revision. normally ctime (as epoch). object_t() : ino(0), bno(0), rev(0) {} object_t(__uint64_t i, __uint32_t b) : ino(i), bno(b), rev(0) {} diff --git a/ceph/include/types.h b/ceph/include/types.h index 3a649857deb96..76458b9b86c23 100644 --- a/ceph/include/types.h +++ b/ceph/include/types.h @@ -360,19 +360,6 @@ inline ostream& operator<<(ostream& out, const eversion_t e) { } -#ifdef OBJECT128 -//typedef lame128_t object_t; -struct object_t { - inodeno_t ino; // 64 bits - __uint32_t bno; // 32 bits - - snapv_t snap_last; // 16 bits - snapv_t snap_first; // 16 bits -}; -#else -//typedef __uint64_t object_t; // object id - -#endif #define PG_NONE 0xffffffffL diff --git a/ceph/messages/MOSDOp.h b/ceph/messages/MOSDOp.h index b8e5e6fbfdfb0..acfd203818170 100644 --- a/ceph/messages/MOSDOp.h +++ b/ceph/messages/MOSDOp.h @@ -60,6 +60,7 @@ typedef struct { tid_t rep_tid; object_t oid; + objectrev_t rev; pg_t pg; epoch_t map_epoch; diff --git a/ceph/osd/FakeStore.cc b/ceph/osd/FakeStore.cc index 7e7c9bab11d3c..c2f573a81038f 100644 --- a/ceph/osd/FakeStore.cc +++ b/ceph/osd/FakeStore.cc @@ -112,7 +112,7 @@ void FakeStore::get_dir(string& dir) { void FakeStore::get_oname(object_t oid, string& fn) { char s[100]; static hash H; - sprintf(s, "%d/%02x/%016llx.%08x", whoami, H(oid) & HASH_MASK, oid.ino, oid.bno); + sprintf(s, "%d/%02x/%016llx.%08x.%d", whoami, H(oid) & HASH_MASK, oid.ino, oid.bno, oid.rev); fn = basedir + "/" + s; // dout(1) << "oname is " << fn << endl; } diff --git a/ceph/osd/FakeStore.h b/ceph/osd/FakeStore.h index 6c92d839eda42..3f70f3b81de43 100644 --- a/ceph/osd/FakeStore.h +++ b/ceph/osd/FakeStore.h @@ -66,6 +66,9 @@ class FakeStore : public ObjectStore, // ------------------ // objects + int pick_object_revision(object_t& oid) { + return 0; + } bool exists(object_t oid); int stat(object_t oid, struct stat *st); int remove(object_t oid, Context *onsafe); diff --git a/ceph/osd/ObjectStore.h b/ceph/osd/ObjectStore.h index 986801d0f6248..7407b5c420311 100644 --- a/ceph/osd/ObjectStore.h +++ b/ceph/osd/ObjectStore.h @@ -384,6 +384,8 @@ public: virtual int statfs(struct statfs *buf) = 0; // objects + virtual int pick_object_revision(object_t& oid) = 0; + virtual bool exists(object_t oid) = 0; // useful? virtual int stat(object_t oid, struct stat *st) = 0; // struct stat? -- 2.39.5