|
Luís Henriques |
34ce54 |
From: Xiubo Li <xiubli@redhat.com>
|
|
Luís Henriques |
34ce54 |
Date: Wed, 27 Apr 2022 14:14:41 +0800
|
|
Luís Henriques |
34ce54 |
Subject: ceph: try to queue a writeback if revoking fails
|
|
Luís Henriques |
34ce54 |
Git-commit: a74379543d229a3fb1af8cd44cbd19844a7bb1bc
|
|
Luís Henriques |
34ce54 |
Patch-mainline: v5.19-rc1
|
|
Luís Henriques |
34ce54 |
References: jsc#SES-1880
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
If the pagecaches writeback just finished and the i_wrbuffer_ref
|
|
Luís Henriques |
34ce54 |
reaches zero it will try to trigger ceph_check_caps(). But if just
|
|
Luís Henriques |
34ce54 |
before ceph_check_caps() the i_wrbuffer_ref could be increased
|
|
Luís Henriques |
34ce54 |
again by mmap/cache write, then the Fwb revoke will fail.
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
We need to try to queue a writeback in this case instead of
|
|
Luís Henriques |
34ce54 |
triggering the writeback by BDI's delayed work per 5 seconds.
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
URL: https://tracker.ceph.com/issues/46904
|
|
Luís Henriques |
34ce54 |
URL: https://tracker.ceph.com/issues/55377
|
|
Luís Henriques |
34ce54 |
Signed-off-by: Xiubo Li <xiubli@redhat.com>
|
|
Luís Henriques |
34ce54 |
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
Luís Henriques |
34ce54 |
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
|
Luís Henriques |
34ce54 |
Acked-by: Luis Henriques <lhenriques@suse.com>
|
|
Luís Henriques |
34ce54 |
---
|
|
Luís Henriques |
34ce54 |
fs/ceph/caps.c | 28 ++++++++++++++++++++++++----
|
|
Luís Henriques |
34ce54 |
1 file changed, 24 insertions(+), 4 deletions(-)
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
|
|
Luís Henriques |
34ce54 |
index a051e6e4d7ca..bf2e94005598 100644
|
|
Luís Henriques |
34ce54 |
--- a/fs/ceph/caps.c
|
|
Luís Henriques |
34ce54 |
+++ b/fs/ceph/caps.c
|
|
Luís Henriques |
34ce54 |
@@ -1911,6 +1911,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
|
|
Luís Henriques |
34ce54 |
struct rb_node *p;
|
|
Luís Henriques |
34ce54 |
bool queue_invalidate = false;
|
|
Luís Henriques |
34ce54 |
bool tried_invalidate = false;
|
|
Luís Henriques |
34ce54 |
+ bool queue_writeback = false;
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
if (session)
|
|
Luís Henriques |
34ce54 |
ceph_get_mds_session(session);
|
|
Luís Henriques |
34ce54 |
@@ -2063,10 +2064,27 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
|
|
Luís Henriques |
34ce54 |
}
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
/* completed revocation? going down and there are no caps? */
|
|
Luís Henriques |
34ce54 |
- if (revoking && (revoking & cap_used) == 0) {
|
|
Luís Henriques |
34ce54 |
- dout("completed revocation of %s\n",
|
|
Luís Henriques |
34ce54 |
- ceph_cap_string(cap->implemented & ~cap->issued));
|
|
Luís Henriques |
34ce54 |
- goto ack;
|
|
Luís Henriques |
34ce54 |
+ if (revoking) {
|
|
Luís Henriques |
34ce54 |
+ if ((revoking & cap_used) == 0) {
|
|
Luís Henriques |
34ce54 |
+ dout("completed revocation of %s\n",
|
|
Luís Henriques |
34ce54 |
+ ceph_cap_string(cap->implemented & ~cap->issued));
|
|
Luís Henriques |
34ce54 |
+ goto ack;
|
|
Luís Henriques |
34ce54 |
+ }
|
|
Luís Henriques |
34ce54 |
+
|
|
Luís Henriques |
34ce54 |
+ /*
|
|
Luís Henriques |
34ce54 |
+ * If the "i_wrbuffer_ref" was increased by mmap or generic
|
|
Luís Henriques |
34ce54 |
+ * cache write just before the ceph_check_caps() is called,
|
|
Luís Henriques |
34ce54 |
+ * the Fb capability revoking will fail this time. Then we
|
|
Luís Henriques |
34ce54 |
+ * must wait for the BDI's delayed work to flush the dirty
|
|
Luís Henriques |
34ce54 |
+ * pages and to release the "i_wrbuffer_ref", which will cost
|
|
Luís Henriques |
34ce54 |
+ * at most 5 seconds. That means the MDS needs to wait at
|
|
Luís Henriques |
34ce54 |
+ * most 5 seconds to finished the Fb capability's revocation.
|
|
Luís Henriques |
34ce54 |
+ *
|
|
Luís Henriques |
34ce54 |
+ * Let's queue a writeback for it.
|
|
Luís Henriques |
34ce54 |
+ */
|
|
Luís Henriques |
34ce54 |
+ if (S_ISREG(inode->i_mode) && ci->i_wrbuffer_ref &&
|
|
Luís Henriques |
34ce54 |
+ (revoking & CEPH_CAP_FILE_BUFFER))
|
|
Luís Henriques |
34ce54 |
+ queue_writeback = true;
|
|
Luís Henriques |
34ce54 |
}
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
/* want more caps from mds? */
|
|
Luís Henriques |
34ce54 |
@@ -2136,6 +2154,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
|
|
Luís Henriques |
34ce54 |
spin_unlock(&ci->i_ceph_lock);
|
|
Luís Henriques |
34ce54 |
|
|
Luís Henriques |
34ce54 |
ceph_put_mds_session(session);
|
|
Luís Henriques |
34ce54 |
+ if (queue_writeback)
|
|
Luís Henriques |
34ce54 |
+ ceph_queue_writeback(inode);
|
|
Luís Henriques |
34ce54 |
if (queue_invalidate)
|
|
Luís Henriques |
34ce54 |
ceph_queue_invalidate(inode);
|
|
Luís Henriques |
34ce54 |
}
|
|
Luís Henriques |
34ce54 |
|