]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: make sure snap inode's last match existing snapshots
authorYan, Zheng <zyan@redhat.com>
Fri, 10 Apr 2015 05:58:15 +0000 (13:58 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 21 Apr 2015 05:56:16 +0000 (13:56 +0800)
MDCache::pick_inode_snap() and snap caps flushing code require
this.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CInode.cc
src/mds/MDCache.cc

index 38ecb1615305f6fa7efcadb3d9229493346c1d51..b5507d3b923a831b90837ecd0d4756ebe7e24596 100644 (file)
@@ -304,10 +304,14 @@ void CInode::split_need_snapflush(CInode *cowin, CInode *in)
 {
   dout(10) << "split_need_snapflush [" << cowin->first << "," << cowin->last << "] for " << *cowin << dendl;
   for (compact_map<snapid_t, set<client_t> >::iterator p = client_need_snapflush.lower_bound(cowin->first);
-       p != client_need_snapflush.end() && p->first <= cowin->last;
-       ++p) {
-    assert(!p->second.empty());
-    cowin->auth_pin(this);
+       p != client_need_snapflush.end() && p->first < in->first; ) {
+    compact_map<snapid_t, set<client_t> >::iterator q = p;
+    ++p;
+    assert(!q->second.empty());
+    if (cowin->last >= q->first)
+      cowin->auth_pin(this);
+    else
+      client_need_snapflush.erase(q);
     in->auth_unpin(this);
   }
 }
index f9e5a48e85c33059a49252e802d1535f650bd455..041c691b3a3ad6cddadc72b75d4daa866119dde4 100644 (file)
@@ -1482,11 +1482,25 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
 {
   assert(last >= in->first);
 
-  CInode *oldin = new CInode(this, true, in->first, last);
+  SnapRealm *realm = in->find_snaprealm();
+  const set<snapid_t>& snaps = realm->get_snaps();
+
+  // make sure snap inode's last match existing snapshots.
+  // MDCache::pick_inode_snap() requires this.
+  snapid_t last_snap = last;
+  if (snaps.count(last) == 0) {
+    set<snapid_t>::const_iterator p = snaps.upper_bound(last);
+    if (p != snaps.begin()) {
+      --p;
+      if (*p >= in->first)
+       last_snap = *p;
+    }
+  }
+
+  CInode *oldin = new CInode(this, true, in->first, last_snap);
   oldin->inode = *in->get_previous_projected_inode();
   oldin->symlink = in->symlink;
   oldin->xattrs = *in->get_previous_projected_xattrs();
-
   oldin->inode.trim_client_ranges(last);
 
   if (in->first < in->oldest_snap)
@@ -1496,9 +1510,6 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
 
   dout(10) << "cow_inode " << *in << " to " << *oldin << dendl;
   add_inode(oldin);
-  
-  SnapRealm *realm = in->find_snaprealm();
-  const set<snapid_t>& snaps = realm->get_snaps();
 
   if (in->last != CEPH_NOSNAP) {
     CInode *head_in = get_inode(in->ino());