[PATCH] ceph: trigger to flush dirty caps when trimming caps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Xiubo Li <xiubli@xxxxxxxxxx>

The MDS side may time out waiting the caps to be released, so we
need to trigger to flush the dirty caps as soon as possible.

URL: https://tracker.ceph.com/issues/50223
Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx>
---
 fs/ceph/caps.c       |  9 +++++++--
 fs/ceph/mds_client.c | 14 +++++++++-----
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index a36366df7773..93953ae07398 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2035,6 +2035,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags)
 	struct ceph_mds_session *session = NULL;
 
 	spin_lock(&ci->i_ceph_lock);
+
+	/* Cancel the delay caps checking */
+	__cap_delay_cancel(mdsc, ci);
+
 	if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
 		ci->i_ceph_flags |= CEPH_I_ASYNC_CHECK_CAPS;
 
@@ -4644,8 +4648,6 @@ unsigned long ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
 			if (time_before(jiffies, ci->i_hold_caps_max))
 				break;
 		}
-		list_del_init(&ci->i_cap_delay_list);
-
 		inode = igrab(&ci->netfs.inode);
 		if (inode) {
 			spin_unlock(&mdsc->cap_delay_lock);
@@ -4654,7 +4656,10 @@ unsigned long ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
 			ceph_check_caps(ci, 0);
 			iput(inode);
 			spin_lock(&mdsc->cap_delay_lock);
+		} else {
+			list_del_init(&ci->i_cap_delay_list);
 		}
+
 	}
 	spin_unlock(&mdsc->cap_delay_lock);
 	doutc(cl, "done\n");
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a7bffb030036..7896bf27a3cf 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2160,6 +2160,7 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
 	struct ceph_inode_info *ci = ceph_inode(inode);
 	int used, wanted, oissued, mine;
 	struct ceph_cap *cap;
+	bool check_cap = false;
 
 	if (*remaining <= 0)
 		return -1;
@@ -2180,9 +2181,6 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
 	      ceph_cap_string(oissued), ceph_cap_string(used),
 	      ceph_cap_string(wanted));
 	if (cap == ci->i_auth_cap) {
-		if (ci->i_dirty_caps || ci->i_flushing_caps ||
-		    !list_empty(&ci->i_cap_snaps))
-			goto out;
 		if ((used | wanted) & CEPH_CAP_ANY_WR)
 			goto out;
 		/* Note: it's possible that i_filelock_ref becomes non-zero
@@ -2190,6 +2188,8 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
 		 * of lock mds request will re-add auth caps. */
 		if (atomic_read(&ci->i_filelock_ref) > 0)
 			goto out;
+		if (ci->i_dirty_caps || !list_empty(&ci->i_cap_snaps))
+			check_cap = true;
 	}
 	/* The inode has cached pages, but it's no longer used.
 	 * we can safely drop it */
@@ -2202,7 +2202,7 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
 	if ((used | wanted) & ~oissued & mine)
 		goto out;   /* we need these caps */
 
-	if (oissued) {
+	if (oissued && cap != ci->i_auth_cap) {
 		/* we aren't the only cap.. just remove us */
 		ceph_remove_cap(mdsc, cap, true);
 		(*remaining)--;
@@ -2223,11 +2223,15 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
 		} else {
 			dput(dentry);
 		}
-		return 0;
+		goto unlocked;
 	}
 
 out:
 	spin_unlock(&ci->i_ceph_lock);
+
+unlocked:
+	if (check_cap)
+		ceph_check_caps(ci, CHECK_CAPS_FLUSH);
 	return 0;
 }
 
-- 
2.39.1




[Index of Archives]     [CEPH Users]     [Ceph Large]     [Ceph Dev]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux