Merge branch 'v3.10/topic/misc' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / drivers / md / persistent-data / dm-space-map-metadata.c
index 58fc1eef7499e1923ef00095502c1e1b49f50ffb..afb419e514bf53f2ed1f1173c31471c5fac3e1f5 100644 (file)
@@ -608,20 +608,38 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
         * Flick into a mode where all blocks get allocated in the new area.
         */
        smm->begin = old_len;
-       memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
+       memcpy(sm, &bootstrap_ops, sizeof(*sm));
 
        /*
         * Extend.
         */
        r = sm_ll_extend(&smm->ll, extra_blocks);
+       if (r)
+               goto out;
 
        /*
-        * Switch back to normal behaviour.
+        * We repeatedly increment then commit until the commit doesn't
+        * allocate any new blocks.
         */
-       memcpy(&smm->sm, &ops, sizeof(smm->sm));
-       for (i = old_len; !r && i < smm->begin; i++)
-               r = sm_ll_inc(&smm->ll, i, &ev);
+       do {
+               for (i = old_len; !r && i < smm->begin; i++) {
+                       r = sm_ll_inc(&smm->ll, i, &ev);
+                       if (r)
+                               goto out;
+               }
+               old_len = smm->begin;
+
+               r = sm_ll_commit(&smm->ll);
+               if (r)
+                       goto out;
+
+       } while (old_len != smm->begin);
 
+out:
+       /*
+        * Switch back to normal behaviour.
+        */
+       memcpy(sm, &ops, sizeof(*sm));
        return r;
 }