diff --git a/include/linux/zio-trigger.h b/include/linux/zio-trigger.h
index 57d51cca216f5076ee755c976bea19400751add9..e50f26e0b39d36f0aaddcef74c3296b2ad029f36 100644
--- a/include/linux/zio-trigger.h
+++ b/include/linux/zio-trigger.h
@@ -70,7 +70,9 @@ void zio_fire_trigger(struct zio_ti *ti);
  * trigger. For output, data_done frees the blocks and prepares new
  * blocks if possible; for input, data_done pushes material to the buffers.
  * If the transfer must be interrupted before the invocation of data_done,
- * the abort function must be called.
+ * the abort function must be called. The abort function has two choice: it
+ * can invoke data_done and return partial blocks, or free all the active
+ * blocks.
  *
  * Then, a trigger instance is configured either by sysfs (and this means
  * the conf_set callback runs and the instance is notified) or by writing
diff --git a/zio-sys.c b/zio-sys.c
index 5aad6ccbd79d6e379bd967af62dd945f9e7069db..f0949aab33f4deec49492f754cd307dea8cb59cc 100644
--- a/zio-sys.c
+++ b/zio-sys.c
@@ -770,9 +770,13 @@ static void __zobj_enable(struct kobject *kobj, unsigned int enable,
 
 		ti = to_zio_ti(kobj);
 		/* if trigger is running, abort it*/
-		if (*flags & ZTI_BUSY)
+		spin_lock(&ti->cset->lock);
+		if (*flags & ZTI_BUSY) {
 			if(ti->t_op->abort)
 				ti->t_op->abort(ti->cset);
+			*flags &= ~ZTI_BUSY; /* when disabled is not busy */
+		}
+		spin_unlock(&ti->cset->lock);
 		/* trigger instance callback */
 		if (ti->t_op->change_status) {
 			pr_debug("%s:%d\n", __func__, __LINE__);