]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: fix Client::handle_cap_flushsnap_ack() crash 14563/head
authorYan, Zheng <zyan@redhat.com>
Tue, 10 Jan 2017 09:16:40 +0000 (17:16 +0800)
committerNathan Cutler <ncutler@suse.com>
Fri, 14 Apr 2017 21:40:22 +0000 (23:40 +0200)
Struct CapSnap holds a reference to its parent inode. So erasing
struct CapSnap from Inode::cap_snaps may drop inode's last reference.
The inode gets freed in the middle of erasing struct CapSnap

Fixes: http://tracker.ceph.com/issues/18460
Signed-off-by: Yan, Zheng <zyan@redhat.com>
(cherry picked from commit 525c52fd491ed1ced385c8047872e3f557f8423f)

src/client/Client.cc

index 81be35b983560d1a5e8f0ecb54dabcfe19cbdefd..14c3aa75b3eb749837d95e934c23d5d19126d7c3 100644 (file)
@@ -4805,6 +4805,9 @@ void Client::handle_cap_flushsnap_ack(MetaSession *session, Inode *in, MClientCa
     } else {
       ldout(cct, 5) << "handle_cap_flushedsnap mds." << mds << " flushed snap follows " << follows
              << " on " << *in << dendl;
+      InodeRef tmp_ref;
+      if (in->get_num_ref() == 1)
+       tmp_ref = in; // make sure inode not get freed while erasing item from in->cap_snaps
       if (in->flushing_caps == 0 && in->cap_snaps.empty())
        in->flushing_cap_item.remove_myself();
       session->flushing_caps_tids.erase(capsnap.flush_tid);