Luis Henriques a522a2
From: "Yan, Zheng" <zyan@redhat.com>
Luis Henriques a522a2
Date: Thu, 22 Nov 2018 15:26:01 +0800
Luis Henriques a522a2
Subject: ceph: skip updating 'wanted' caps if caps are already issued
Luis Henriques a522a2
Git-commit: fdac94fab7995ebc52ff9c5b6247133c67a7564a
Luis Henriques a522a2
Patch-mainline: v5.0-rc1
Luis Henriques a522a2
References: bsc#1122215
Luis Henriques a522a2
Luis Henriques a522a2
When reading cached inode that already has Fscr caps, this can avoid
Luis Henriques a522a2
two cap messages (one updats 'wanted' caps, one clears 'wanted' caps).
Luis Henriques a522a2
Luis Henriques a522a2
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Luis Henriques a522a2
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Luis Henriques a522a2
Acked-by: Luis Henriques <lhenriques@suse.com>
Luis Henriques a522a2
---
Luis Henriques a522a2
 fs/ceph/caps.c |   27 +++++++++++++++++----------
Luis Henriques a522a2
 1 file changed, 17 insertions(+), 10 deletions(-)
Luis Henriques a522a2
Luis Henriques a522a2
--- a/fs/ceph/caps.c
Luis Henriques a522a2
+++ b/fs/ceph/caps.c
Luis Henriques a522a2
@@ -1970,8 +1970,7 @@ retry_locked:
Luis Henriques a522a2
 			goto ack;
Luis Henriques a522a2
 
Luis Henriques a522a2
 		/* things we might delay */
Luis Henriques a522a2
-		if ((cap->issued & ~retain) == 0 &&
Luis Henriques a522a2
-		    cap->mds_wanted == want)
Luis Henriques a522a2
+		if ((cap->issued & ~retain) == 0)
Luis Henriques a522a2
 			continue;     /* nope, all good */
Luis Henriques a522a2
 
Luis Henriques a522a2
 		if (no_delay)
Luis Henriques a522a2
@@ -3047,7 +3046,8 @@ static void handle_cap_grant(struct inod
Luis Henriques a522a2
 	int used, wanted, dirty;
Luis Henriques a522a2
 	u64 size = le64_to_cpu(grant->size);
Luis Henriques a522a2
 	u64 max_size = le64_to_cpu(grant->max_size);
Luis Henriques a522a2
-	int check_caps = 0;
Luis Henriques a522a2
+	unsigned char check_caps = 0;
Luis Henriques a522a2
+	bool was_stale = cap->cap_gen < session->s_cap_gen;
Luis Henriques a522a2
 	bool wake = false;
Luis Henriques a522a2
 	bool writeback = false;
Luis Henriques a522a2
 	bool queue_trunc = false;
Luis Henriques a522a2
@@ -3199,13 +3199,20 @@ static void handle_cap_grant(struct inod
Luis Henriques a522a2
 	     ceph_cap_string(wanted),
Luis Henriques a522a2
 	     ceph_cap_string(used),
Luis Henriques a522a2
 	     ceph_cap_string(dirty));
Luis Henriques a522a2
-	if (wanted != le32_to_cpu(grant->wanted)) {
Luis Henriques a522a2
-		dout("mds wanted %s -> %s\n",
Luis Henriques a522a2
-		     ceph_cap_string(le32_to_cpu(grant->wanted)),
Luis Henriques a522a2
-		     ceph_cap_string(wanted));
Luis Henriques a522a2
-		/* imported cap may not have correct mds_wanted */
Luis Henriques a522a2
-		if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT)
Luis Henriques a522a2
-			check_caps = 1;
Luis Henriques a522a2
+
Luis Henriques a522a2
+	if ((was_stale || le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) &&
Luis Henriques a522a2
+	    (wanted & ~(cap->mds_wanted | newcaps))) {
Luis Henriques a522a2
+		/*
Luis Henriques a522a2
+		 * If mds is importing cap, prior cap messages that update
Luis Henriques a522a2
+		 * 'wanted' may get dropped by mds (migrate seq mismatch).
Luis Henriques a522a2
+		 *
Luis Henriques a522a2
+		 * We don't send cap message to update 'wanted' if what we
Luis Henriques a522a2
+		 * want are already issued. If mds revokes caps, cap message
Luis Henriques a522a2
+		 * that releases caps also tells mds what we want. But if
Luis Henriques a522a2
+		 * caps got revoked by mds forcedly (session stale). We may
Luis Henriques a522a2
+		 * haven't told mds what we want.
Luis Henriques a522a2
+		 */
Luis Henriques a522a2
+		check_caps = 1;
Luis Henriques a522a2
 	}
Luis Henriques a522a2
 
Luis Henriques a522a2
 	/* revocation, grant, or no-op? */