Commit 606d1023 authored by Jeff Layton's avatar Jeff Layton Committed by Ilya Dryomov
Browse files

ceph: fetch cap_gen under spinlock in ceph_add_cap



It's protected by the s_gen_ttl_lock, so we should fetch under it
and ensure that we're using the same generation in both places.

Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Reviewed-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 5de16b30
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -614,6 +614,7 @@ void ceph_add_cap(struct inode *inode,
	struct ceph_cap *cap;
	int mds = session->s_mds;
	int actual_wanted;
	u32 gen;

	dout("add_cap %p mds%d cap %llx %s seq %d\n", inode,
	     session->s_mds, cap_id, ceph_cap_string(issued), seq);
@@ -625,6 +626,10 @@ void ceph_add_cap(struct inode *inode,
	if (fmode >= 0)
		wanted |= ceph_caps_for_mode(fmode);

	spin_lock(&session->s_gen_ttl_lock);
	gen = session->s_cap_gen;
	spin_unlock(&session->s_gen_ttl_lock);

	cap = __get_cap_for_mds(ci, mds);
	if (!cap) {
		cap = *new_cap;
@@ -650,7 +655,7 @@ void ceph_add_cap(struct inode *inode,
		list_move_tail(&cap->session_caps, &session->s_caps);
		spin_unlock(&session->s_cap_lock);

		if (cap->cap_gen < session->s_cap_gen)
		if (cap->cap_gen < gen)
			cap->issued = cap->implemented = CEPH_CAP_PIN;

		/*
@@ -744,7 +749,7 @@ void ceph_add_cap(struct inode *inode,
	cap->seq = seq;
	cap->issue_seq = seq;
	cap->mseq = mseq;
	cap->cap_gen = session->s_cap_gen;
	cap->cap_gen = gen;

	if (fmode >= 0)
		__ceph_get_fmode(ci, fmode);