From bc9b7792e4d44c199b526c2d5b17916d948b0354 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 10 Jan 2017 17:16:40 +0800 Subject: [PATCH] client: fix Client::handle_cap_flushsnap_ack() crash 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 (cherry picked from commit 525c52fd491ed1ced385c8047872e3f557f8423f) Conflicts: src/client/Client.cc (jewel does in->cap_snaps.erase(follows), master does not; put it after the tmp_ref assignment) --- src/client/Client.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/client/Client.cc b/src/client/Client.cc index 576babe2083f..719370dc8dfc 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4741,6 +4741,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 in->cap_snaps.erase(follows); if (in->flushing_caps == 0 && in->cap_snaps.empty()) in->flushing_cap_item.remove_myself(); -- 2.47.3