aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2017-12-19 05:00:54 -0500
committerIlya Dryomov <idryomov@gmail.com>2018-01-29 12:36:09 -0500
commit7d9c9193b5d0b1b806f453a3baa9bfe7e6fac52d (patch)
treec25913f90e6e3af08160c72b9018afe0726effa2
parent314c4737a45dd4447eac6d313e3715b25785f58b (diff)
ceph: fix incorrect snaprealm when adding caps
Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--fs/ceph/caps.c14
-rw-r--r--fs/ceph/snap.c8
2 files changed, 19 insertions, 3 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 57120e3d44de..7e09fa8ab0ed 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -577,18 +577,30 @@ void ceph_add_cap(struct inode *inode,
577 } 577 }
578 } 578 }
579 579
580 if (!ci->i_snap_realm) { 580 if (!ci->i_snap_realm ||
581 ((flags & CEPH_CAP_FLAG_AUTH) &&
582 realmino != (u64)-1 && ci->i_snap_realm->ino != realmino)) {
581 /* 583 /*
582 * add this inode to the appropriate snap realm 584 * add this inode to the appropriate snap realm
583 */ 585 */
584 struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc, 586 struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc,
585 realmino); 587 realmino);
586 if (realm) { 588 if (realm) {
589 struct ceph_snap_realm *oldrealm = ci->i_snap_realm;
590 if (oldrealm) {
591 spin_lock(&oldrealm->inodes_with_caps_lock);
592 list_del_init(&ci->i_snap_realm_item);
593 spin_unlock(&oldrealm->inodes_with_caps_lock);
594 }
595
587 spin_lock(&realm->inodes_with_caps_lock); 596 spin_lock(&realm->inodes_with_caps_lock);
588 ci->i_snap_realm = realm; 597 ci->i_snap_realm = realm;
589 list_add(&ci->i_snap_realm_item, 598 list_add(&ci->i_snap_realm_item,
590 &realm->inodes_with_caps); 599 &realm->inodes_with_caps);
591 spin_unlock(&realm->inodes_with_caps_lock); 600 spin_unlock(&realm->inodes_with_caps_lock);
601
602 if (oldrealm)
603 ceph_put_snap_realm(mdsc, oldrealm);
592 } else { 604 } else {
593 pr_err("ceph_add_cap: couldn't find snap realm %llx\n", 605 pr_err("ceph_add_cap: couldn't find snap realm %llx\n",
594 realmino); 606 realmino);
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index 8a2ca41e4b97..07cf95e6413d 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -922,13 +922,17 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
922 /* 922 /*
923 * Move the inode to the new realm 923 * Move the inode to the new realm
924 */ 924 */
925 spin_lock(&realm->inodes_with_caps_lock); 925 oldrealm = ci->i_snap_realm;
926 spin_lock(&oldrealm->inodes_with_caps_lock);
926 list_del_init(&ci->i_snap_realm_item); 927 list_del_init(&ci->i_snap_realm_item);
928 spin_unlock(&oldrealm->inodes_with_caps_lock);
929
930 spin_lock(&realm->inodes_with_caps_lock);
927 list_add(&ci->i_snap_realm_item, 931 list_add(&ci->i_snap_realm_item,
928 &realm->inodes_with_caps); 932 &realm->inodes_with_caps);
929 oldrealm = ci->i_snap_realm;
930 ci->i_snap_realm = realm; 933 ci->i_snap_realm = realm;
931 spin_unlock(&realm->inodes_with_caps_lock); 934 spin_unlock(&realm->inodes_with_caps_lock);
935
932 spin_unlock(&ci->i_ceph_lock); 936 spin_unlock(&ci->i_ceph_lock);
933 937
934 ceph_get_snap_realm(mdsc, realm); 938 ceph_get_snap_realm(mdsc, realm);