btrfs-progs: mkfs: Enhance minimal device size calculation to fix mkfs failure on...
[platform/upstream/btrfs-progs.git] / mkfs / main.c
index 284dbd7..90fab59 100644 (file)
@@ -1073,6 +1073,19 @@ static int make_image(const char *source_dir, struct btrfs_root *root)
                printf("Making image is completed.\n");
        return 0;
 fail:
+       /*
+        * Since we don't have btrfs_abort_transaction() yet, uncommitted trans
+        * will trigger a BUG_ON().
+        *
+        * However before mkfs is fully finished, the magic number is invalid,
+        * so even we commit transaction here, the fs still can't be mounted.
+        *
+        * To do a graceful error out, here we commit transaction as a
+        * workaround.
+        * Since we have already hit some problem, the return value doesn't
+        * matter now.
+        */
+       btrfs_commit_transaction(trans, root);
        while (!list_empty(&dir_head.list)) {
                dir_entry = list_entry(dir_head.list.next,
                                       struct directory_name_entry, list);
@@ -1440,6 +1453,7 @@ int main(int argc, char **argv)
        u64 num_of_meta_chunks = 0;
        u64 size_of_data = 0;
        u64 source_dir_size = 0;
+       u64 min_dev_size;
        int dev_cnt = 0;
        int saved_optind;
        char fs_uuid[BTRFS_UUID_UNPARSED_SIZE] = { 0 };
@@ -1584,8 +1598,12 @@ int main(int argc, char **argv)
        while (dev_cnt-- > 0) {
                file = argv[optind++];
                if (is_block_device(file) == 1)
-                       if (test_dev_for_mkfs(file, force_overwrite))
-                               goto error;
+                       ret = test_dev_for_mkfs(file, force_overwrite);
+               else
+                       ret = test_status_for_mkfs(file, force_overwrite);
+
+               if (ret)
+                       goto error;
        }
 
        optind = saved_optind;
@@ -1650,19 +1668,21 @@ int main(int argc, char **argv)
                goto error;
        }
 
+       min_dev_size = btrfs_min_dev_size(nodesize, mixed, metadata_profile,
+                                         data_profile);
        /* Check device/block_count after the nodesize is determined */
-       if (block_count && block_count < btrfs_min_dev_size(nodesize)) {
+       if (block_count && block_count < min_dev_size) {
                error("size %llu is too small to make a usable filesystem",
                        block_count);
                error("minimum size for btrfs filesystem is %llu",
-                       btrfs_min_dev_size(nodesize));
+                       min_dev_size);
                goto error;
        }
        for (i = saved_optind; i < saved_optind + dev_cnt; i++) {
                char *path;
 
                path = argv[i];
-               ret = test_minimum_size(path, nodesize);
+               ret = test_minimum_size(path, min_dev_size);
                if (ret < 0) {
                        error("failed to check size for %s: %s",
                                path, strerror(-ret));
@@ -1672,7 +1692,7 @@ int main(int argc, char **argv)
                        error("'%s' is too small to make a usable filesystem",
                                path);
                        error("minimum size for each btrfs device is %llu",
-                               btrfs_min_dev_size(nodesize));
+                               min_dev_size);
                        goto error;
                }
        }