These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / md / persistent-data / dm-space-map-metadata.c
index e8a9042..7e44005 100644 (file)
@@ -136,7 +136,7 @@ static int brb_push(struct bop_ring_buffer *brb,
        return 0;
 }
 
-static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
+static int brb_peek(struct bop_ring_buffer *brb, struct block_op *result)
 {
        struct block_op *bop;
 
@@ -147,6 +147,14 @@ static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
        result->type = bop->type;
        result->block = bop->block;
 
+       return 0;
+}
+
+static int brb_pop(struct bop_ring_buffer *brb)
+{
+       if (brb_empty(brb))
+               return -ENODATA;
+
        brb->begin = brb_next(brb, brb->begin);
 
        return 0;
@@ -204,6 +212,29 @@ static void in(struct sm_metadata *smm)
        smm->recursion_count++;
 }
 
+static int apply_bops(struct sm_metadata *smm)
+{
+       int r = 0;
+
+       while (!brb_empty(&smm->uncommitted)) {
+               struct block_op bop;
+
+               r = brb_peek(&smm->uncommitted, &bop);
+               if (r) {
+                       DMERR("bug in bop ring buffer");
+                       break;
+               }
+
+               r = commit_bop(smm, &bop);
+               if (r)
+                       break;
+
+               brb_pop(&smm->uncommitted);
+       }
+
+       return r;
+}
+
 static int out(struct sm_metadata *smm)
 {
        int r = 0;
@@ -216,21 +247,8 @@ static int out(struct sm_metadata *smm)
                return -ENOMEM;
        }
 
-       if (smm->recursion_count == 1) {
-               while (!brb_empty(&smm->uncommitted)) {
-                       struct block_op bop;
-
-                       r = brb_pop(&smm->uncommitted, &bop);
-                       if (r) {
-                               DMERR("bug in bop ring buffer");
-                               break;
-                       }
-
-                       r = commit_bop(smm, &bop);
-                       if (r)
-                               break;
-               }
-       }
+       if (smm->recursion_count == 1)
+               apply_bops(smm);
 
        smm->recursion_count--;
 
@@ -675,7 +693,6 @@ static struct dm_space_map bootstrap_ops = {
 static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
 {
        int r, i;
-       enum allocation_event ev;
        struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
        dm_block_t old_len = smm->ll.nr_blocks;
 
@@ -697,13 +714,20 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
         * allocate any new blocks.
         */
        do {
-               for (i = old_len; !r && i < smm->begin; i++) {
-                       r = sm_ll_inc(&smm->ll, i, &ev);
-                       if (r)
-                               goto out;
-               }
+               for (i = old_len; !r && i < smm->begin; i++)
+                       r = add_bop(smm, BOP_INC, i);
+
+               if (r)
+                       goto out;
+
                old_len = smm->begin;
 
+               r = apply_bops(smm);
+               if (r) {
+                       DMERR("%s: apply_bops failed", __func__);
+                       goto out;
+               }
+
                r = sm_ll_commit(&smm->ll);
                if (r)
                        goto out;
@@ -740,7 +764,6 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
 {
        int r;
        dm_block_t i;
-       enum allocation_event ev;
        struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
 
        smm->begin = superblock + 1;
@@ -768,11 +791,17 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
         * allocated blocks that they were built from.
         */
        for (i = superblock; !r && i < smm->begin; i++)
-               r = sm_ll_inc(&smm->ll, i, &ev);
+               r = add_bop(smm, BOP_INC, i);
 
        if (r)
                return r;
 
+       r = apply_bops(smm);
+       if (r) {
+               DMERR("%s: apply_bops failed", __func__);
+               return r;
+       }
+
        return sm_metadata_commit(sm);
 }