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>
This commit is contained in:
@ -1916,6 +1916,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags)
|
|||||||
|
|
||||||
spin_lock(&ci->i_ceph_lock);
|
spin_lock(&ci->i_ceph_lock);
|
||||||
if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
|
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 */
|
/* Don't send messages until we get async create reply */
|
||||||
spin_unlock(&ci->i_ceph_lock);
|
spin_unlock(&ci->i_ceph_lock);
|
||||||
return;
|
return;
|
||||||
|
@ -534,14 +534,23 @@ static void wake_async_create_waiters(struct inode *inode,
|
|||||||
struct ceph_mds_session *session)
|
struct ceph_mds_session *session)
|
||||||
{
|
{
|
||||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||||
|
bool check_cap = false;
|
||||||
|
|
||||||
spin_lock(&ci->i_ceph_lock);
|
spin_lock(&ci->i_ceph_lock);
|
||||||
if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
|
if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
|
||||||
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);
|
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);
|
ceph_kick_flushing_inode_caps(session, ci);
|
||||||
spin_unlock(&ci->i_ceph_lock);
|
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,
|
static void ceph_async_create_cb(struct ceph_mds_client *mdsc,
|
||||||
|
@ -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_ASYNC_CREATE_BIT (12) /* async create in flight for this */
|
||||||
#define CEPH_I_ASYNC_CREATE (1 << CEPH_ASYNC_CREATE_BIT)
|
#define CEPH_I_ASYNC_CREATE (1 << CEPH_ASYNC_CREATE_BIT)
|
||||||
#define CEPH_I_SHUTDOWN (1 << 13) /* inode is no longer usable */
|
#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.
|
* Masks of ceph inode work.
|
||||||
|
Reference in New Issue
Block a user