]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: limit client writable range increment
authorYan, Zheng <zyan@redhat.com>
Wed, 17 May 2017 11:08:37 +0000 (19:08 +0800)
committerNathan Cutler <ncutler@suse.com>
Mon, 19 Jun 2017 17:33:16 +0000 (19:33 +0200)
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>
(cherry picked from commit 538f35bef944b18e9bca2b15ed7f4e8807ef0554)

Conflicts:
        src/mds/Locker.h - in jewel, file_update_finish() has different
            arguments than it does in master

src/common/config_opts.h
src/mds/Locker.cc
src/mds/Locker.h

index 125f06674c8b6e460c2c6cdd65e36c96f1098ecd..60ff9772e53929ee7d55c705874e395016c9d152 100644 (file)
@@ -562,6 +562,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 410ad14f4fc848d8f5fa8da684c66decb40025ca..c4dcadd85803c27d0e1a5227c8263cb09debe4d4 100644 (file)
@@ -2153,13 +2153,23 @@ 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)
 {
   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;
@@ -2876,17 +2886,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
  */
@@ -3089,11 +3088,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 653988ecfb756169dfcbd4ceb5f186df3f9cadbb..569e2882d946cbf72199b10643768cd8b3b6c25d 100644 (file)
@@ -250,6 +250,8 @@ protected:
 
   void file_update_finish(CInode *in, MutationRef& mut, bool share, client_t client, Capability *cap,
                          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);
   bool check_inode_max_size(CInode *in, bool force_wrlock=false,