]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: clear objects' dirty flags after log segment is expired 2375/head
authorYan, Zheng <ukernel@gmail.com>
Tue, 2 Sep 2014 09:10:41 +0000 (17:10 +0800)
committerYan, Zheng <ukernel@gmail.com>
Fri, 5 Sep 2014 00:33:21 +0000 (08:33 +0800)
When standby-replay MDS detects a log segment is expired, it should check
the expired segment's dirty lists and clear corresponding objects' dirty
bits. Otherwise these objects will be pinned in the standby-replay MDS's
cache forever.

Fixes: #8648
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/MDLog.cc

index 79d1cf2547fbb0b482c49d6f7517dbe63a54a46f..ea5bb361601808d84b74bd9776bf71e5b52663bf 100644 (file)
@@ -6142,7 +6142,7 @@ bool MDCache::trim(int max, int count)
   while (lru.lru_get_size() + unexpirable > (unsigned)max) {
     CDentry *dn = static_cast<CDentry*>(lru.lru_expire());
     if (!dn) break;
-    if ((is_standby_replay && dn->get_linkage() &&
+    if ((is_standby_replay && dn->get_linkage()->inode &&
         dn->get_linkage()->inode->item_open_file.is_on_list()) ||
        trim_dentry(dn, expiremap)) {
       unexpirables.push_back(dn);
@@ -6368,7 +6368,7 @@ bool MDCache::trim_inode(CDentry *dn, CInode *in, CDir *con, map<int, MCacheExpi
   // INODE
   if (in->is_auth()) {
     // eval stray after closing dirfrags
-    if (dn) {
+    if (dn && !mds->is_standby_replay()) {
       maybe_eval_stray(in);
       if (dn->get_num_ref() > 0)
        return true;
@@ -6687,6 +6687,40 @@ void MDCache::try_trim_non_auth_subtree(CDir *dir)
   show_subtrees();
 }
 
+void MDCache::standby_trim_segment(LogSegment *ls)
+{
+  ls->new_dirfrags.clear_list();
+  ls->open_files.clear_list();
+
+  while (!ls->dirty_dirfrags.empty()) {
+    CDir *dir = ls->dirty_dirfrags.front();
+    dir->mark_clean();
+  }
+  while (!ls->dirty_inodes.empty()) {
+    CInode *in = ls->dirty_inodes.front();
+    in->mark_clean();
+  }
+  while (!ls->dirty_dentries.empty()) {
+    CDentry *dn = ls->dirty_dentries.front();
+    dn->mark_clean();
+  }
+  while (!ls->dirty_parent_inodes.empty()) {
+    CInode *in = ls->dirty_parent_inodes.front();
+    in->clear_dirty_parent();
+  }
+  while (!ls->dirty_dirfrag_dir.empty()) {
+    CInode *in = ls->dirty_dirfrag_dir.front();
+    in->filelock.remove_dirty();
+  }
+  while (!ls->dirty_dirfrag_nest.empty()) {
+    CInode *in = ls->dirty_dirfrag_nest.front();
+    in->nestlock.remove_dirty();
+  }
+  while (!ls->dirty_dirfrag_dirfragtree.empty()) {
+    CInode *in = ls->dirty_dirfrag_dirfragtree.front();
+    in->dirfragtreelock.remove_dirty();
+  }
+}
 
 /* This function DOES put the passed message before returning */
 void MDCache::handle_cache_expire(MCacheExpire *m)
index 4baba241f3ddb1c9daf062b44314d052e83f7804..9f02b3ba31fe2444ee412c42942d09cfb36a644e 100644 (file)
@@ -566,6 +566,7 @@ public:
   void send_expire_messages(map<int, MCacheExpire*>& expiremap);
   void trim_non_auth();      // trim out trimmable non-auth items
   bool trim_non_auth_subtree(CDir *directory);
+  void standby_trim_segment(LogSegment *ls);
   void try_trim_non_auth_subtree(CDir *dir);
   bool can_trim_non_auth_dirfrag(CDir *dir) {
     return my_ambiguous_imports.count((dir)->dirfrag()) == 0 &&
index 473b7ce32b635b7d0eddb3fb0fedf5c36231364a..a10535747767a9d195d521f4d20a0431b2c9cc6d 100644 (file)
@@ -1114,15 +1114,7 @@ void MDLog::standby_trim_segments()
     if (seg->end > expire_pos)
       break;
     dout(10) << " removing segment " << seg->seq << "/" << seg->offset << dendl;
-    seg->dirty_dirfrags.clear_list();
-    seg->new_dirfrags.clear_list();
-    seg->dirty_inodes.clear_list();
-    seg->dirty_dentries.clear_list();
-    seg->open_files.clear_list();
-    seg->dirty_parent_inodes.clear_list();
-    seg->dirty_dirfrag_dir.clear_list();
-    seg->dirty_dirfrag_nest.clear_list();
-    seg->dirty_dirfrag_dirfragtree.clear_list();
+    mds->mdcache->standby_trim_segment(seg);
     remove_oldest_segment();
     removed_segment = true;
   }