From: Xiubo Li <xiubli@xxxxxxxxxx> We should call the check_caps() again immediately after the async creating finishes in case the MDS is waiting for caps revocation to finish. URL: https://tracker.ceph.com/issues/46904 Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx> --- fs/ceph/caps.c | 2 ++ fs/ceph/file.c | 9 +++++++++ fs/ceph/super.h | 1 + 3 files changed, 12 insertions(+) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 5e5b0c696584..894adfb4a092 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1967,6 +1967,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 eb34da31600d..85afcbbb5648 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -539,14 +539,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 cff419f63e51..7b75a84ba48d 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -607,6 +607,7 @@ 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. -- 2.31.1