From: John Spray Date: Mon, 19 Dec 2016 14:03:04 +0000 (+0000) Subject: mds: move dir purge and truncate into purgequeue X-Git-Tag: v12.0.1~140^2~20 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ed4c7cbea84305a7e7136f166b087ed8a1a8e03e;p=ceph.git mds: move dir purge and truncate into purgequeue Signed-off-by: John Spray --- diff --git a/src/mds/PurgeQueue.cc b/src/mds/PurgeQueue.cc index bcf1e9990653..d39b09b2cc49 100644 --- a/src/mds/PurgeQueue.cc +++ b/src/mds/PurgeQueue.cc @@ -30,22 +30,26 @@ static ostream& _prefix(std::ostream *_dout, mds_rank_t rank) { void PurgeItem::encode(bufferlist &bl) const { ENCODE_START(1, 1, bl); + ::encode((uint8_t)action, bl); ::encode(ino, bl); ::encode(size, bl); ::encode(layout, bl, CEPH_FEATURE_FS_FILE_LAYOUT_V2); ::encode(old_pools, bl); ::encode(snapc, bl); + ::encode(fragtree, bl); ENCODE_FINISH(bl); } void PurgeItem::decode(bufferlist::iterator &p) { DECODE_START(1, p); + ::decode((uint8_t&)action, p); ::decode(ino, p); ::decode(size, p); ::decode(layout, p); ::decode(old_pools, p); ::decode(snapc, p); + ::decode(fragtree, p); DECODE_FINISH(p); } @@ -131,6 +135,9 @@ void PurgeQueue::create(Context *fin) journaler.write_head(fin); } +/** + * The `completion` context will always be called back via a Finisher + */ void PurgeQueue::push(const PurgeItem &pi, Context *completion) { dout(4) << "pushing inode 0x" << std::hex << pi.ino << std::dec << dendl; @@ -269,37 +276,72 @@ void PurgeQueue::_execute_item( in_flight[expire_to] = item; - // TODO: handle things other than normal file purges - // (directories, snapshot truncates) + SnapContext nullsnapc; + C_GatherBuilder gather(cct); - if (item.size > 0) { - uint64_t num = Striper::get_num_objects(item.layout, item.size); - dout(10) << " 0~" << item.size << " objects 0~" << num - << " snapc " << item.snapc << " on " << item.ino << dendl; - filer.purge_range(item.ino, &item.layout, item.snapc, - 0, num, ceph::real_clock::now(), 0, - gather.new_sub()); - } + if (item.action == PurgeItem::PURGE_FILE) { + if (item.size > 0) { + uint64_t num = Striper::get_num_objects(item.layout, item.size); + dout(10) << " 0~" << item.size << " objects 0~" << num + << " snapc " << item.snapc << " on " << item.ino << dendl; + filer.purge_range(item.ino, &item.layout, item.snapc, + 0, num, ceph::real_clock::now(), 0, + gather.new_sub()); + } - // remove the backtrace object if it was not purged - object_t oid = CInode::get_object_name(item.ino, frag_t(), ""); - if (!gather.has_subs() || !item.layout.pool_ns.empty()) { - object_locator_t oloc(item.layout.pool_id); - dout(10) << " remove backtrace object " << oid - << " pool " << oloc.pool << " snapc " << item.snapc << dendl; - objecter->remove(oid, oloc, item.snapc, - ceph::real_clock::now(), 0, - NULL, gather.new_sub()); - } + // remove the backtrace object if it was not purged + object_t oid = CInode::get_object_name(item.ino, frag_t(), ""); + if (!gather.has_subs() || !item.layout.pool_ns.empty()) { + object_locator_t oloc(item.layout.pool_id); + dout(10) << " remove backtrace object " << oid + << " pool " << oloc.pool << " snapc " << item.snapc << dendl; + objecter->remove(oid, oloc, item.snapc, + ceph::real_clock::now(), 0, + NULL, gather.new_sub()); + } - // remove old backtrace objects - for (const auto &p : item.old_pools) { - object_locator_t oloc(p); - dout(10) << " remove backtrace object " << oid - << " old pool " << p << " snapc " << item.snapc << dendl; - objecter->remove(oid, oloc, item.snapc, - ceph::real_clock::now(), 0, - NULL, gather.new_sub()); + // remove old backtrace objects + for (const auto &p : item.old_pools) { + object_locator_t oloc(p); + dout(10) << " remove backtrace object " << oid + << " old pool " << p << " snapc " << item.snapc << dendl; + objecter->remove(oid, oloc, item.snapc, + ceph::real_clock::now(), 0, + NULL, gather.new_sub()); + } + } else if (item.action == PurgeItem::PURGE_DIR) { + object_locator_t oloc(metadata_pool); + std::list frags; + if (!item.fragtree.is_leaf(frag_t())) + item.fragtree.get_leaves(frags); + frags.push_back(frag_t()); + for (const auto &frag : frags) { + object_t oid = CInode::get_object_name(item.ino, frag, ""); + dout(10) << " remove dirfrag " << oid << dendl; + objecter->remove(oid, oloc, nullsnapc, + ceph::real_clock::now(), + 0, NULL, gather.new_sub()); + } + } else if (item.action == PurgeItem::TRUNCATE_FILE) { + const uint64_t num = Striper::get_num_objects(item.layout, item.size); + dout(10) << " 0~" << item.size << " objects 0~" << num + << " snapc " << item.snapc << " on " << item.ino << dendl; + + // keep backtrace object + if (num > 1) { + filer.purge_range(item.ino, &item.layout, item.snapc, + 1, num - 1, ceph::real_clock::now(), + 0, gather.new_sub()); + } + filer.zero(item.ino, &item.layout, item.snapc, + 0, item.layout.object_size, + ceph::real_clock::now(), + 0, true, NULL, gather.new_sub()); + } else { + derr << "Invalid item (action=" << item.action << ") in purge queue, " + "dropping it" << dendl; + in_flight.erase(expire_to); + return; } assert(gather.has_subs()); diff --git a/src/mds/PurgeQueue.h b/src/mds/PurgeQueue.h index b7ed4345f732..f6b4aa1569c3 100644 --- a/src/mds/PurgeQueue.h +++ b/src/mds/PurgeQueue.h @@ -29,14 +29,23 @@ class PurgeItem { public: + enum Action : uint8_t { + NONE = 0, + PURGE_FILE = 1, + TRUNCATE_FILE, + PURGE_DIR + }; + + Action action; inodeno_t ino; uint64_t size; file_layout_t layout; compact_set old_pools; SnapContext snapc; + fragtree_t fragtree; PurgeItem() - : ino(0), size(0) + : action(NONE), ino(0), size(0) {} void encode(bufferlist &bl) const; diff --git a/src/mds/StrayManager.cc b/src/mds/StrayManager.cc index 0b793447633b..816f9249883c 100644 --- a/src/mds/StrayManager.cc +++ b/src/mds/StrayManager.cc @@ -15,8 +15,6 @@ #include "common/perf_counters.h" -#include "osdc/Objecter.h" -#include "osdc/Filer.h" #include "mds/MDSRank.h" #include "mds/MDCache.h" #include "mds/MDLog.h" @@ -99,65 +97,46 @@ void StrayManager::purge(CDentry *dn) // dir. on recovery, we'll need to re-eval all strays anyway. SnapContext nullsnapc; - C_GatherBuilder gather( - g_ceph_context, - new C_OnFinisher(new C_IO_PurgeStrayPurged( - this, dn, false), mds->finisher)); + PurgeItem item; + item.ino = in->inode.ino; if (in->is_dir()) { - object_locator_t oloc(mds->mdsmap->get_metadata_pool()); - std::list ls; - if (!in->dirfragtree.is_leaf(frag_t())) - in->dirfragtree.get_leaves(ls); - ls.push_back(frag_t()); - for (std::list::iterator p = ls.begin(); - p != ls.end(); - ++p) { - object_t oid = CInode::get_object_name(in->inode.ino, *p, ""); - dout(10) << __func__ << " remove dirfrag " << oid << dendl; - mds->objecter->remove(oid, oloc, nullsnapc, - ceph::real_clock::now(), - 0, gather.new_sub()); - } - assert(gather.has_subs()); - gather.activate(); - return; - } - - const SnapContext *snapc; - SnapRealm *realm = in->find_snaprealm(); - if (realm) { - dout(10) << " realm " << *realm << dendl; - snapc = &realm->get_snap_context(); + item.action = PurgeItem::PURGE_DIR; + item.fragtree = in->dirfragtree; } else { - dout(10) << " NO realm, using null context" << dendl; - snapc = &nullsnapc; - assert(in->last == CEPH_NOSNAP); - } + item.action = PurgeItem::PURGE_FILE; - uint64_t to = 0; - if (in->is_file()) { - to = in->inode.get_max_size(); - to = MAX(in->inode.size, to); - // when truncating a file, the filer does not delete stripe objects that are - // truncated to zero. so we need to purge stripe objects up to the max size - // the file has ever been. - to = MAX(in->inode.max_size_ever, to); - } + const SnapContext *snapc; + SnapRealm *realm = in->find_snaprealm(); + if (realm) { + dout(10) << " realm " << *realm << dendl; + snapc = &realm->get_snap_context(); + } else { + dout(10) << " NO realm, using null context" << dendl; + snapc = &nullsnapc; + assert(in->last == CEPH_NOSNAP); + } - inode_t *pi = in->get_projected_inode(); + uint64_t to = 0; + if (in->is_file()) { + to = in->inode.get_max_size(); + to = MAX(in->inode.size, to); + // when truncating a file, the filer does not delete stripe objects that are + // truncated to zero. so we need to purge stripe objects up to the max size + // the file has ever been. + to = MAX(in->inode.max_size_ever, to); + } - PurgeItem item; - item.ino = in->inode.ino; - item.size = to; - item.layout = pi->layout; - item.old_pools = pi->old_pools; - item.snapc = *snapc; + inode_t *pi = in->get_projected_inode(); - purge_queue.push(item, gather.new_sub()); + item.size = to; + item.layout = pi->layout; + item.old_pools = pi->old_pools; + item.snapc = *snapc; + } - assert(gather.has_subs()); - gather.activate(); + purge_queue.push(item, new C_IO_PurgeStrayPurged( + this, dn, false)); } class C_PurgeStrayLogged : public StrayManagerLogContext { @@ -679,25 +658,20 @@ StrayManager::StrayManager(MDSRank *mds, PurgeQueue &purge_queue_) : delayed_eval_stray(member_offset(CDentry, item_stray)), mds(mds), logger(NULL), started(false), num_strays(0), num_strays_delayed(0), num_strays_enqueuing(0), - filer(mds->objecter, mds->finisher), purge_queue(purge_queue_) + purge_queue(purge_queue_) { assert(mds != NULL); } void StrayManager::truncate(CDentry *dn) { - CDentry::linkage_t *dnl = dn->get_projected_linkage(); - CInode *in = dnl->get_inode(); + const CDentry::linkage_t *dnl = dn->get_projected_linkage(); + const CInode *in = dnl->get_inode(); assert(in); dout(10) << __func__ << ": " << *dn << " " << *in << dendl; assert(!dn->is_replicated()); - C_GatherBuilder gather( - g_ceph_context, - new C_OnFinisher(new C_IO_PurgeStrayPurged(this, dn, true), - mds->finisher)); - - SnapRealm *realm = in->find_snaprealm(); + const SnapRealm *realm = in->find_snaprealm(); assert(realm); dout(10) << " realm " << *realm << dendl; const SnapContext *snapc = &realm->get_snap_context(); @@ -708,25 +682,17 @@ void StrayManager::truncate(CDentry *dn) // truncated to zero. so we need to purge stripe objects up to the max size // the file has ever been. to = MAX(in->inode.max_size_ever, to); - if (to > 0) { - uint64_t num = Striper::get_num_objects(in->inode.layout, to); - dout(10) << __func__ << " 0~" << to << " objects 0~" << num - << " snapc " << snapc << " on " << *in << dendl; - - // keep backtrace object - if (num > 1) { - filer.purge_range(in->ino(), &in->inode.layout, *snapc, - 1, num - 1, ceph::real_clock::now(), - 0, gather.new_sub()); - } - filer.zero(in->ino(), &in->inode.layout, *snapc, - 0, in->inode.layout.object_size, - ceph::real_clock::now(), - 0, true, gather.new_sub()); - } - assert(gather.has_subs()); - gather.activate(); + assert(to > 0); + + PurgeItem item; + item.ino = in->inode.ino; + item.layout = in->inode.layout; + item.snapc = *snapc; + item.size = to; + + purge_queue.push(item, new C_IO_PurgeStrayPurged( + this, dn, true)); } void StrayManager::_truncate_stray_logged(CDentry *dn, LogSegment *ls) diff --git a/src/mds/StrayManager.h b/src/mds/StrayManager.h index 3124478bf63d..eff21958ddfb 100644 --- a/src/mds/StrayManager.h +++ b/src/mds/StrayManager.h @@ -16,7 +16,6 @@ #include "include/elist.h" #include -#include "osdc/Filer.h" #include "mds/PurgeQueue.h" class MDSRank; @@ -49,8 +48,6 @@ class StrayManager // recorded by PurgeQueue yet uint64_t num_strays_enqueuing; - Filer filer; - PurgeQueue &purge_queue; void truncate(CDentry *dn);