From 2b8061b64b45047434aa967cb0026e6953785c82 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 4 Aug 2008 10:37:23 -0700 Subject: [PATCH] client: invalidate child snaprealms; adjust snaprealm parents on split --- src/client/Client.cc | 65 +++++++++++++++++++++++++++++++------- src/client/Client.h | 9 ++++++ src/messages/MClientSnap.h | 3 ++ 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 9677f018a9288..d000b7aa8644b 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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 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::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::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); diff --git a/src/client/Client.h b/src/client/Client.h index 971e5d6504754..4c7b0407b898a 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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& trace); + void invalidate_snaprealm_and_children(SnapRealm *realm); Inode *open_snapdir(Inode *diri); diff --git a/src/messages/MClientSnap.h b/src/messages/MClientSnap.h index 6f5181f2fa131..0b9bab1154b15 100644 --- a/src/messages/MClientSnap.h +++ b/src/messages/MClientSnap.h @@ -24,6 +24,7 @@ struct MClientSnap : public Message { // (for split only) inodeno_t split; list split_inos; + list 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()); } -- 2.39.5