diff options
author | Yan, Zheng <zyan@redhat.com> | 2017-12-19 05:00:54 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-01-29 12:36:09 -0500 |
commit | 7d9c9193b5d0b1b806f453a3baa9bfe7e6fac52d (patch) | |
tree | c25913f90e6e3af08160c72b9018afe0726effa2 | |
parent | 314c4737a45dd4447eac6d313e3715b25785f58b (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.c | 14 | ||||
-rw-r--r-- | fs/ceph/snap.c | 8 |
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); |