summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoumya Koduri <skoduri@redhat.com>2018-10-29 14:41:26 +0530
committerSoumya Koduri <skoduri@redhat.com>2019-01-03 15:08:16 +0530
commit1651c8c3546777ef3072ae83127f5aa47bb160b5 (patch)
treed54c49158e7caa5409c632666ad6a6a1748f6390
parente33a97ea1aa23222c5f9e5ccbd52d4cb682e9c09 (diff)
lease: Treat unlk request as noop if lease not found
When the glusterfs server recalls the lease, it expects client to flush data and unlock the lease. If not it sets a timer (starting from the time it sends RECALL request) and post timeout, it revokes it. Here we could have a race where in client did send UNLK lease request but because of network delay it may have reached after server revokes it. To handle such situations, treat such requests as noop and return sucesss. Change-Id: I166402d10273f4f115ff04030ecbc14676a01663 updates: bz#1655532 Signed-off-by: Soumya Koduri <skoduri@redhat.com>
-rw-r--r--tests/features/glfs-lease.c4
-rw-r--r--xlators/features/leases/src/leases-internal.c23
2 files changed, 21 insertions, 6 deletions
diff --git a/tests/features/glfs-lease.c b/tests/features/glfs-lease.c
index 1a375ecbeb3..7255770912f 100644
--- a/tests/features/glfs-lease.c
+++ b/tests/features/glfs-lease.c
@@ -247,7 +247,7 @@ testcase1_rd_lease ()
VERIFY_RESULT (6, ret, NONE);
ret = unlk_read_lease (fd1, lid1);
- VERIFY_RESULT (7, ret, SHUD_FAIL);
+ VERIFY_RESULT (7, ret, SHUD_PASS);
ret = glfs_close (fd1);
VERIFY_RESULT (8, ret, SHUD_PASS);
@@ -270,7 +270,7 @@ testcase2_wr_lease ()
VERIFY_RESULT (1, ret, SHUD_FAIL);
ret = unlk_write_lease (fd1, lid1);
- VERIFY_RESULT (2, ret, SHUD_FAIL);
+ VERIFY_RESULT (2, ret, SHUD_PASS);
ret = set_write_lease (fd1, lid1);
VERIFY_RESULT (3, ret, SHUD_PASS);
diff --git a/xlators/features/leases/src/leases-internal.c b/xlators/features/leases/src/leases-internal.c
index 7202743c74b..a4820ec481b 100644
--- a/xlators/features/leases/src/leases-internal.c
+++ b/xlators/features/leases/src/leases-internal.c
@@ -641,11 +641,26 @@ __remove_lease (xlator_t *this, inode_t *inode, lease_inode_ctx_t *lease_ctx,
"lease type:%d, lease id:%s", client_uid, lease->lease_type,
leaseid_utoa (lease->lease_id));
- lease_entry = __get_lease_id_entry (lease_ctx, lease->lease_id);
- if (!lease_entry || !(lease_entry->lease_type & lease->lease_type)) {
- gf_msg (this->name, GF_LOG_INFO, 0, LEASE_MSG_INVAL_UNLK_LEASE,
+
+ /* There could be a race where in server recalled the lease and by the time
+ * client sends lease_unlock request, server may have revoked it. To handle
+ * such cases, if lease doesnt exist treat it as noop and return success.
+ */
+ lease_entry = __get_lease_id_entry(lease_ctx, lease->lease_id);
+ if (!lease_entry) {
+ gf_msg(this->name, GF_LOG_INFO, 0, LEASE_MSG_INVAL_UNLK_LEASE,
"Got unlock lease request from client:%s, but has no "
- "corresponding lock", client_uid);
+ "corresponding lock",
+ client_uid);
+ ret = 0;
+ goto out;
+ }
+
+ if (!(lease_entry->lease_type & lease->lease_type)) {
+ gf_msg(this->name, GF_LOG_INFO, 0, LEASE_MSG_INVAL_UNLK_LEASE,
+ "Got unlock lease request from client:%s for an invalid "
+ "lease_type",
+ client_uid);
ret = -EINVAL;
errno = EINVAL;
goto out;