btrfs-progs: check the free space tree in btrfsck
[platform/upstream/btrfs-progs.git] / utils.c
diff --git a/utils.c b/utils.c
index 4f3fbba..03648db 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -154,7 +154,7 @@ int test_uuid_unique(char *fs_uuid)
        blkid_dev dev = NULL;
        blkid_cache cache = NULL;
 
-       if (blkid_get_cache(&cache, 0) < 0) {
+       if (blkid_get_cache(&cache, NULL) < 0) {
                printf("ERROR: lblkid cache get failed\n");
                return 1;
        }
@@ -552,12 +552,12 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
 
        /* and write out the super block */
        BUG_ON(sizeof(super) > cfg->sectorsize);
-       memset(buf->data, 0, cfg->sectorsize);
+       memset(buf->data, 0, BTRFS_SUPER_INFO_SIZE);
        memcpy(buf->data, &super, sizeof(super));
-       buf->len = cfg->sectorsize;
+       buf->len = BTRFS_SUPER_INFO_SIZE;
        csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
-       ret = pwrite(fd, buf->data, cfg->sectorsize, cfg->blocks[0]);
-       if (ret != cfg->sectorsize) {
+       ret = pwrite(fd, buf->data, BTRFS_SUPER_INFO_SIZE, cfg->blocks[0]);
+       if (ret != BTRFS_SUPER_INFO_SIZE) {
                ret = (ret < 0 ? -errno : -EIO);
                goto out;
        }
@@ -1180,19 +1180,25 @@ static int is_loop_device (const char* device) {
 static int resolve_loop_device_with_loopdev(const char* loop_dev, char* loop_file)
 {
        int fd;
+       int ret;
        struct loop_info64 lo64;
 
        fd = open(loop_dev, O_RDONLY | O_NONBLOCK);
        if (fd < 0)
                return -errno;
-       if (ioctl(fd, LOOP_GET_STATUS64, &lo64) < 0)
-               return -errno;
+       ret = ioctl(fd, LOOP_GET_STATUS64, &lo64);
+       if (ret < 0) {
+               ret = -errno;
+               goto out;
+       }
 
-       memcpy(loop_file, lo64.lo_file_name, strlen(lo64.lo_file_name) + 1);
-       if (close(fd) < 0)
-               return -errno;
+       memcpy(loop_file, lo64.lo_file_name, sizeof(lo64.lo_file_name));
+       loop_file[sizeof(lo64.lo_file_name)] = 0;
 
-       return 0;
+out:
+       close(fd);
+
+       return ret;
 }
 
 /* Takes a loop device path (e.g. /dev/loop0) and returns
@@ -2457,7 +2463,7 @@ static int group_profile_devs_min(u64 flag)
 }
 
 int test_num_disk_vs_raid(u64 metadata_profile, u64 data_profile,
-       u64 dev_cnt, int mixed)
+       u64 dev_cnt, int mixed, int ssd)
 {
        u64 allowed = 0;
 
@@ -2498,11 +2504,9 @@ int test_num_disk_vs_raid(u64 metadata_profile, u64 data_profile,
                return 1;
        }
 
-       if (!mixed && (data_profile & BTRFS_BLOCK_GROUP_DUP)) {
-               fprintf(stderr,
-                       "ERROR: DUP for data is allowed only in mixed mode\n");
-               return 1;
-       }
+       warning_on(!mixed && (data_profile & BTRFS_BLOCK_GROUP_DUP) && ssd,
+                  "DUP may not actually lead to 2 copies on the device, see manual page");
+
        return 0;
 }
 
@@ -2597,7 +2601,7 @@ int btrfs_scan_lblkid(void)
        if (btrfs_scan_done)
                return 0;
 
-       if (blkid_get_cache(&cache, 0) < 0) {
+       if (blkid_get_cache(&cache, NULL) < 0) {
                printf("ERROR: lblkid cache get failed\n");
                return 1;
        }