]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: split old_inode when needed
authorYan, Zheng <zyan@redhat.com>
Thu, 15 Jan 2015 07:24:53 +0000 (15:24 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 5 Feb 2015 14:40:39 +0000 (22:40 +0800)
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Locker.cc

index 6006c1a06cf1f2a9ad1c6e4dc9032740d6cb75df..1313a67c12d14efd2d41147c83494477de89eeb7 100644 (file)
@@ -2406,6 +2406,19 @@ old_inode_t& CInode::cow_old_inode(snapid_t follows, bool cow_head)
   return old;
 }
 
+void CInode::split_old_inode(snapid_t snap)
+{
+  map<snapid_t, old_inode_t>::iterator p = old_inodes.lower_bound(snap);
+  assert(p != old_inodes.end() && p->second.first < snap);
+
+  old_inode_t &old = old_inodes[snap - 1];
+  old = p->second;
+
+  p->second.first = snap;
+  dout(10) << "split_old_inode " << "[" << old.first << "," << p->first
+          << "] to [" << snap << "," << p->first << "] on " << *this << dendl;
+}
+
 void CInode::pre_cow_old_inode()
 {
   snapid_t follows = find_snaprealm()->get_newest_seq();
index da3c71d7e0ac685ff9661f1cf17633dbc620d14e..e6d159230cdacf45dd57efa13cd862288afc96ac 100644 (file)
@@ -367,6 +367,7 @@ private:
 
 public:
   old_inode_t& cow_old_inode(snapid_t follows, bool cow_head);
+  void split_old_inode(snapid_t snap);
   old_inode_t *pick_old_inode(snapid_t last);
   void pre_cow_old_inode();
   void purge_stale_snap_data(const std::set<snapid_t>& snaps);
index 39dcbb4d38f375007a9cefdf7f0cbf315f90e030..212a042c58336f5b28b433976f2faddf8ee5845c 100644 (file)
@@ -2834,19 +2834,24 @@ void Locker::_do_snap_update(CInode *in, snapid_t snap, int dirty, snapid_t foll
   old_inode_t *oi = 0;
   if (in->is_multiversion()) {
     oi = in->pick_old_inode(snap);
-    if (oi) {
-      dout(10) << " writing into old inode" << dendl;
-      if (xattrs)
-       px = &oi->xattrs;
-    }
   }
-  if (xattrs && !px)
-    px = new map<string,bufferptr>;
 
-  inode_t *pi = in->project_inode(px);
-  pi->version = in->pre_dirty();
-  if (oi)
+  inode_t *pi;
+  if (oi) {
+    dout(10) << " writing into old inode" << dendl;
+    pi = in->project_inode();
+    pi->version = in->pre_dirty();
+    if (snap > oi->first)
+      in->split_old_inode(snap);
     pi = &oi->inode;
+    if (xattrs)
+      px = &oi->xattrs;
+  } else {
+    if (xattrs)
+      px = new map<string,bufferptr>;
+    pi = in->project_inode(px);
+    pi->version = in->pre_dirty();
+  }
 
   _update_cap_fields(in, dirty, m, pi);