]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: adjust subtree roots on rename
authorSage Weil <sage.weil@dreamhost.com>
Mon, 6 Jun 2011 20:30:25 +0000 (13:30 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Mon, 6 Jun 2011 20:30:25 +0000 (13:30 -0700)
If we replay a dir rename operation, we need to adjust the subtree map
accordingly.

This covers the case where the metablob contains both the src and dest
dentries.  Remaining cases will follow.

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
src/mds/Server.cc
src/mds/events/EMetaBlob.h
src/mds/journal.cc

index 04a13c0b56ad9cc78812f31aef9b7cf360a160ec..cf849995ab2fc5e46aa2a6f11b726bc3ed2bb262 100644 (file)
@@ -5090,6 +5090,12 @@ void Server::_rename_prepare(MDRequest *mdr,
   if (silent)
     dout(10) << " reintegrating stray; will avoid changing nlink or dir mtime" << dendl;
 
+  if (srci->is_dir() &&
+      (srcdn->is_auth() || destdn->is_auth())) {
+    dout(10) << " noting renamed dir ino " << srci->ino() << " in metablob" << dendl;
+    metablob->renamed_dirino = srci->ino();
+  }
+
   // prepare
   inode_t *pi = 0, *ji = 0;    // renamed inode
   inode_t *tpi = 0, *tji = 0;  // target/overwritten inode
index deb4ed3b9ed2da362e97bf9b1af88cf4fa933f90..3eee2d0243ff3213d2615c99bf6fda0284477dce 100644 (file)
@@ -352,6 +352,9 @@ private:
   list<pair<__u8,version_t> > table_tids;  // tableclient transactions
 
   inodeno_t opened_ino;
+public:
+  inodeno_t renamed_dirino;
+private:
   
   // ino (pre)allocation.  may involve both inotable AND session state.
   version_t inotablev, sessionmapv;
@@ -371,7 +374,7 @@ private:
 
  public:
   void encode(bufferlist& bl) const {
-    __u8 struct_v = 2;
+    __u8 struct_v = 3;
     ::encode(struct_v, bl);
     ::encode(lump_order, bl);
     ::encode(lump_map, bl);
@@ -391,6 +394,7 @@ private:
     ::encode(truncate_finish, bl);
     ::encode(destroyed_inodes, bl);
     ::encode(client_reqs, bl);
+    ::encode(renamed_dirino, bl);
   } 
   void decode(bufferlist::iterator &bl) {
     __u8 struct_v;
@@ -414,9 +418,9 @@ private:
     ::decode(truncate_start, bl);
     ::decode(truncate_finish, bl);
     ::decode(destroyed_inodes, bl);
-    if (struct_v >= 2) 
+    if (struct_v >= 2) {
       ::decode(client_reqs, bl);
-    else {
+    else {
       list<metareqid_t> r;
       ::decode(r, bl);
       while (!r.empty()) {
@@ -424,6 +428,8 @@ private:
        r.pop_front();
       }
     }
+    if (struct_v >= 3)
+      ::decode(renamed_dirino, bl);
   }
 
 
index 0e66e2262e2e1c515795f5eecff6d0a21294954e..bd30592a0bdd9b83ac5447a8ce3a2b1d91172dfc 100644 (file)
@@ -310,7 +310,7 @@ void EString::replay(MDS *mds)
 // EMetaBlob
 
 EMetaBlob::EMetaBlob(MDLog *mdlog) : root(NULL),
-                                    opened_ino(0),
+                                    opened_ino(0), renamed_dirino(0),
                                     inotablev(0), sessionmapv(0),
                                     allocated_ino(0),
                                     last_subtree_map(mdlog ? mdlog->get_last_segment_offset() : 0),
@@ -463,6 +463,16 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
     dout(10) << "EMetaBlob.replay " << (isnew ? " added root ":" updated root ") << *in << dendl;    
   }
 
+  CInode *renamed_diri = 0;
+  CDir *olddir = 0;
+  if (renamed_dirino) {
+    renamed_diri = mds->mdcache->get_inode(renamed_dirino);
+    if (renamed_diri)
+      dout(10) << "EMetaBlob.replay renamed inode is " << *renamed_diri << dendl;
+    else
+      dout(10) << "EMetaBlob.replay don't have renamed ino " << renamed_dirino << dendl;
+  }
+
   // walk through my dirs (in order!)
   for (list<dirfrag_t>::iterator lp = lump_order.begin();
        lp != lump_order.end();
@@ -620,6 +630,9 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
        dn->first = p->dnfirst;
        if (!dn->get_linkage()->is_null()) {
          dout(10) << "EMetaBlob.replay unlinking " << *dn << dendl;
+         if (dn->get_linkage()->is_primary() &&
+             dn->get_linkage()->get_inode() == renamed_diri)
+           olddir = dir;
          dir->unlink_inode(dn);
        }
        dn->set_version(p->dnv);
@@ -630,6 +643,19 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
     }
   }
 
+  if (renamed_dirino) {
+    if (olddir) {
+      assert(renamed_diri);
+      mds->mdcache->adjust_subtree_after_rename(renamed_diri, olddir, false);
+    } else {
+      if (!renamed_diri) {
+       renamed_diri = mds->mdcache->get_inode(renamed_dirino);
+       assert(renamed_diri);
+      }
+      // FIXME.
+    }
+  }
+
   // table client transactions
   for (list<pair<__u8,version_t> >::iterator p = table_tids.begin();
        p != table_tids.end();