summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorPranith Kumar K <pkarampu@redhat.com>2018-01-31 22:10:46 +0530
committerShyamsundar Ranganathan <srangana@redhat.com>2018-02-02 15:05:01 +0000
commitd1e091cb9dd4e69323138641c41bda28e333f50a (patch)
tree4de47728414d7f76f5bd79ac3e01809fbe15e7f8 /xlators
parente31a697c28dfc36748f7551428b97a863fba3968 (diff)
cluster/ec: Do lock conflict check correctly for wait-list
Problem: ec_link_has_lock_conflict() is traversing over only owner_list but the function is also getting called with wait_list. Fix: Modify ec_link_has_lock_conflict() to traverse lists correctly. Updated the callers to reflect the changes. BUG: 1540896 Change-Id: Ibd7ea10f4498e7c2761f9a6faac6d5cb7d750c91 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/cluster/ec/src/ec-common.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
index 2cb640e455c..63d7c0ec919 100644
--- a/xlators/cluster/ec/src/ec-common.c
+++ b/xlators/cluster/ec/src/ec-common.c
@@ -1648,18 +1648,27 @@ ec_lock_update_fd(ec_lock_t *lock, ec_fop_data_t *fop)
}
static gf_boolean_t
-ec_link_has_lock_conflict (ec_lock_link_t *link, struct list_head *owners)
+ec_link_has_lock_conflict (ec_lock_link_t *link, gf_boolean_t waitlist_check)
{
- ec_lock_link_t *owner_link = NULL;
+ ec_lock_link_t *trav_link = NULL;
ec_t *ec = link->fop->xl->private;
if (!ec->parallel_writes)
return _gf_true;
- list_for_each_entry (owner_link, owners, owner_list) {
- if (ec_lock_conflict (owner_link, link))
+ list_for_each_entry (trav_link, &link->lock->owners, owner_list) {
+ if (ec_lock_conflict (trav_link, link))
return _gf_true;
}
+
+ if (!waitlist_check)
+ return _gf_false;
+
+ list_for_each_entry (trav_link, &link->lock->waiting, wait_list) {
+ if (ec_lock_conflict (trav_link, link))
+ return _gf_true;
+ }
+
return _gf_false;
}
@@ -1681,7 +1690,7 @@ ec_lock_wake_shared(ec_lock_t *lock, struct list_head *list)
/* If the fop is not shareable, only this fop can be assigned as owner.
* Other fops will need to wait until this one finishes. */
- if (ec_link_has_lock_conflict (link, &lock->owners)) {
+ if (ec_link_has_lock_conflict (link, _gf_false)) {
conflict = _gf_true;
}
@@ -1928,9 +1937,7 @@ ec_lock_assign_owner(ec_lock_link_t *link)
* owners, or waiters(to prevent starvation).
* Otherwise we need to wait.
*/
- if (!lock->acquired ||
- ec_link_has_lock_conflict (link, &lock->owners) ||
- ec_link_has_lock_conflict (link, &lock->waiting)) {
+ if (!lock->acquired || ec_link_has_lock_conflict (link, _gf_true)) {
ec_trace("LOCK_QUEUE_WAIT", fop, "lock=%p", lock);
list_add_tail(&link->wait_list, &lock->waiting);