From 1f82e1047120df89dbeffae96f3b76d88f842b49 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 24 Feb 2010 10:48:31 -0800 Subject: [PATCH] filer: remove -> purge_range, and scale to large ranges Redefine remove interface to operate over a range of objects numbers, not a byte range, since we are removing objects. It is the caller's responsibility to ensure they have the proper range (by mapping from the ceph_file_layout). And behave when the range is large by only allowing a few in flight remove requests at once. Eventually the objecter probably needs a more generalized request throttling mechanism, but this will do for now. --- src/mds/MDCache.cc | 10 +++-- src/osdc/Filer.cc | 85 +++++++++++++++++++++++++++++++++++++++++++ src/osdc/Filer.h | 37 +++++-------------- src/osdc/Journaler.cc | 14 ++++--- 4 files changed, 109 insertions(+), 37 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index da5c06b4cda35..9a411378fde0f 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -6920,12 +6920,14 @@ void MDCache::purge_stray(CDentry *dn) assert(in->last == CEPH_NOSNAP); } + __u64 period = in->inode.layout.fl_object_size * in->inode.layout.fl_stripe_count; __u64 to = MAX(in->inode.size, in->inode.get_max_size()); - dout(10) << "purge_stray 0~" << to << " snapc " << snapc << " on " << *in << dendl; + __u64 num = (to + period - 1) / period; + dout(10) << "purge_stray 0~" << to << " objects 0~" << num << " snapc " << snapc << " on " << *in << dendl; if (to) - mds->filer->remove(in->inode.ino, &in->inode.layout, *snapc, - 0, to, g_clock.now(), 0, - 0, new C_MDC_PurgeStrayPurged(this, dn)); + mds->filer->purge_range(in->inode.ino, &in->inode.layout, *snapc, + 0, num, g_clock.now(), 0, + new C_MDC_PurgeStrayPurged(this, dn)); else _purge_stray_purged(dn); } diff --git a/src/osdc/Filer.cc b/src/osdc/Filer.cc index cba7c126db1d0..adc54211c5c39 100644 --- a/src/osdc/Filer.cc +++ b/src/osdc/Filer.cc @@ -210,6 +210,91 @@ void Filer::_probed(Probe *probe, const object_t& oid, __u64 size, utime_t mtime } +// ----------------------- + +struct PurgeRange { + inodeno_t ino; + ceph_file_layout layout; + SnapContext snapc; + __u64 first, num; + utime_t mtime; + int flags; + Context *oncommit; + int uncommitted; +}; + +int Filer::purge_range(inodeno_t ino, + ceph_file_layout *layout, + const SnapContext& snapc, + __u64 first_obj, __u64 num_obj, + utime_t mtime, + int flags, + Context *oncommit) +{ + assert(num_obj > 0); + + // single object? easy! + if (num_obj == 1) { + object_t oid = file_object_t(ino, first_obj); + ceph_object_layout ol = objecter->osdmap->file_to_object_layout(oid, *layout); + objecter->remove(oid, ol, snapc, mtime, flags, NULL, oncommit); + return 0; + } + + // lots! let's do this in pieces. + PurgeRange *pr = new PurgeRange; + pr->ino = ino; + pr->layout = *layout; + pr->snapc = snapc; + pr->first = first_obj; + pr->num = num_obj; + pr->mtime = mtime; + pr->flags = flags; + pr->oncommit = oncommit; + pr->uncommitted = 0; + + _do_purge_range(pr, 0); + return 0; +} + +struct C_PurgeRange : public Context { + Filer *filer; + PurgeRange *pr; + C_PurgeRange(Filer *f, PurgeRange *p) : filer(f), pr(p) {} + void finish(int r) { + filer->_do_purge_range(pr, 1); + } +}; + +void Filer::_do_purge_range(PurgeRange *pr, int fin) +{ + pr->uncommitted -= fin; + dout(10) << "_do_purge_range " << pr->ino << " objects " << pr->first << "~" << pr->num + << " uncommitted " << pr->uncommitted << dendl; + + if (pr->num == 0 && pr->uncommitted == 0) { + pr->oncommit->finish(0); + delete pr->oncommit; + delete pr; + return; + } + + int max = 10 - pr->uncommitted; + while (pr->num > 0 && max > 0) { + object_t oid = file_object_t(pr->ino, pr->first); + ceph_object_layout ol = objecter->osdmap->file_to_object_layout(oid, pr->layout); + objecter->remove(oid, ol, pr->snapc, pr->mtime, pr->flags, + NULL, new C_PurgeRange(this, pr)); + pr->uncommitted++; + pr->first++; + pr->num--; + max--; + } +} + + +// ----------------------- + void Filer::file_to_extents(inodeno_t ino, ceph_file_layout *layout, __u64 offset, __u64 len, vector& extents) diff --git a/src/osdc/Filer.h b/src/osdc/Filer.h index 6e9dcb1d515cb..f7e4ba2b0a556 100644 --- a/src/osdc/Filer.h +++ b/src/osdc/Filer.h @@ -240,34 +240,15 @@ class Filer { return 0; } - int remove(inodeno_t ino, - ceph_file_layout *layout, - const SnapContext& snapc, - __u64 offset, - __u64 len, - utime_t mtime, - int flags, - Context *onack, - Context *oncommit) { - vector extents; - file_to_extents(ino, layout, offset, len, extents); - if (extents.size() == 1) { - objecter->remove(extents[0].oid, extents[0].layout, - snapc, mtime, flags, onack, oncommit); - } else { - C_Gather *gack = 0, *gcom = 0; - if (onack) - gack = new C_Gather(onack); - if (oncommit) - gcom = new C_Gather(oncommit); - for (vector::iterator p = extents.begin(); p != extents.end(); p++) - objecter->remove(p->oid, p->layout, - snapc, mtime, flags, - gack ? gack->new_sub():0, - gcom ? gcom->new_sub():0); - } - return 0; - } + // purge range of ino.### objects + int purge_range(inodeno_t ino, + ceph_file_layout *layout, + const SnapContext& snapc, + __u64 first_obj, __u64 num_obj, + utime_t mtime, + int flags, + Context *oncommit); + void _do_purge_range(class PurgeRange *pr, int fin); /* * probe diff --git a/src/osdc/Journaler.cc b/src/osdc/Journaler.cc index d4111578e09a5..85ef1a783a2c3 100644 --- a/src/osdc/Journaler.cc +++ b/src/osdc/Journaler.cc @@ -782,8 +782,10 @@ public: void Journaler::trim() { + __u64 period = layout.fl_stripe_count * layout.fl_object_size; + __s64 trim_to = last_committed.expire_pos; - trim_to -= trim_to % (layout.fl_stripe_count * layout.fl_object_size); + trim_to -= trim_to % period; dout(10) << "trim last_commited head was " << last_committed << ", can trim to " << trim_to << dendl; @@ -806,11 +808,13 @@ void Journaler::trim() << ", trimmed/trimming/expire are " << trimmed_pos << "/" << trimming_pos << "/" << expire_pos << dendl; - + + // delete range of objects + __u64 first = trimming_pos / period; + __u64 num = (trim_to - trimming_pos) / period; SnapContext snapc; - filer.remove(ino, &layout, snapc, - trimming_pos, trim_to-trimming_pos, g_clock.now(), 0, - NULL, new C_Trim(this, trim_to)); + filer.purge_range(ino, &layout, snapc, first, num, g_clock.now(), 0, + new C_Trim(this, trim_to)); trimming_pos = trim_to; } -- 2.39.5