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)
Conflicts:
src/client/Client.cc (jewel does in->cap_snaps.erase(follows), master
does not; put it after the tmp_ref assignment)
} 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();