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" <zyan@redhat.com>
This commit is contained in:
Yan, Zheng 2017-05-17 19:08:37 +08:00
parent 26df056e34
commit 538f35bef9
3 changed files with 18 additions and 16 deletions

View File

@ -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)

View File

@ -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<client_t,client_writeable_range_t> *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;

View File

@ -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<client_t, client_writeable_range_t>* new_ranges,