diff options
author | Yan, Zheng <zyan@redhat.com> | 2017-12-19 18:00:54 +0800 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-01-29 18:36:09 +0100 |
commit | 7d9c9193b5d0b1b806f453a3baa9bfe7e6fac52d (patch) | |
tree | c25913f90e6e3af08160c72b9018afe0726effa2 /fs | |
parent | 314c4737a45dd4447eac6d313e3715b25785f58b (diff) | |
download | linux-stable-7d9c9193b5d0b1b806f453a3baa9bfe7e6fac52d.tar.gz linux-stable-7d9c9193b5d0b1b806f453a3baa9bfe7e6fac52d.tar.bz2 linux-stable-7d9c9193b5d0b1b806f453a3baa9bfe7e6fac52d.zip |
ceph: fix incorrect snaprealm when adding caps
Signed-off-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 | 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, } } - if (!ci->i_snap_realm) { + if (!ci->i_snap_realm || + ((flags & CEPH_CAP_FLAG_AUTH) && + realmino != (u64)-1 && ci->i_snap_realm->ino != realmino)) { /* * add this inode to the appropriate snap realm */ struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc, realmino); if (realm) { + struct ceph_snap_realm *oldrealm = ci->i_snap_realm; + if (oldrealm) { + spin_lock(&oldrealm->inodes_with_caps_lock); + list_del_init(&ci->i_snap_realm_item); + spin_unlock(&oldrealm->inodes_with_caps_lock); + } + spin_lock(&realm->inodes_with_caps_lock); ci->i_snap_realm = realm; list_add(&ci->i_snap_realm_item, &realm->inodes_with_caps); spin_unlock(&realm->inodes_with_caps_lock); + + if (oldrealm) + ceph_put_snap_realm(mdsc, oldrealm); } else { pr_err("ceph_add_cap: couldn't find snap realm %llx\n", 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, /* * Move the inode to the new realm */ - spin_lock(&realm->inodes_with_caps_lock); + oldrealm = ci->i_snap_realm; + spin_lock(&oldrealm->inodes_with_caps_lock); list_del_init(&ci->i_snap_realm_item); + spin_unlock(&oldrealm->inodes_with_caps_lock); + + spin_lock(&realm->inodes_with_caps_lock); list_add(&ci->i_snap_realm_item, &realm->inodes_with_caps); - oldrealm = ci->i_snap_realm; ci->i_snap_realm = realm; spin_unlock(&realm->inodes_with_caps_lock); + spin_unlock(&ci->i_ceph_lock); ceph_get_snap_realm(mdsc, realm); |