]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: invalidate child snaprealms; adjust snaprealm parents on split
authorSage Weil <sage@newdream.net>
Mon, 4 Aug 2008 17:37:23 +0000 (10:37 -0700)
committerSage Weil <sage@newdream.net>
Mon, 4 Aug 2008 17:37:23 +0000 (10:37 -0700)
src/client/Client.cc
src/client/Client.h
src/messages/MClientSnap.h

index 9677f018a928834d8d29a44b35431aa68fe34bd4..d000b7aa8644b18bce6256089ce3b5d7ef45bb43 100644 (file)
@@ -1631,6 +1631,40 @@ void SnapRealm::build_snaps()
   cout << *this << " build_snaps got " << cached_snaps << std::endl;
 }
 
+void Client::invalidate_snaprealm_and_children(SnapRealm *realm)
+{
+  list<SnapRealm*> q;
+  q.push_back(realm);
+
+  while (!q.empty()) {
+    realm = q.front();
+    q.pop_front();
+
+    dout(10) << "invalidate_snaprealm_and_children " << *realm << dendl;
+    realm->invalidate_cache();
+
+    for (set<SnapRealm*>::iterator p = realm->pchildren.begin();
+        p != realm->pchildren.end(); 
+        p++)
+      q.push_back(*p);
+  }
+}
+
+void Client::adjust_realm_parent(SnapRealm *realm, inodeno_t parent)
+{
+  if (realm->parent != parent) {
+    dout(10) << "adjust_realm_parent " << *realm
+            << " " << realm->parent << " -> " << parent << dendl;
+    realm->parent = parent;
+    if (realm->pparent) {
+      realm->pparent->pchildren.erase(realm);
+      put_snap_realm(realm->pparent);
+    }
+    realm->pparent = get_snap_realm(parent);
+    realm->pparent->pchildren.insert(realm);
+  }
+}
+
 inodeno_t Client::update_snap_trace(bufferlist& bl, bool flush)
 {
   inodeno_t first_realm = 0;
@@ -1673,32 +1707,27 @@ inodeno_t Client::update_snap_trace(bufferlist& bl, bool flush)
            q.push_back(*p);
        }
       }
+    }
 
-      
+    // _always_ verify parent
+    adjust_realm_parent(realm, info.parent);
+
+    if (info.seq > realm->seq) {
       // update
       realm->created = info.created;
-      if (realm->parent != info.parent) {
-       realm->parent = info.parent;
-       if (realm->pparent) {
-         realm->pparent->pchildren.erase(realm);
-         put_snap_realm(realm->pparent);
-       }
-       realm->pparent = get_snap_realm(info.parent);
-       realm->pparent->pchildren.insert(realm);
-      }
       realm->parent = info.parent;
       realm->parent_since = info.parent_since;
       realm->prior_parent_snaps = info.prior_parent_snaps;
       realm->my_snaps = info.my_snaps;
       realm->seq = info.seq;
 
-      realm->invalidate_cache();
+      invalidate_snaprealm_and_children(realm);
       dout(15) << "  snaps " << realm->get_snaps() << dendl;
     } else {
       dout(10) << "update_snap_trace " << *realm << " seq " << info.seq
               << " <= " << realm->seq << ", SKIPPING" << dendl;
     }
-    
+        
     put_snap_realm(realm);
   }
 
@@ -1753,6 +1782,18 @@ void Client::handle_snap(MClientSnap *m)
        }
       }
     }
+
+    // move child snaprealms, too
+    for (list<inodeno_t>::iterator p = m->split_realms.begin();
+        p != m->split_realms.end();
+        p++) {
+      dout(10) << "adjusting snaprealm " << *p << " parent" << dendl;
+      SnapRealm *child = get_snap_realm_maybe(*p);
+      if (!child)
+       continue;
+      adjust_realm_parent(child, realm->ino);
+      put_snap_realm(child);
+    }
   }
 
   update_snap_trace(m->bl, m->op != CEPH_SNAP_OP_DESTROY);
index 971e5d6504754fa070f41c047a41bb401b6a8a90..4c7b0407b898a749bd6befc681c1f97d64eedbb2 100644 (file)
@@ -626,14 +626,23 @@ protected:
     realm->nref++;
     return realm;
   }
+  SnapRealm *get_snap_realm_maybe(inodeno_t r) {
+    if (snap_realms.count(r) == 0)
+      return NULL;
+    SnapRealm *realm = snap_realms[r];
+    realm->nref++;
+    return realm;
+  }
   void put_snap_realm(SnapRealm *realm) {
     if (realm->nref-- == 0) {
       snap_realms.erase(realm->ino);
       delete realm;
     }
   }
+  void adjust_realm_parent(SnapRealm *realm, inodeno_t parent);
   inodeno_t update_snap_trace(bufferlist& bl, bool must_flush=true);
   inodeno_t _update_snap_trace(vector<SnapRealmInfo>& trace);
+  void invalidate_snaprealm_and_children(SnapRealm *realm);
 
   Inode *open_snapdir(Inode *diri);
 
index 6f5181f2fa1317ef93ae6ef1a69b59dfee8fc757..0b9bab1154b153b4bf94c2dc31faad3d8daf9c7f 100644 (file)
@@ -24,6 +24,7 @@ struct MClientSnap : public Message {
   // (for split only)
   inodeno_t split;
   list<inodeno_t> split_inos;
+  list<inodeno_t> split_realms;
   
   MClientSnap(int o=0) : 
     Message(CEPH_MSG_CLIENT_SNAP),
@@ -42,6 +43,7 @@ struct MClientSnap : public Message {
     ::encode(bl, payload);
     ::encode(split, payload);
     ::encode(split_inos, payload);
+    ::encode(split_realms, payload);
   }
   void decode_payload() {
     bufferlist::iterator p = payload.begin();
@@ -49,6 +51,7 @@ struct MClientSnap : public Message {
     ::decode(bl, p);
     ::decode(split, p);
     ::decode(split_inos, p);
+    ::decode(split_realms, p);
     assert(p.end());
   }