]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: snapid_t, multiversion inodes, fixed up perdirty_nested
authorSage Weil <sage@newdream.net>
Fri, 11 Jul 2008 16:52:32 +0000 (09:52 -0700)
committerSage Weil <sage@newdream.net>
Fri, 11 Jul 2008 20:29:17 +0000 (13:29 -0700)
13 files changed:
src/include/object.h
src/include/types.h
src/mds/CDir.cc
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Locker.cc
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/Server.cc
src/mds/mdstypes.h
src/mds/snap.cc
src/messages/MClientFileCaps.h
src/messages/MClientReply.h

index 6475c77ff17dcbef8b1922a8fc1fb1f494850fc4..01528ad698794c690df7b50125ff63ccda566ec0 100644 (file)
@@ -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));
   };
 
index 7827bc5713b3aa732419e727984fa9065a088e89..bdf65acf198195cad1ecf32c68ce11479c11dfc1 100644 (file)
@@ -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
 
index f6c6a61b4c7a8673dabb6c95dc815721ac82ffa5..06d071ddfe21fdb7b26b4041fef31cad68fa2833 100644 (file)
@@ -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()) 
index 296a4c9c694c516ab3aad150bf3ffc6249177fca..08433b3307416aef79cdbb778e48a74cbd12039a 100644 (file)
@@ -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()) 
index fb8bb9595cf5d7526b80cb5edba704f24b6d8af9..a08d96701f0ff588435376509a8739fe1ed1bd6d 100644 (file)
@@ -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<snapid_t, old_inode_t> 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; }
index b49fe010537f3cc8dc34c5561e0d1498490c7abf..be7684a80dc2f9e422211025efe18e47f5ee6b02 100644 (file)
@@ -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<CInode*>::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);
   }
  
 }
index e169b1f6652121fc723f26b4d916ad75444a9cee..dc8f0fea36595e87038df227422509ee64e9f604 100644 (file)
@@ -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());
     }   
   }
 }    
index 59a0f5b6865504499f1fd6fc294b76267fb7c9ed..37b96f3481b008855cfb2112c7d7b836fd3eac2d 100644 (file)
@@ -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<int> &slaves) {
index 374d244eef7aa8374560a1dd3e3e512e46a7a277..67f51aafc52238777d02f5fcb09089a3f75fd6bf 100644 (file)
@@ -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));
index 5089a479f4edc23a68cfb3546491ca9569783c22..d70bb3b3c2d24178aeedc8e11186602808d4f15c 100644 (file)
@@ -278,7 +278,7 @@ WRITE_CLASS_ENCODER(inode_t)
 
 struct old_inode_t {
   snapid_t first;
-  inodeno_t inode;
+  inode_t inode;
   map<string,bufferptr> xattrs;
 
   void encode(bufferlist& bl) const {
index fe5dd26ea2afe40599f4573ca2e9333221adb3be..ac2b4a5dadd9c6f23a10007ab286e07417ff0010 100644 (file)
@@ -80,7 +80,7 @@ void SnapRealm::get_snap_set(set<snapid_t> &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);
index 1012a15d05e8712c1c184523dba0b640f6c6615a..7dd499878c460c499c62b414c7bc91b227d209b8 100644 (file)
@@ -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<snapid_t> &get_snaps() { return snaps; }
 
   inodeno_t get_ino() { return inodeno_t(h.ino); }
index 4450fcd628c4ee993d7fe55ef78a8b238d342d42..2dbf9d50773fdcd70f400e63a4b269823e06cde0 100644 (file)
@@ -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<snapid_t> &get_snaps() { return snaps; }
 
   void set_snap_info(inodeno_t r, snapid_t c, snapid_t hw) {