summaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2021-09-02 18:47:01 +0200
committerIlya Dryomov <idryomov@gmail.com>2021-11-08 03:29:51 +0100
commit3c3050267e3c9a230f23a5621d7c6bd084d15094 (patch)
tree59d272dacf493f6fc83e9e1e37791c0dff5bd19e /fs/ceph
parentceph: drop private list from remove_session_caps_cb (diff)
downloadlinux-3c3050267e3c9a230f23a5621d7c6bd084d15094.tar.xz
linux-3c3050267e3c9a230f23a5621d7c6bd084d15094.zip
ceph: fix auth cap handling logic in remove_session_caps_cb
The existing logic relies on ci->i_auth_cap being NULL, but if we end up removing the auth cap early, then we'll do a lot of useless work and lock-taking on the remaining caps. Ensure that we only do the auth cap removal when we're _actually_ removing the auth cap. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/mds_client.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 9967824ad9c3..3239e6c9047f 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1619,6 +1619,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
struct ceph_fs_client *fsc = (struct ceph_fs_client *)arg;
struct ceph_mds_client *mdsc = fsc->mdsc;
struct ceph_inode_info *ci = ceph_inode(inode);
+ bool is_auth;
bool dirty_dropped = false;
bool invalidate = false;
int capsnap_release = 0;
@@ -1626,8 +1627,9 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
dout("removing cap %p, ci is %p, inode is %p\n",
cap, ci, &ci->vfs_inode);
spin_lock(&ci->i_ceph_lock);
+ is_auth = (cap == ci->i_auth_cap);
__ceph_remove_cap(cap, false);
- if (!ci->i_auth_cap) {
+ if (is_auth) {
struct ceph_cap_flush *cf;
if (READ_ONCE(fsc->mount_state) >= CEPH_MOUNT_SHUTDOWN) {