diff options
author | Jeff Layton <jlayton@kernel.org> | 2019-07-22 13:12:01 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-09-16 06:06:24 -0400 |
commit | 606d102327a45a49d293557527802ee7fbfd7af1 (patch) | |
tree | fe5f8976a9670517eaaeba958845392a21da94ba /fs | |
parent | 5de16b30d3121eca26c8c898cc0eff090e21dda6 (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.c | 9 |
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); |