From: Yan, Zheng Date: Tue, 21 Jun 2016 08:20:58 +0000 (+0800) Subject: mds: properly update client_snap_caps when splitting snap inode X-Git-Tag: ses5-milestone5~375^2~15 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4883779935219817c7e391940a025be1679daeb5;p=ceph.git mds: properly update client_snap_caps when splitting snap inode update the new snap inode's client_snap_caps according to the old snap inode. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 326fe35995b9..12b1a9d9480c 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -311,20 +311,23 @@ void CInode::remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t cli } } -void CInode::split_need_snapflush(CInode *cowin, CInode *in) +bool CInode::split_need_snapflush(CInode *cowin, CInode *in) { dout(10) << "split_need_snapflush [" << cowin->first << "," << cowin->last << "] for " << *cowin << dendl; + bool need_flush = false; for (compact_map >::iterator p = client_need_snapflush.lower_bound(cowin->first); p != client_need_snapflush.end() && p->first < in->first; ) { compact_map >::iterator q = p; ++p; assert(!q->second.empty()); - if (cowin->last >= q->first) + if (cowin->last >= q->first) { cowin->auth_pin(this); - else + need_flush = true; + } else client_need_snapflush.erase(q); in->auth_unpin(this); } + return need_flush; } void CInode::mark_dirty_rstat() diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 21686a2e080f..b4d9ba0602c8 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -566,7 +566,7 @@ public: void add_need_snapflush(CInode *snapin, snapid_t snapid, client_t client); void remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t client); - void split_need_snapflush(CInode *cowin, CInode *in); + bool split_need_snapflush(CInode *cowin, CInode *in); protected: diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 1830b8f73d4a..b71e1d4a699c 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -1546,7 +1546,21 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last) if (in->last != CEPH_NOSNAP) { CInode *head_in = get_inode(in->ino()); assert(head_in); - head_in->split_need_snapflush(oldin, in); + if (head_in->split_need_snapflush(oldin, in)) { + oldin->client_snap_caps = in->client_snap_caps; + for (compact_map >::iterator p = in->client_snap_caps.begin(); + p != in->client_snap_caps.end(); + ++p) { + SimpleLock *lock = oldin->get_lock(p->first); + assert(lock); + for (auto q = p->second.begin(); q != p->second.end(); ++q) { + oldin->auth_pin(lock); + lock->set_state(LOCK_SNAP_SYNC); // gathering + lock->get_wrlock(true); + } + } + } + return oldin; } // clone caps?