summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoumya Koduri <skoduri@redhat.com>2018-10-29 14:41:26 +0530
committerShyamsundar Ranganathan <srangana@redhat.com>2018-12-12 12:53:10 +0000
commitf17188e4aa5e02d266cf147cf418e6cc27f5db21 (patch)
treea724112b11624885c04af12fdf85253dbe3dccb0
parent426e128b98f84d185a7d53ec36b9ad12a7facc40 (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#1651323 Signed-off-by: Soumya Koduri <skoduri@redhat.com> (cherry picked from commit c2e758b54d8a3f778e3e63db0000bb8b63de9b25)
-rw-r--r--tests/features/glfs-lease.c4
-rw-r--r--xlators/features/leases/src/leases-internal.c16
2 files changed, 16 insertions, 4 deletions
diff --git a/tests/features/glfs-lease.c b/tests/features/glfs-lease.c
index f781f46c4ca..e82cd875b38 100644
--- a/tests/features/glfs-lease.c
+++ b/tests/features/glfs-lease.c
@@ -262,7 +262,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);
@@ -285,7 +285,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 00fb670ff2a..2823ca5a262 100644
--- a/xlators/features/leases/src/leases-internal.c
+++ b/xlators/features/leases/src/leases-internal.c
@@ -624,17 +624,29 @@ __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));
+ /* 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 || !(lease_entry->lease_type & lease->lease_type)) {
+ 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);
+ 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;
}
-
lease_type = lease->lease_type;
lease_entry->lease_type_cnt[lease_type]--;
lease_entry->lease_cnt--;