summaryrefslogtreecommitdiffstats
path: root/xlators/cluster
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster')
-rw-r--r--xlators/cluster/ec/src/ec-common.c8
-rw-r--r--xlators/cluster/ec/src/ec-data.c1
2 files changed, 9 insertions, 0 deletions
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
index 8d1196dd0c3..41adbb4c508 100644
--- a/xlators/cluster/ec/src/ec-common.c
+++ b/xlators/cluster/ec/src/ec-common.c
@@ -244,6 +244,7 @@ void ec_sleep(ec_fop_data_t *fop)
{
LOCK(&fop->lock);
+ GF_ASSERT (fop->refs > 0);
fop->refs++;
fop->jobs++;
@@ -1319,6 +1320,12 @@ void ec_lock(ec_fop_data_t *fop)
ec_lock_link_t *timer_link = NULL;
ec_lock_t *lock;
+ /* There is a chance that ec_resume is called on fop even before ec_sleep.
+ * Which can result in refs == 0 for fop leading to use after free in this
+ * function when it calls ec_sleep so do ec_sleep at start and ec_resume at
+ * the end of this function.*/
+ ec_sleep (fop);
+
while (fop->locked < fop->lock_count) {
/* Since there are only up to 2 locks per fop, this xor will change
* the order of the locks if fop->first_lock is 1. */
@@ -1383,6 +1390,7 @@ void ec_lock(ec_fop_data_t *fop)
timer_link = NULL;
}
}
+ ec_resume (fop, 0);
if (timer_link != NULL) {
ec_resume(timer_link->fop, 0);
diff --git a/xlators/cluster/ec/src/ec-data.c b/xlators/cluster/ec/src/ec-data.c
index 2a34f78999c..78c505cc704 100644
--- a/xlators/cluster/ec/src/ec-data.c
+++ b/xlators/cluster/ec/src/ec-data.c
@@ -258,6 +258,7 @@ void ec_fop_data_release(ec_fop_data_t * fop)
ec_trace("RELEASE", fop, "");
+ GF_ASSERT (fop->refs > 0);
refs = --fop->refs;
UNLOCK(&fop->lock);