From: Sage Weil Date: Tue, 5 Aug 2008 21:09:18 +0000 (-0700) Subject: mds: split snaprealm on unlink; clean up rename realm updates X-Git-Tag: v0.4~322 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f1537f1ebdf85e647077fc6bfa6dd56118b21c93;p=ceph.git mds: split snaprealm on unlink; clean up rename realm updates --- diff --git a/src/TODO b/src/TODO index 8c3ce9506607..42c572ed9cdd 100644 --- a/src/TODO +++ b/src/TODO @@ -34,15 +34,6 @@ snaps on mds - mds open within snapshot - client snap read - -- test rejoin -- client reconnect - - esp cap claim - - - -/- call open_parents() where needed. - - what about during recovery? e.g. client reconnected caps... - mds server ops - link rollback - rename rollback diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 10b2ee157a49..2887bfd3d0d7 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -1206,7 +1206,7 @@ void CInode::purge_stale_snap_data(const set& snaps) } */ -void CInode::open_snaprealm() +void CInode::open_snaprealm(bool nosplit) { if (!snaprealm) { SnapRealm *parent = find_snaprealm(); @@ -1217,18 +1217,22 @@ void CInode::open_snaprealm() << " siblings are " << parent->open_children << dendl; snaprealm->parent = parent; - parent->split_at(snaprealm); + if (!nosplit) + parent->split_at(snaprealm); parent->open_children.insert(snaprealm); } } } -void CInode::close_snaprealm() +void CInode::close_snaprealm(bool nojoin) { if (snaprealm) { dout(15) << "close_snaprealm " << *snaprealm << dendl; snaprealm->close_parents(); - if (snaprealm->parent) + if (snaprealm->parent) { snaprealm->parent->open_children.erase(snaprealm); + //if (!nojoin) + //snaprealm->parent->join(snaprealm); + } delete snaprealm; snaprealm = 0; } diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 0ec80acb7fcd..6b189d4655e8 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -454,8 +454,8 @@ public: // -- snap -- - void open_snaprealm(); - void close_snaprealm(); + void open_snaprealm(bool no_split=false); + void close_snaprealm(bool no_join=false); SnapRealm *find_snaprealm(); void encode_snap_blob(bufferlist &bl); void decode_snap_blob(bufferlist &bl); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 2e4134410365..c2844bfe6c33 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2491,7 +2491,7 @@ void Server::_link_remote_finish(MDRequest *mdr, bool inc, for (map::iterator it = dn->replicas_begin(); it != dn->replicas_end(); it++) { - dout(7) << "_unlink_remote_finish sending MDentryUnlink to mds" << it->first << dendl; + dout(7) << "_link_remote_finish sending MDentryUnlink to mds" << it->first << dendl; MDentryUnlink *unlink = new MDentryUnlink(dn->dir->dirfrag(), dn->name); mds->send_message_mds(unlink, it->first); } @@ -2961,11 +2961,20 @@ void Server::_unlink_local(MDRequest *mdr, CDentry *dn, CDentry *straydn) le->metablob.add_null_dentry(dn, true); if (dn->is_primary()) { + // project snaprealm, too + bufferlist snapbl; + if (!dn->inode->snaprealm) { + dn->inode->open_snaprealm(true); // don't do a split + dn->inode->snaprealm->project_past_parent(straydn->dir->inode->snaprealm, snapbl); + dn->inode->close_snaprealm(true); // or a matching join + } else + dn->inode->snaprealm->project_past_parent(straydn->dir->inode->snaprealm, snapbl); + // primary link. add stray dentry. assert(straydn); mdcache->predirty_journal_parents(mdr, &le->metablob, dn->inode, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, -1); mdcache->predirty_journal_parents(mdr, &le->metablob, dn->inode, straydn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - le->metablob.add_primary_dentry(straydn, true, dn->inode, pi); + le->metablob.add_primary_dentry(straydn, true, dn->inode, pi, 0, &snapbl); } else { // remote link. update remote inode. mdcache->predirty_journal_parents(mdr, &le->metablob, dn->inode, dn->dir, PREDIRTY_DIR, -1); @@ -2994,6 +3003,12 @@ void Server::_unlink_local_finish(MDRequest *mdr, if (straydn) { dout(20) << " straydn is " << *straydn << dendl; straydn->dir->link_primary_inode(straydn, in); + + if (!straydn->inode->snaprealm) { + straydn->inode->open_snaprealm(); + mdcache->do_realm_split_notify(straydn->inode); + } + straydn->inode->snaprealm->add_past_parent(dn->dir->inode->find_snaprealm()); } dn->mark_dirty(dnpv, mdr->ls); @@ -3700,28 +3715,8 @@ void Server::_rename_prepare(MDRequest *mdr, } else if (srcdn->is_primary()) { // project snap parent update? bufferlist snapbl; - if (!srcdn->inode->snaprealm) - srcdn->inode->open_snaprealm(); - if (destdn->is_auth()) { - SnapRealm *realm = srcdn->inode->snaprealm; - snapid_t oldlast = realm->parent->get_newest_snap(); - snapid_t newlast = destdn->dir->inode->find_snaprealm()->get_last_created(); - snapid_t first = realm->current_parent_since; - - snapid_t old_since = realm->current_parent_since; - realm->current_parent_since = MAX(oldlast, newlast) + 1; - if (oldlast >= first) { - realm->past_parents[oldlast].ino = realm->parent->inode->ino(); - realm->past_parents[oldlast].first = first; - dout(10) << " projecting new past_parent [" << first << "," << oldlast << "] = " - << realm->parent->inode->ino() << " on " << *realm << dendl; - } - dout(10) << " projected current_parent_since " << realm->current_parent_since << " on" << *realm << dendl; - ::encode(*realm, snapbl); - if (oldlast >= first) - realm->past_parents.erase(oldlast); - realm->current_parent_since = old_since; - } + if (destdn->is_auth() && srcdn->inode->snaprealm) + srcdn->inode->snaprealm->project_past_parent(destdn->dir->inode->find_snaprealm(), snapbl); if (!destdn->is_null()) mdcache->journal_cow_dentry(mdr, metablob, destdn); @@ -3833,23 +3828,8 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen destdn->inode->pop_and_dirty_projected_inode(mdr->ls); // snap parent update? - if (destdn->inode->is_dir()) { - SnapRealm *realm = destdn->inode->snaprealm; - snapid_t oldlast = srcdn->dir->inode->find_snaprealm()->get_newest_snap(); - snapid_t newlast = destdn->dir->inode->find_snaprealm()->get_last_created(); - snapid_t first = realm->current_parent_since; - - if (oldlast >= realm->current_parent_since) { - SnapRealm *oldparent = srcdn->dir->inode->find_snaprealm(); - realm->past_parents[oldlast].ino = oldparent->inode->ino(); - realm->past_parents[oldlast].first = realm->current_parent_since; - realm->add_open_past_parent(oldparent); - dout(10) << " adding past_parent [" << realm->past_parents[oldlast].first << "," << oldlast << "] = " - << realm->past_parents[oldlast].ino << " on " << *realm << dendl; - } - realm->current_parent_since = MAX(oldlast, newlast) + 1; - dout(10) << " set current_parent_since " << realm->current_parent_since << " on " << *realm << dendl; - } + if (destdn->is_auth() && destdn->inode->snaprealm) + destdn->inode->snaprealm->add_past_parent(srcdn->dir->inode->find_snaprealm()); } // src diff --git a/src/mds/snap.cc b/src/mds/snap.cc index 83f0301138e1..0541a179e70a 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -385,7 +385,6 @@ void SnapRealm::split_at(SnapRealm *child) - void SnapRealm::build_snap_trace(bufferlist& snapbl) { SnapRealmInfo info; @@ -421,3 +420,45 @@ void SnapRealm::build_snap_trace(bufferlist& snapbl) if (parent) parent->build_snap_trace(snapbl); } + + + + +void SnapRealm::project_past_parent(SnapRealm *newparent, bufferlist& snapbl) +{ + snapid_t newlast = newparent->get_last_created(); + snapid_t oldlast = parent->get_newest_snap(); + snapid_t first = current_parent_since; + + if (oldlast >= current_parent_since) { + past_parents[oldlast].ino = parent->inode->ino(); + past_parents[oldlast].first = first; + dout(10) << "project_past_parent new past_parent [" << first << "," << oldlast << "] = " + << parent->inode->ino() << dendl; + } + current_parent_since = MAX(oldlast, newlast) + 1; + dout(10) << "project_past_parent current_parent_since " << current_parent_since << dendl; + + ::encode(*this, snapbl); + + if (oldlast >= first) + past_parents.erase(oldlast); + current_parent_since = first; +} + +void SnapRealm::add_past_parent(SnapRealm *oldparent) +{ + snapid_t newlast = parent->get_last_created(); + snapid_t oldlast = oldparent->get_newest_snap(); + snapid_t first = current_parent_since; + + if (oldlast >= current_parent_since) { + past_parents[oldlast].ino = oldparent->inode->ino(); + past_parents[oldlast].first = first; + add_open_past_parent(oldparent); + dout(10) << "add_past_parent [" << first << "," << oldlast << "] = " + << oldparent->inode->ino() << dendl; + } + current_parent_since = MAX(oldlast, newlast) + 1; + dout(10) << "add_past_parent current_parent_since " << current_parent_since << dendl; +} diff --git a/src/mds/snap.h b/src/mds/snap.h index 3f5d63c23357..077e9c70e508 100644 --- a/src/mds/snap.h +++ b/src/mds/snap.h @@ -155,6 +155,9 @@ struct SnapRealm { void add_open_past_parent(SnapRealm *parent); void close_parents(); + void project_past_parent(SnapRealm *newparent, bufferlist& snapbl); + void add_past_parent(SnapRealm *oldparent); + void build_snap_set(set& s, snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed, snapid_t first, snapid_t last); @@ -199,6 +202,7 @@ struct SnapRealm { parent->open_children.insert(this); } void split_at(SnapRealm *child); + void join(SnapRealm *child); void add_cap(int client, Capability *cap) { client_caps[client].push_back(&cap->snaprealm_caps_item);