From 156d276fc482519dd0b245bfa2ab13b5a6df7eb1 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 11 Jul 2008 09:52:32 -0700 Subject: [PATCH] mds: snapid_t, multiversion inodes, fixed up perdirty_nested --- src/include/object.h | 2 +- src/include/types.h | 19 +++++++++++++++- src/mds/CDir.cc | 3 ++- src/mds/CInode.cc | 7 ++++-- src/mds/CInode.h | 8 ++++--- src/mds/Locker.cc | 10 +++++++-- src/mds/MDCache.cc | 40 +++++++++++++++++++++++++++------- src/mds/MDCache.h | 4 ++-- src/mds/Server.cc | 20 +++++++++-------- src/mds/mdstypes.h | 2 +- src/mds/snap.cc | 2 +- src/messages/MClientFileCaps.h | 4 ++-- src/messages/MClientReply.h | 4 ++-- 13 files changed, 90 insertions(+), 35 deletions(-) diff --git a/src/include/object.h b/src/include/object.h index 6475c77ff17dc..01528ad698794 100644 --- a/src/include/object.h +++ b/src/include/object.h @@ -38,7 +38,7 @@ struct object_t { struct { uint64_t ino; // "file" identifier uint32_t bno; // "block" in that "file" - objectrev_t snap; // revision. normally ctime (as epoch). + uint64_t snap; // snap revision. } __attribute__ ((packed)); }; diff --git a/src/include/types.h b/src/include/types.h index 7827bc5713b3a..bdf65acf19819 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -140,7 +140,24 @@ typedef __u64 coll_t; // snaps -typedef __u64 snapid_t; +struct snapid_t { + __u64 val; + snapid_t(__u64 v=0) : val(v) {} + snapid_t operator+=(snapid_t o) { val += o.val; return *this; } + snapid_t operator++() { ++val; return *this; } + operator __u64() const { return val; } +}; + +inline void encode(snapid_t i, bufferlist &bl) { encode(i.val, bl); } +inline void decode(snapid_t &i, bufferlist::iterator &p) { decode(i.val, p); } + +inline ostream& operator<<(ostream& out, snapid_t s) { + if (s == CEPH_NOSNAP) + return out << "head"; + else + return out << s.val; +} + #define MAXSNAP CEPH_MAXSNAP #define NOSNAP CEPH_NOSNAP diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index f6c6a61b4c7a8..06d071ddfe21f 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1081,7 +1081,8 @@ void CDir::_fetched(bufferlist &bl) // inode in = new CInode(cache); in->inode = inode; - in->snapid = first; + in->first = first; + in->last = last; // symlink? if (in->is_symlink()) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 296a4c9c694c5..08433b3307416 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -51,8 +51,11 @@ ostream& operator<<(ostream& out, CInode& in) filepath path; in.make_path(path); out << "[inode " << in.inode.ino << " " << path << (in.is_dir() ? "/":""); - if (in.snapid) - out << " SNAP=" << in.snapid; + if (in.is_multiversion()) + out << " [" << in.first << ",...]"; + else + out << " [" << in.first << "," << in.last << "]"; + if (in.is_auth()) { out << " auth"; if (in.is_replicated()) diff --git a/src/mds/CInode.h b/src/mds/CInode.h index fb8bb9595cf5d..a08d96701f0ff 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -137,9 +137,11 @@ class CInode : public MDSCacheObject { SnapRealm *snaprealm; SnapRealm *containing_realm; - snapid_t snapid; // 0 = multiversion OR head + snapid_t first, last; // last=0 => multiversion or head. map old_inodes; // key = last, value.first = first + bool is_multiversion() { return snaprealm || inode.is_dir(); } + loff_t last_journaled; // log offset for the last time i was journaled loff_t last_open_journaled; // log offset for the last journaled EOpen @@ -263,7 +265,7 @@ private: CInode(MDCache *c, bool auth=true) : mdcache(c), snaprealm(0), containing_realm(0), - snapid(0), + first(1), last(0), last_journaled(0), last_open_journaled(0), //hack_accessed(true), stickydir_ref(0), @@ -316,7 +318,7 @@ private: inodeno_t ino() const { return inode.ino; } - vinodeno_t vino() const { return vinodeno_t(inode.ino, snapid); } + vinodeno_t vino() const { return vinodeno_t(inode.ino, last); } inode_t& get_inode() { return inode; } CDentry* get_parent_dn() { return parent; } CDentry* get_projected_parent_dn() { return projected_parent ? projected_parent:parent; } diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index b49fe010537f3..be7684a80dc2f 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -1450,12 +1450,18 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, assert(parent->is_auth()); blob->add_dir_context(parent); blob->add_dir(parent, true); + SnapRealm *realm = 0; for (list::iterator p = lsi.begin(); p != lsi.end(); p++) { CInode *cur = *p; - inode_t *pi = cur->get_projected_inode(); - blob->add_primary_dentry(cur->get_projected_parent_dn(), true, 0, pi); + if (!realm) + realm = cur->find_snaprealm(); + else if (cur->snaprealm) + realm = cur->snaprealm; + mds->mdcache->journal_dirty_inode(blob, cur, realm->get_latest_snap()); + //inode_t *pi = cur->get_projected_inode(); + //blob->add_primary_dentry(cur->get_projected_parent_dn(), true, 0, pi); } } diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index e169b1f665212..dc8f0fea36595 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -959,11 +959,16 @@ CInode *MDCache::pick_inode_snap(CInode *in, snapid_t follows) return in; } -CInode *MDCache::cow_inode(CInode *in, snapid_t tosnap) +CInode *MDCache::cow_inode(CInode *in, snapid_t first, snapid_t last) { CInode *oldin = new CInode(this); oldin->inode = *in->get_previous_projected_inode(); - oldin->snapid = tosnap; + oldin->symlink = in->symlink; + oldin->xattrs = in->xattrs; + + oldin->first = first; + oldin->last = last; + dout(10) << " oldin " << *oldin << dendl; add_inode(oldin); @@ -976,27 +981,46 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t tosnap) void MDCache::journal_dirty_inode(EMetaBlob *metablob, CInode *in, snapid_t follows) { dout(10) << "journal_dirty_inode follows " << follows << " on " << *in << dendl; - CDentry *dn = in->parent; + CDentry *dn = in->get_projected_parent_dn(); dout(10) << " orig dn " << *dn << dendl; - if (in->snaprealm || in->inode.is_dir()) { + if (follows == CEPH_NOSNAP) + follows = in->find_snaprealm()->get_latest_snap(); + + if (in->is_multiversion()) { // multiversion inode. - assert(0); + if (follows < in->first) { + metablob->add_primary_dentry(dn, true, in, in->get_projected_inode()); + } else { + old_inode_t &old = in->old_inodes[follows]; + old.first = in->first; + if (in->is_projected()) + old.inode = *in->get_previous_projected_inode(); // mkdir/mknod/symlink don't bother to project new inodes + else + old.inode = in->inode; + old.xattrs = in->xattrs; + + in->first = follows+1; + metablob->add_primary_dentry(dn, true, in, in->get_projected_inode()); + + dout(10) << " duped to old_inode [" << old.first << "," << follows << "] " + << *in << dendl; + } } else { // is dn within current snap? if (follows < dn->first) { - metablob->add_primary_dentry(dn, true, 0, in->get_projected_inode()); + metablob->add_primary_dentry(dn, true, in, in->get_projected_inode()); } else { snapid_t oldfirst = dn->first; dn->first = follows+1; dout(10) << " dn " << *dn << dendl; - CInode *oldin = cow_inode(in, follows); + CInode *oldin = cow_inode(in, in->first, follows); CDentry *olddn = dn->dir->add_primary_dentry(dn->name, oldin, oldfirst, follows); dout(10) << " olddn " << *olddn << dendl; metablob->add_primary_dentry(olddn, true); - metablob->add_primary_dentry(dn, true, 0, in->get_projected_inode()); + metablob->add_primary_dentry(dn, true, in, in->get_projected_inode()); } } } diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 59a0f5b686550..37b96f3481b00 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -466,8 +466,8 @@ public: // journal helpers CInode *pick_inode_snap(CInode *in, snapid_t follows); - CInode *cow_inode(CInode *in, snapid_t tosnap); - void journal_dirty_inode(EMetaBlob *metablob, CInode *in, snapid_t follows); + CInode *cow_inode(CInode *in, snapid_t first, snapid_t last); + void journal_dirty_inode(EMetaBlob *metablob, CInode *in, snapid_t follows=CEPH_NOSNAP); // slaves void add_uncommitted_master(metareqid_t reqid, LogSegment *ls, set &slaves) { diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 374d244eef7aa..67f51aafc5223 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1628,7 +1628,7 @@ void Server::handle_client_utime(MDRequest *mdr) EUpdate *le = new EUpdate(mdlog, "utime"); le->metablob.add_client_req(req->get_reqid()); mds->locker->predirty_nested(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false); - le->metablob.add_primary_dentry(cur->parent, true, 0, pi); + mdcache->journal_dirty_inode(&le->metablob, cur); mdlog->submit_entry(le, new C_MDS_inode_update_finish(mds, mdr, cur)); } @@ -1669,7 +1669,7 @@ void Server::handle_client_chmod(MDRequest *mdr) EUpdate *le = new EUpdate(mdlog, "chmod"); le->metablob.add_client_req(req->get_reqid()); mds->locker->predirty_nested(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false); - le->metablob.add_primary_dentry(cur->parent, true, 0, pi); + mdcache->journal_dirty_inode(&le->metablob, cur); mdlog->submit_entry(le, new C_MDS_inode_update_finish(mds, mdr, cur)); } @@ -1710,7 +1710,7 @@ void Server::handle_client_chown(MDRequest *mdr) EUpdate *le = new EUpdate(mdlog, "chown"); le->metablob.add_client_req(req->get_reqid()); mds->locker->predirty_nested(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false); - le->metablob.add_primary_dentry(cur->parent, true, 0, pi); + mdcache->journal_dirty_inode(&le->metablob, cur); mdlog->submit_entry(le, new C_MDS_inode_update_finish(mds, mdr, cur)); } @@ -1769,7 +1769,7 @@ void Server::handle_client_setxattr(MDRequest *mdr) EUpdate *le = new EUpdate(mdlog, "setxattr"); le->metablob.add_client_req(req->get_reqid()); mds->locker->predirty_nested(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false); - le->metablob.add_primary_dentry(cur->parent, true, 0, pi); + mdcache->journal_dirty_inode(&le->metablob, cur); mdlog->submit_entry(le, new C_MDS_inode_update_finish(mds, mdr, cur)); } @@ -1813,7 +1813,7 @@ void Server::handle_client_removexattr(MDRequest *mdr) EUpdate *le = new EUpdate(mdlog, "removexattr"); le->metablob.add_client_req(req->get_reqid()); mds->locker->predirty_nested(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false); - le->metablob.add_primary_dentry(cur->parent, true, 0, pi); + mdcache->journal_dirty_inode(&le->metablob, cur); mdlog->submit_entry(le, new C_MDS_inode_update_finish(mds, mdr, cur)); } @@ -2007,6 +2007,8 @@ void Server::handle_client_mknod(MDRequest *mdr) newi->inode.mode |= S_IFREG; newi->inode.version = dn->pre_dirty() - 1; newi->inode.dirstat.rfiles = 1; + + newi->projected_parent = dn; dout(10) << "mknod mode " << newi->inode.mode << " rdev " << newi->inode.rdev << dendl; @@ -2017,8 +2019,7 @@ void Server::handle_client_mknod(MDRequest *mdr) le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version()); mds->locker->predirty_nested(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - - le->metablob.add_primary_dentry(dn, true, newi, &newi->inode); + mdcache->journal_dirty_inode(&le->metablob, newi, dn->dir->inode->find_snaprealm()->get_latest_snap()); // log + wait mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi)); @@ -2062,7 +2063,8 @@ void Server::handle_client_mkdir(MDRequest *mdr) le->metablob.add_client_req(req->get_reqid()); le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version()); mds->locker->predirty_nested(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - le->metablob.add_primary_dentry(dn, true, newi, &newi->inode); + //le->metablob.add_primary_dentry(dn, true, newi, &newi->inode); + mdcache->journal_dirty_inode(&le->metablob, newi, dn->dir->inode->find_snaprealm()->get_latest_snap()); le->metablob.add_dir(newdir, true, true); // dirty AND complete // log + wait @@ -2100,7 +2102,7 @@ void Server::handle_client_symlink(MDRequest *mdr) le->metablob.add_client_req(req->get_reqid()); le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version()); mds->locker->predirty_nested(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - le->metablob.add_primary_dentry(dn, true, newi, &newi->inode); + mdcache->journal_dirty_inode(&le->metablob, newi, dn->dir->inode->find_snaprealm()->get_latest_snap()); // log + wait mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi)); diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index 5089a479f4edc..d70bb3b3c2d24 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -278,7 +278,7 @@ WRITE_CLASS_ENCODER(inode_t) struct old_inode_t { snapid_t first; - inodeno_t inode; + inode_t inode; map xattrs; void encode(bufferlist& bl) const { diff --git a/src/mds/snap.cc b/src/mds/snap.cc index fe5dd26ea2afe..ac2b4a5dadd9c 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -80,7 +80,7 @@ void SnapRealm::get_snap_set(set &s, snapid_t first, snapid_t last) oldparent->snaprealm->get_snap_set(s, MAX(first, p->second.first), thru); - thru++; + ++thru; } if (thru <= last && parent) parent->get_snap_set(s, thru, last); diff --git a/src/messages/MClientFileCaps.h b/src/messages/MClientFileCaps.h index 1012a15d05e87..7dd499878c460 100644 --- a/src/messages/MClientFileCaps.h +++ b/src/messages/MClientFileCaps.h @@ -43,8 +43,8 @@ class MClientFileCaps : public Message { capseq_t get_mseq() { return h.migrate_seq; } inodeno_t get_snap_realm() { return inodeno_t(h.snap_realm); } - snapid_t get_snap_created() { return h.snap_created; } - snapid_t get_snap_highwater() { return h.snap_highwater; } + snapid_t get_snap_created() { return snapid_t(h.snap_created); } + snapid_t get_snap_highwater() { return snapid_t(h.snap_highwater); } vector &get_snaps() { return snaps; } inodeno_t get_ino() { return inodeno_t(h.ino); } diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h index 4450fcd628c4e..2dbf9d50773fd 100644 --- a/src/messages/MClientReply.h +++ b/src/messages/MClientReply.h @@ -165,8 +165,8 @@ class MClientReply : public Message { int get_result() { return (__s32)(__u32)st.result; } inodeno_t get_snap_realm() { return inodeno_t((__u64)st.snap_realm); } - snapid_t get_snap_created() { return st.snap_created; } - snapid_t get_snap_highwater() { return st.snap_highwater; } + snapid_t get_snap_created() { return snapid_t(st.snap_created); } + snapid_t get_snap_highwater() { return snapid_t(st.snap_highwater); } vector &get_snaps() { return snaps; } void set_snap_info(inodeno_t r, snapid_t c, snapid_t hw) { -- 2.39.5