aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2019-07-22 13:12:01 -0400
committerIlya Dryomov <idryomov@gmail.com>2019-09-16 06:06:24 -0400
commit606d102327a45a49d293557527802ee7fbfd7af1 (patch)
treefe5f8976a9670517eaaeba958845392a21da94ba /fs
parent5de16b30d3121eca26c8c898cc0eff090e21dda6 (diff)
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: Jeff Layton <jlayton@kernel.org> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/caps.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 4615f2501e15..bdfec8978479 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -614,6 +614,7 @@ void ceph_add_cap(struct inode *inode,
614 struct ceph_cap *cap; 614 struct ceph_cap *cap;
615 int mds = session->s_mds; 615 int mds = session->s_mds;
616 int actual_wanted; 616 int actual_wanted;
617 u32 gen;
617 618
618 dout("add_cap %p mds%d cap %llx %s seq %d\n", inode, 619 dout("add_cap %p mds%d cap %llx %s seq %d\n", inode,
619 session->s_mds, cap_id, ceph_cap_string(issued), seq); 620 session->s_mds, cap_id, ceph_cap_string(issued), seq);
@@ -625,6 +626,10 @@ void ceph_add_cap(struct inode *inode,
625 if (fmode >= 0) 626 if (fmode >= 0)
626 wanted |= ceph_caps_for_mode(fmode); 627 wanted |= ceph_caps_for_mode(fmode);
627 628
629 spin_lock(&session->s_gen_ttl_lock);
630 gen = session->s_cap_gen;
631 spin_unlock(&session->s_gen_ttl_lock);
632
628 cap = __get_cap_for_mds(ci, mds); 633 cap = __get_cap_for_mds(ci, mds);
629 if (!cap) { 634 if (!cap) {
630 cap = *new_cap; 635 cap = *new_cap;
@@ -650,7 +655,7 @@ void ceph_add_cap(struct inode *inode,
650 list_move_tail(&cap->session_caps, &session->s_caps); 655 list_move_tail(&cap->session_caps, &session->s_caps);
651 spin_unlock(&session->s_cap_lock); 656 spin_unlock(&session->s_cap_lock);
652 657
653 if (cap->cap_gen < session->s_cap_gen) 658 if (cap->cap_gen < gen)
654 cap->issued = cap->implemented = CEPH_CAP_PIN; 659 cap->issued = cap->implemented = CEPH_CAP_PIN;
655 660
656 /* 661 /*
@@ -744,7 +749,7 @@ void ceph_add_cap(struct inode *inode,
744 cap->seq = seq; 749 cap->seq = seq;
745 cap->issue_seq = seq; 750 cap->issue_seq = seq;
746 cap->mseq = mseq; 751 cap->mseq = mseq;
747 cap->cap_gen = session->s_cap_gen; 752 cap->cap_gen = gen;
748 753
749 if (fmode >= 0) 754 if (fmode >= 0)
750 __ceph_get_fmode(ci, fmode); 755 __ceph_get_fmode(ci, fmode);