On 4/28/22 8:29 PM, Jeff Layton wrote:
On Thu, 2022-04-28 at 20:13 +0800, Xiubo Li wrote:
For example if the Frwcb caps are being revoked, but only the Fr
caps is still being used then the kclient will skip releasing them
all. But in next turn if the Fr caps is ready to be released the
Fw caps maybe just being used again. So in corner case, such as
heavy load IOs, the revocation maybe stuck for a long time.
Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx>
---
fs/ceph/caps.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 0c0c8f5ae3b3..7eb5238941fc 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1947,6 +1947,13 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
/* The ones we currently want to retain (may be adjusted below) */
retain = file_wanted | used | CEPH_CAP_PIN;
+
+ /*
+ * Do not retain the capabilities if they are under revoking
+ * but not used, this could help speed up the revoking.
+ */
+ retain &= ~((revoking & retain) & ~used);
+
if (!mdsc->stopping && inode->i_nlink > 0) {
if (file_wanted) {
retain |= CEPH_CAP_ANY; /* be greedy */
Actually maybe something like this would be simpler to understand?
/* Retain any caps that are actively in use */
retain = used | CEPH_CAP_PIN;
/* Also retain caps wanted by open files, if they aren't being revoked */
retain |= (file_wanted & ~revoking);
This won't work, because the caps maybe '|' back again in the following
code:
1950 if (!mdsc->stopping && inode->i_nlink > 0) {
1951 if (file_wanted) {
1952 retain |= CEPH_CAP_ANY; /* be greedy */
...
1979 }
I have adjust the code and simplified it in V2.
-- Xiubo