]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: limit client writable range increment
authorYan, Zheng <zyan@redhat.com>
Wed, 17 May 2017 11:08:37 +0000 (19:08 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 22 May 2017 08:45:11 +0000 (16:45 +0800)
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>
src/common/config_opts.h
src/mds/Locker.cc
src/mds/Locker.h

index f9509f5798289d1d23a37a4b2bcf866d6b00da7e..d0dcfa83c92059c2b3c255b6f498c80fbd7ee479 100644 (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)
 
index 18125e3ef456f87de1435e727cb4f03e5feee811..7070cb2116c147a3fd6d5b5cc14bb0d27776d494 100644 (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;
index eb3d45ce58158c33fe1b777516e3335551352eeb..32b7d63016e4cdd8cabeb07eb6d3f9e9fa430b50 100644 (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,