]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: pin inode while one renamed_files list
authorSage Weil <sage@newdream.net>
Thu, 2 Jun 2011 20:14:48 +0000 (13:14 -0700)
committerSage Weil <sage@newdream.net>
Thu, 2 Jun 2011 20:16:31 +0000 (13:16 -0700)
Make sure the inode is pinned while it is on the LogSegment::renamed_files
list.  Avoids a crash when an inode on that list is wrongly trimmed.

Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/CDir.cc
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Server.cc

index efa4962b0eba4a2bd89a806b41282cbe70d4aa26..d7390d8e62bcc4b8f1eda16ad51c659c19db8512 100644 (file)
@@ -1997,6 +1997,7 @@ void CDir::_committed(version_t v, version_t lrv)
       lrv == inode->inode.last_renamed_version) {
     inode->item_renamed_file.remove_myself();
     inode->state_clear(CInode::STATE_DIRTYPARENT);
+    inode->put(CInode::PIN_DIRTYPARENT);
     dout(10) << "_committed  stored parent pointer, removed from renamed_files list " << *inode << dendl;
   }
   
index 321ec01f04e60773176889cf70487d736fc8f985..76b0d964612d4486cb2c22398a5ae65c114a7483 100644 (file)
@@ -1098,13 +1098,18 @@ void CInode::store_parent(Context *fin)
 
 void CInode::_stored_parent(version_t v, Context *fin)
 {
-  if (v == inode.last_renamed_version) {
-    dout(10) << "stored_parent committed v" << v << ", removing from list" << dendl;
-    item_renamed_file.remove_myself();
-    state_clear(STATE_DIRTYPARENT);
+  if (state_test(STATE_DIRTYPARENT)) {
+    if (v == inode.last_renamed_version) {
+      dout(10) << "stored_parent committed v" << v << ", removing from list" << dendl;
+      item_renamed_file.remove_myself();
+      state_clear(STATE_DIRTYPARENT);
+      put(PIN_DIRTYPARENT);
+    } else {
+      dout(10) << "stored_parent committed v" << v << " < " << inode.last_renamed_version
+              << ", renamed again, not removing from list" << dendl;
+    }
   } else {
-    dout(10) << "stored_parent committed v" << v << " < " << inode.last_renamed_version
-            << ", renamed again, not removing from list" << dendl;
+    dout(10) << "stored_parent committed v" << v << ", tho i wasn't on the renamed_files list" << dendl;
   }
   if (fin) {
     fin->finish(0);
index d37a6d2ada0522a15f5101fb40e51933b9688c2e..b851fc9ad3181367cf9fee23105df8d66054d1fa 100644 (file)
@@ -137,6 +137,7 @@ public:
   static const int PIN_NEEDSNAPFLUSH =    20;
   static const int PIN_DIRTYRSTAT =       21;
   static const int PIN_EXPORTINGCAPS =    22;
+  static const int PIN_DIRTYPARENT =      23;
 
   const char *pin_name(int p) {
     switch (p) {
@@ -161,6 +162,7 @@ public:
     case PIN_STRAY: return "stray";
     case PIN_NEEDSNAPFLUSH: return "needsnapflush";
     case PIN_DIRTYRSTAT: return "dirtyrstat";
+    case PIN_DIRTYPARENT: return "dirtyparent";
     default: return generic_pin_name(p);
     }
   }
index c1eceff53351c19b567863da10e0521d86c4c788..3166df6d29584f5ba72c4a058546314b9a815072 100644 (file)
@@ -5372,8 +5372,13 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
 
       if (desti->is_dir()) {
        mdr->ls->renamed_files.push_back(&desti->item_renamed_file);
-       desti->state_set(CInode::STATE_DIRTYPARENT);
-       dout(10) << "added dir to logsegment renamed_files list " << *desti << dendl;
+       if (!desti->state_test(CInode::STATE_DIRTYPARENT)) {
+         desti->state_set(CInode::STATE_DIRTYPARENT);
+         desti->get(CInode::PIN_DIRTYPARENT);
+         dout(10) << "added dir to logsegment renamed_files list " << *desti << dendl;
+       } else {
+         dout(10) << "re-added dir to logsegment renamed_files list " << *desti << dendl;
+       }
       }
     } else {
       // FIXME: fix up snaprealm!