diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/cluster/ec/src/ec-common.c | 8 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec-data.c | 1 | 
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 200aedaa5b1..439773e1ac8 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);  | 
