]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: create snaprealm for stray dentries resulting from rename
authorSage Weil <sage@newdream.net>
Fri, 3 Oct 2008 20:34:31 +0000 (13:34 -0700)
committerSage Weil <sage@newdream.net>
Fri, 3 Oct 2008 21:00:32 +0000 (14:00 -0700)
This was done in the unlink path, but overlooked by rename(), resulting in
problems down the line when the stray nlink=0 item was purged.

src/mds/MDCache.cc
src/mds/Server.cc

index 5fd112744dc8613692ce241e8b63a3948d2ea17f..b35bcc161d5698588ddce7141ebf0da615ca3ad7 100644 (file)
@@ -4075,6 +4075,7 @@ void MDCache::_do_purge_inode(CInode *in, loff_t newsize, loff_t oldsize)
   // remove
   if (newsize < oldsize) {
     SnapRealm *realm = in->find_snaprealm();
+    assert(realm);
     dout(10) << "_do_purge_inode realm " << *realm << dendl;
     const SnapContext& snapc = realm->get_snap_context();
     dout(10) << "_do_purge_inode snapc " << snapc << " on " << *in << dendl;
index a44fb65dbd2ac95dee01bab0394ea799c041d200..e1e1e49567f3e3117fb72e99210505f90c889a55 100644 (file)
@@ -3738,7 +3738,15 @@ void Server::_rename_prepare(MDRequest *mdr,
   // target inode
   if (!linkmerge) {
     if (destdn->is_primary()) {
-      tji = metablob->add_primary_dentry(straydn, true, destdn->inode, tpi);
+      // project snaprealm, too
+      bufferlist snapbl;
+      if (!destdn->inode->snaprealm) {
+       destdn->inode->open_snaprealm(true);   // don't do a split
+       destdn->inode->snaprealm->project_past_parent(straydn->dir->inode->snaprealm, snapbl);
+       destdn->inode->close_snaprealm(true);  // or a matching join
+      } else
+       destdn->inode->snaprealm->project_past_parent(straydn->dir->inode->snaprealm, snapbl);
+      tji = metablob->add_primary_dentry(straydn, true, destdn->inode, tpi, 0, &snapbl);
     } else if (destdn->is_remote()) {
       metablob->add_dir_context(destdn->inode->get_parent_dir());
       mdcache->journal_cow_dentry(mdr, metablob, destdn->inode->parent);
@@ -3829,6 +3837,20 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
       dout(10) << "straydn is " << *straydn << dendl;
       destdn->dir->unlink_inode(destdn);
       straydn->dir->link_primary_inode(straydn, oldin);
+      
+      if (straydn->is_auth()) {
+       SnapRealm *oldparent = destdn->dir->inode->find_snaprealm();
+       bool isnew = false;
+       if (!straydn->inode->snaprealm) {
+         straydn->inode->open_snaprealm();
+         straydn->inode->snaprealm->seq = oldparent->get_newest_seq();
+         isnew = true;
+       }
+       straydn->inode->snaprealm->add_past_parent(oldparent);
+       if (isnew)
+         mdcache->do_realm_invalidate_and_update_notify(straydn->inode, CEPH_SNAP_OP_SPLIT);
+      }
+
     } else {
       destdn->dir->unlink_inode(destdn);
     }