diff --git a/buffers/zio-buf-kmalloc.c b/buffers/zio-buf-kmalloc.c
index 543f9ba9dd88b3e437df15ff363194e7a5f90aa7..72723c89d1d0cf658992d6b54ae2eb2e4818fedb 100644
--- a/buffers/zio-buf-kmalloc.c
+++ b/buffers/zio-buf-kmalloc.c
@@ -71,6 +71,13 @@ static struct zio_block *zbk_alloc_block(struct zio_bi *bi,
 
 	pr_debug("%s:%d\n", __func__, __LINE__);
 
+	/* alloc fails if we overflow the buffer size */
+	spin_lock(&bi->lock);
+	if (zbki->nitem >= bi->zattr_set.std_zattr[ZIO_ATTR_ZBUF_MAXLEN].value)
+		goto out_unlock;
+	zbki->nitem++;
+	spin_unlock(&bi->lock);
+
 	/* alloc item and data. Control remains null at this point */
 	item = kmem_cache_alloc(zbk_slab, gfp);
 	data = kmalloc(datalen, gfp);
@@ -88,6 +95,10 @@ out_free:
 	kfree(data);
 	kmem_cache_free(zbk_slab, item);
 	zio_free_control(ctrl);
+	spin_lock(&bi->lock);
+	zbki->nitem--;
+out_unlock:
+	spin_unlock(&bi->lock);
 	return NULL;
 }
 
@@ -96,14 +107,25 @@ static void zbk_free_block(struct zio_bi *bi, struct zio_block *block)
 {
 	struct zbk_item *item;
 	struct zbk_instance *zbki;
+	int awake = 0;
 
 	pr_debug("%s:%d\n", __func__, __LINE__);
 
 	item = to_item(block);
 	zbki = item->instance;
+
+	spin_lock(&bi->lock);
+	if ( ((bi->flags & ZIO_DIR) == ZIO_DIR_OUTPUT) &&
+	     zbki->nitem < bi->zattr_set.std_zattr[ZIO_ATTR_ZBUF_MAXLEN].value)
+		awake = 1;
+	zbki->nitem--;
+	spin_unlock(&bi->lock);
+
 	kfree(block->data);
 	zio_free_control(zio_get_ctrl(block));
 	kmem_cache_free(zbk_slab, item);
+	if (awake)
+		wake_up_interruptible(&bi->q);
 }
 
 /* When write() stores the first block, we try pushing it */
@@ -134,25 +156,17 @@ static int zbk_store_block(struct zio_bi *bi, struct zio_block *block)
 {
 	struct zbk_instance *zbki = to_zbki(bi);
 	struct zio_channel *chan = bi->chan;
-	struct zbk_item *item;
-	int awake = 0, pushed = 0, output;
+	struct zbk_item *item = to_item(block);
+	int awake = 0, pushed = 0, isempty;
+	int output = (bi->flags & ZIO_DIR) == ZIO_DIR_OUTPUT;
 
 	pr_debug("%s:%d (%p, %p)\n", __func__, __LINE__, bi, block);
 
-	if (unlikely(!zio_get_ctrl(block))) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	item = to_item(block);
-	output = (bi->flags & ZIO_DIR) == ZIO_DIR_OUTPUT;
-
 	/* add to the buffer instance or push to the trigger */
 	spin_lock(&bi->lock);
-	if (zbki->nitem >= bi->zattr_set.std_zattr[ZIO_ATTR_ZBUF_MAXLEN].value)
-		goto out_unlock;
+	isempty = list_empty(&zbki->list);
 	list_add_tail(&item->list, &zbki->list);
-	if (!zbki->nitem) {
+	if (isempty) {
 		if (unlikely(output))
 			pushed = __try_push(bi, chan, block);
 		else
@@ -160,17 +174,12 @@ static int zbk_store_block(struct zio_bi *bi, struct zio_block *block)
 	}
 	if (pushed)
 		list_del(&item->list);
-	zbki->nitem += !pushed;
 	spin_unlock(&bi->lock);
 
 	/* if first input, awake user space */
 	if (awake)
 		wake_up_interruptible(&bi->q);
 	return 0;
-
-out_unlock:
-	spin_unlock(&bi->lock);
-	return -ENOSPC;
 }
 
 /* Retr is called by f->read (for input) or by the trigger (for output) */
@@ -180,23 +189,17 @@ static struct zio_block *zbk_retr_block(struct zio_bi *bi)
 	struct zbk_instance *zbki;
 	struct zio_ti *ti;
 	struct list_head *first;
-	int awake = 0;
 
 	zbki = to_zbki(bi);
 
 	spin_lock(&bi->lock);
-	if (!zbki->nitem || bi->flags & ZIO_BI_PUSHING)
+	if (list_empty(&zbki->list) || bi->flags & ZIO_BI_PUSHING)
 		goto out_unlock;
 	first = zbki->list.next;
 	item = list_entry(first, struct zbk_item, list);
 	list_del(&item->list);
-	if (zbki->nitem == bi->zattr_set.std_zattr[ZIO_ATTR_ZBUF_MAXLEN].value)
-		awake = 1;
-	zbki->nitem--;
 	spin_unlock(&bi->lock);
 
-	if (awake && ((bi->flags & ZIO_DIR) == ZIO_DIR_OUTPUT))
-		wake_up_interruptible(&bi->q);
 	pr_debug("%s:%d (%p, %p)\n", __func__, __LINE__, bi, item);
 	return &item->block;