From: Sage Weil Date: Thu, 7 Aug 2008 14:42:07 +0000 (-0700) Subject: mds: adjust snaprealm parents in link helpers X-Git-Tag: v0.4~311 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=56e5431d31a4ea7e1e776142b420f3933c8c919b;p=ceph.git mds: adjust snaprealm parents in link helpers --- diff --git a/src/TODO b/src/TODO index 85ddb4eb2cc7e..2b8b99ebd0d91 100644 --- a/src/TODO +++ b/src/TODO @@ -23,17 +23,6 @@ big items snaps on mds - cap release probably needs ack by mds. or, mds needs to possibly initiate recovery on import? no, release should pbly just be acked by mds... like it was way back when... bah! -- client snap caps - - NO CAP STATE FOR SNAPPED INODES. - - mds grants open access (yes/no), but there is no state, since there is no concurrency. - (mds doesn't grant access until filelock it is readable, i.e., snapped data has flushed) - - client _should_ only send FLUSHSNAP _after_ data is flushed. this will require much more sophisticated barriers in the client's cache. - - reconnect should map caps into snaprealms, and include snaprealm state, such that those can be brought in sync w/ the mds. - - reconnect does _not_ need any per-cap snap-related info. - -- mds open within snapshot -- client snap read - - mds server ops - link rollback - rename rollback @@ -43,14 +32,7 @@ snaps on mds - build snaprealm for any hardlinked file - include snaps for all (primary+remote) parents -- does snap_follows in MClientFileCaps properly handle snap deletion? - snaps on osd -- clean up snap context packaging.. - - seq, not just snap list - - keep newest object around on osd? - - hmm, can we eliminate the snap list for reads? - - fix cloning on unlinked file (where snaps=[], but head may have follows_snap attr) - figure out how to fix up rados logging - snap collections - garbage collection diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index f665a9cd87f60..dbba58f2dfc03 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -405,6 +405,10 @@ void CDir::link_inode_work( CDentry *dn, CInode *in) if (in->inode.anchored + in->nested_anchors) dn->adjust_nested_anchors(in->nested_anchors + in->inode.anchored); + + // verify open snaprealm parent + if (in->snaprealm) + in->snaprealm->adjust_parent(); } void CDir::unlink_inode( CDentry *dn ) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 9d2d9caaaf31a..2bb71a4976c46 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -825,12 +825,6 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir) { dout(10) << "adjust_subtree_after_rename " << *diri << " from " << *olddir << dendl; - // fix up snaprealms - assert(diri->snaprealm); - SnapRealm *newparent = diri->parent->dir->inode->find_snaprealm(); - if (newparent != diri->snaprealm->parent) - diri->snaprealm->change_open_parent_to(newparent); - //show_subtrees(); // adjust subtree @@ -959,6 +953,7 @@ int MDCache::num_subtrees_fullnonauth() // =================================== // journal and snap/cow helpers + /* * find first inode in cache that follows given snapid. otherwise, return current. */ @@ -1067,8 +1062,10 @@ void MDCache::journal_cow_dentry(Mutation *mut, EMetaBlob *metablob, CDentry *dn follows = in->find_snaprealm()->get_newest_snap(); // already cloned? - if (follows < in->first) + if (follows < in->first) { + dout(10) << "journal_cow_dentry follows " << follows << " < first on " << *in << dendl; return; + } in->cow_old_inode(follows, in->get_previous_projected_inode()); @@ -1088,8 +1085,10 @@ void MDCache::journal_cow_dentry(Mutation *mut, EMetaBlob *metablob, CDentry *dn follows = dn->dir->inode->find_snaprealm()->get_newest_snap(); // already cloned? - if (follows < dn->first) + if (follows < dn->first) { + dout(10) << "journal_cow_dentry follows " << follows << " < first on " << *dn << dendl; return; + } // update dn.first before adding old dentry to cdir's map snapid_t oldfirst = dn->first; diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index da146020fe8fe..d37da220b91e8 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -508,7 +508,7 @@ public: void request_drop_locks(MDRequest *r); void request_cleanup(MDRequest *r); - // journal helpers + // journal/snap helpers CInode *pick_inode_snap(CInode *in, snapid_t follows); CInode *cow_inode(CInode *in, snapid_t last); void journal_cow_dentry(Mutation *mut, EMetaBlob *metablob, CDentry *dn, snapid_t follows=CEPH_NOSNAP); diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 6cf82b7227068..e2640c28880ba 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -372,7 +372,6 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg) assert(dn->last == p->dnlast); } - bool do_snap_split = false; CInode *in = mds->mdcache->get_inode(p->inode.ino, p->dnlast); if (!in) { in = new CInode(mds->mdcache, true, p->dnfirst, p->dnlast); @@ -380,9 +379,12 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg) in->xattrs = p->xattrs; if (in->inode.is_dir()) { in->dirfragtree = p->dirfragtree; - in->decode_snap_blob(p->snapbl); - if (in->snaprealm) - do_snap_split = true; + /* + * we can do this before linking hte inode bc the split_at would + * be a no-op.. we have no children (namely open snaprealms) to + * divy up + */ + in->decode_snap_blob(p->snapbl); } if (in->inode.is_symlink()) in->symlink = p->symlink; mds->mdcache->add_inode(in); @@ -409,10 +411,7 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg) in->xattrs = p->xattrs; if (in->inode.is_dir()) { in->dirfragtree = p->dirfragtree; - bool had = in->snaprealm ? true:false; in->decode_snap_blob(p->snapbl); - if (!had && in->snaprealm) - do_snap_split = true; } if (in->inode.is_symlink()) in->symlink = p->symlink; if (p->dirty) in->_mark_dirty(logseg); @@ -425,15 +424,6 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg) dout(10) << "EMetaBlob.replay for [" << p->dnfirst << "," << p->dnlast << "] had " << *in << dendl; } in->first = p->dnfirst; - - // verify open snaprealm parent - if (in->snaprealm) { - SnapRealm *actual = in->get_parent_dn()->get_dir()->inode->find_snaprealm(); - if (actual != in->snaprealm->parent) { - dout(10) << "EMetaBlob.replay fixing snaprealm open parent" << dendl; - in->snaprealm->change_open_parent_to(actual); - } - } } } diff --git a/src/mds/snap.cc b/src/mds/snap.cc index f2220c1dfc2aa..ff9a1006966d7 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -188,7 +188,7 @@ void SnapRealm::check_cache() build_snap_set(cached_snaps, cached_seq, cached_last_created, cached_last_destroyed, 0, CEPH_NOSNAP); - dout(10) << "check_cache " << cached_snaps + dout(10) << "check_cache rebuilt " << cached_snaps << " seq " << seq << " cached_seq " << cached_seq << " cached_last_created " << cached_last_created @@ -334,6 +334,20 @@ snapid_t SnapRealm::resolve_snapname(const string& n, inodeno_t atino, snapid_t } +void SnapRealm::adjust_parent() +{ + SnapRealm *newparent = inode->get_parent_dn()->get_dir()->get_inode()->find_snaprealm(); + if (newparent != parent) { + dout(10) << "adjust_parent " << parent << " -> " << newparent << dendl; + if (parent) + parent->open_children.erase(this); + parent = newparent; + if (parent) + parent->open_children.insert(this); + + invalidate_cached_snaps(); + } +} void SnapRealm::split_at(SnapRealm *child) { @@ -463,4 +477,6 @@ void SnapRealm::add_past_parent(SnapRealm *oldparent) } current_parent_since = MAX(oldlast, newlast) + 1; dout(10) << "add_past_parent current_parent_since " << current_parent_since << dendl; + + invalidate_cached_snaps(); } diff --git a/src/mds/snap.h b/src/mds/snap.h index b4c1a61cbd316..b37349b92f466 100644 --- a/src/mds/snap.h +++ b/src/mds/snap.h @@ -194,13 +194,8 @@ struct SnapRealm { return cached_seq; } - void change_open_parent_to(SnapRealm *newp) { - if (parent) - parent->open_children.erase(this); - parent = newp; - if (parent) - parent->open_children.insert(this); - } + void adjust_parent(); + void split_at(SnapRealm *child); void join(SnapRealm *child);