From 538f35bef944b18e9bca2b15ed7f4e8807ef0554 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 17 May 2017 19:08:37 +0800 Subject: [PATCH] mds: limit client writable range increment For very large file, setting the writable range to '2 * file_size' causes file recovery to run a long time. To recover a 1T file, Filer needs to probe 2T~1T range. Fixes: http://tracker.ceph.com/issues/19955 Signed-off-by: "Yan, Zheng" --- src/common/config_opts.h | 3 +++ src/mds/Locker.cc | 29 +++++++++++++---------------- src/mds/Locker.h | 2 ++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index f9509f57982..d0dcfa83c92 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -628,6 +628,9 @@ OPTION(mds_max_scrub_ops_in_progress, OPT_INT, 5) // the number of simultaneous // Maximum number of damaged frags/dentries before whole MDS rank goes damaged OPTION(mds_damage_table_max_entries, OPT_INT, 10000) +// Maximum increment for client writable range, counted by number of objects +OPTION(mds_client_writeable_range_max_inc_objs, OPT_U32, 1024) + // verify backend can support configured max object name length OPTION(osd_check_max_object_name_len_on_startup, OPT_BOOL, true) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 18125e3ef45..7070cb2116c 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -2231,6 +2231,16 @@ public: } }; +uint64_t Locker::calc_new_max_size(inode_t *pi, uint64_t size) +{ + uint64_t new_max = (size + 1) << 1; + uint64_t max_inc = g_conf->mds_client_writeable_range_max_inc_objs; + if (max_inc > 0) { + max_inc *= pi->get_layout_size_increment(); + new_max = MIN(new_max, size + max_inc); + } + return ROUND_UP_TO(new_max, pi->get_layout_size_increment()); +} void Locker::calc_new_client_ranges(CInode *in, uint64_t size, map *new_ranges, @@ -2239,7 +2249,7 @@ void Locker::calc_new_client_ranges(CInode *in, uint64_t size, inode_t *latest = in->get_projected_inode(); uint64_t ms; if(latest->has_layout()) { - ms = ROUND_UP_TO((size+1)<<1, latest->get_layout_size_increment()); + ms = calc_new_max_size(latest, size); } else { // Layout-less directories like ~mds0/, have zero size ms = 0; @@ -2977,17 +2987,6 @@ void Locker::kick_cap_releases(MDRequestRef& mdr) } } -static uint64_t calc_bounding(uint64_t t) -{ - t |= t >> 1; - t |= t >> 2; - t |= t >> 4; - t |= t >> 8; - t |= t >> 16; - t |= t >> 32; - return t + 1; -} - /** * m and ack might be NULL, so don't dereference them unless dirty != 0 */ @@ -3204,11 +3203,9 @@ bool Locker::_do_cap_update(CInode *in, Capability *cap, << " > max " << old_max << dendl; change_max = true; forced_change_max = true; - new_max = ROUND_UP_TO((m->get_max_size()+1) << 1, latest->get_layout_size_increment()); + new_max = calc_new_max_size(latest, m->get_max_size()); } else { - new_max = calc_bounding(size * 2); - if (new_max < latest->get_layout_size_increment()) - new_max = latest->get_layout_size_increment(); + new_max = calc_new_max_size(latest, size); if (new_max > old_max) change_max = true; diff --git a/src/mds/Locker.h b/src/mds/Locker.h index eb3d45ce581..32b7d63016e 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -250,6 +250,8 @@ protected: void file_update_finish(CInode *in, MutationRef& mut, bool share_max, bool issue_client_cap, client_t client, MClientCaps *ack); +private: + uint64_t calc_new_max_size(inode_t *pi, uint64_t size); public: void calc_new_client_ranges(CInode *in, uint64_t size, map* new_ranges,