From: Xiubo Li <xiubli@xxxxxxxxxx> Try to queue writeback and invalidate the dirty pages when sessions are closed, rejected or reconnect denied. Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx> --- fs/ceph/mds_client.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index be1ac9f8e0e6..68f3b5ed6ac8 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1385,9 +1385,11 @@ 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_inode_info *ci = ceph_inode(inode); + struct ceph_mds_session *session = cap->session; LIST_HEAD(to_remove); bool dirty_dropped = false; bool invalidate = false; + bool writeback = false; dout("removing cap %p, ci is %p, inode is %p\n", cap, ci, &ci->vfs_inode); @@ -1398,12 +1400,21 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, if (!ci->i_auth_cap) { struct ceph_cap_flush *cf; struct ceph_mds_client *mdsc = fsc->mdsc; + int s_state = session->s_state; if (READ_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) { if (inode->i_data.nrpages > 0) invalidate = true; if (ci->i_wrbuffer_ref > 0) mapping_set_error(&inode->i_data, -EIO); + } else if (s_state == CEPH_MDS_SESSION_CLOSED || + s_state == CEPH_MDS_SESSION_REJECTED) { + /* reconnect denied or rejected */ + if (!__ceph_is_any_real_caps(ci) && + inode->i_data.nrpages > 0) + invalidate = true; + if (ci->i_wrbuffer_ref > 0) + writeback = true; } while (!list_empty(&ci->i_cap_flush_list)) { @@ -1472,6 +1483,8 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, } wake_up_all(&ci->i_cap_wq); + if (writeback) + ceph_queue_writeback(inode); if (invalidate) ceph_queue_invalidate(inode); if (dirty_dropped) -- 2.21.0