From: Yan, Zheng Date: Thu, 15 Jan 2015 07:24:53 +0000 (+0800) Subject: mds: split old_inode when needed X-Git-Tag: v0.93~87^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b66e74961b471f2f1938ffe04d2a3a3791d0e56a;p=ceph.git mds: split old_inode when needed Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 6006c1a06cf1..1313a67c12d1 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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::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(); diff --git a/src/mds/CInode.h b/src/mds/CInode.h index da3c71d7e0ac..e6d159230cda 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -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& snaps); diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 39dcbb4d38f3..212a042c5833 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -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; - 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; + pi = in->project_inode(px); + pi->version = in->pre_dirty(); + } _update_cap_fields(in, dirty, m, pi);