From: Sage Weil Date: Thu, 14 Jan 2016 16:32:15 +0000 (-0500) Subject: os/FuseStore: use offset for readdir X-Git-Tag: v10.0.4~154^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f84384ac9a6686180a1696c5513e7aead197e046;p=ceph.git os/FuseStore: use offset for readdir This allows us to list large directories. Signed-off-by: Sage Weil --- diff --git a/src/os/FuseStore.cc b/src/os/FuseStore.cc index 37a22af11510..5d8303b7372a 100644 --- a/src/os/FuseStore.cc +++ b/src/os/FuseStore.cc @@ -359,6 +359,9 @@ static int os_readdir(const char *path, fuse_context *fc = fuse_get_context(); FuseStore *fs = static_cast(fc->private_data); + // we can't shift 32 bits or else off_t will go negative + const int hash_shift = 31; + switch (t) { case FN_ROOT: { @@ -400,38 +403,36 @@ static int os_readdir(const char *path, } break; - case FN_ALL: - { - ghobject_t next; - while (true) { - vector ls; - int r = fs->store->collection_list( - cid, next, ghobject_t::get_max(), true, 1000, &ls, &next); - if (r < 0) - break; - for (auto p : ls) { - string s = stringify(p); - filler(buf, s.c_str(), NULL, 0); - } - if (next == ghobject_t::get_max()) - break; - } - } - break; - case FN_HASH_VAL: + case FN_ALL: { + uint32_t bitwise_hash = (offset >> hash_shift) & 0xffffffff; + uint32_t hashoff = offset - (bitwise_hash << hash_shift); + int skip = hashoff; ghobject_t next = cid.get_min_hobj(); - next.hobj.set_hash(hobject_t::_reverse_bits(hash_value)); - ghobject_t last = next; - uint64_t rev_end = (hash_value | (0xffffffff >> hash_bits)) + 1; - if (rev_end >= 0x100000000) + if (offset) { + // obey the offset + next.hobj.set_hash(hobject_t::_reverse_bits(bitwise_hash)); + } else if (t == FN_HASH_VAL) { + next.hobj.set_hash(hobject_t::_reverse_bits(hash_value)); + } + ghobject_t last; + if (t == FN_HASH_VAL) { + last = next; + uint64_t rev_end = (hash_value | (0xffffffff >> hash_bits)) + 1; + if (rev_end >= 0x100000000) + last = ghobject_t::get_max(); + else + last.hobj.set_hash(hobject_t::_reverse_bits(rev_end)); + } else { last = ghobject_t::get_max(); - else - last.hobj.set_hash(hobject_t::_reverse_bits(rev_end)); - dout(10) << __func__ << " hash " << std::hex - << hobject_t::_reverse_bits(hash_value) << std::dec - << "/" << hash_bits << " first " << next << " last " << last + } + dout(10) << __func__ << std::hex + << " offset " << offset << " hash " + << hobject_t::_reverse_bits(hash_value) + << std::dec + << "/" << hash_bits + << " first " << next << " last " << last << dendl; while (true) { vector ls; @@ -440,9 +441,25 @@ static int os_readdir(const char *path, if (r < 0) break; for (auto p : ls) { + if (skip) { + --skip; + continue; + } + uint32_t cur_bitwise_hash = p.hobj.get_bitwise_key_u32(); + if (cur_bitwise_hash != bitwise_hash) { + bitwise_hash = cur_bitwise_hash; + hashoff = 0; + } + ++hashoff; + uint64_t cur_off = ((uint64_t)bitwise_hash << hash_shift) | + (uint64_t)hashoff; string s = stringify(p); - filler(buf, s.c_str(), NULL, 0); + r = filler(buf, s.c_str(), NULL, cur_off); + if (r) + break; } + if (r) + break; if (next == ghobject_t::get_max() || next == last) break; }