summaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorXiubo Li <xiubli@redhat.com>2022-10-17 22:17:35 +0800
committerIlya Dryomov <idryomov@gmail.com>2022-12-12 19:15:39 +0100
commit68c62bee9d081cf815310b3a96e38d94fc16007d (patch)
tree9516c8722d9858c483d4f72fc3f91f2a83031dfd /fs/ceph
parente4b731ccb0975fd97283e0c0d9841a89063ec31a (diff)
downloadlinux-stable-68c62bee9d081cf815310b3a96e38d94fc16007d.tar.gz
linux-stable-68c62bee9d081cf815310b3a96e38d94fc16007d.tar.bz2
linux-stable-68c62bee9d081cf815310b3a96e38d94fc16007d.zip
ceph: try to check caps immediately after async creating finishes
We should call the check_caps() again immediately after the async creating finishes in case the MDS is waiting for caps revocation to finish. Link: https://tracker.ceph.com/issues/46904 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/caps.c2
-rw-r--r--fs/ceph/file.c9
-rw-r--r--fs/ceph/super.h2
3 files changed, 13 insertions, 0 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 1323fa28ab01..4b159f97fe7b 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1916,6 +1916,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags)
spin_lock(&ci->i_ceph_lock);
if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
+ ci->i_ceph_flags |= CEPH_I_ASYNC_CHECK_CAPS;
+
/* Don't send messages until we get async create reply */
spin_unlock(&ci->i_ceph_lock);
return;
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 4e68220bc06d..a6681b12e280 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -534,14 +534,23 @@ static void wake_async_create_waiters(struct inode *inode,
struct ceph_mds_session *session)
{
struct ceph_inode_info *ci = ceph_inode(inode);
+ bool check_cap = false;
spin_lock(&ci->i_ceph_lock);
if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
ci->i_ceph_flags &= ~CEPH_I_ASYNC_CREATE;
wake_up_bit(&ci->i_ceph_flags, CEPH_ASYNC_CREATE_BIT);
+
+ if (ci->i_ceph_flags & CEPH_I_ASYNC_CHECK_CAPS) {
+ ci->i_ceph_flags &= ~CEPH_I_ASYNC_CHECK_CAPS;
+ check_cap = true;
+ }
}
ceph_kick_flushing_inode_caps(session, ci);
spin_unlock(&ci->i_ceph_lock);
+
+ if (check_cap)
+ ceph_check_caps(ci, CHECK_CAPS_FLUSH);
}
static void ceph_async_create_cb(struct ceph_mds_client *mdsc,
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index e8bc1d0d2614..e1bd6f487226 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -593,6 +593,8 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
#define CEPH_ASYNC_CREATE_BIT (12) /* async create in flight for this */
#define CEPH_I_ASYNC_CREATE (1 << CEPH_ASYNC_CREATE_BIT)
#define CEPH_I_SHUTDOWN (1 << 13) /* inode is no longer usable */
+#define CEPH_I_ASYNC_CHECK_CAPS (1 << 14) /* check caps immediately after async
+ creating finishes */
/*
* Masks of ceph inode work.