Btrfs: fix race in check-integrity caused by usage of bitfield
[firefly-linux-kernel-4.4.55.git] / fs / btrfs / check-integrity.c
index 58dfac1359a32e29fdad40f7286166e4fa51c592..11d47bfb62b418f6f4d5459d8c02a18b05c3731b 100644 (file)
@@ -137,7 +137,7 @@ struct btrfsic_block {
        unsigned int never_written:1;   /* block was added because it was
                                         * referenced, not because it was
                                         * written */
-       unsigned int mirror_num:2;      /* large enough to hold
+       unsigned int mirror_num;        /* large enough to hold
                                         * BTRFS_SUPER_MIRROR_MAX */
        struct btrfsic_dev_state *dev_state;
        u64 dev_bytenr;         /* key, physical byte num on disk */
@@ -1582,9 +1582,21 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len,
        struct btrfs_device *device;
 
        length = len;
-       ret = btrfs_map_block(&state->root->fs_info->mapping_tree, READ,
+       ret = btrfs_map_block(state->root->fs_info, READ,
                              bytenr, &length, &multi, mirror_num);
 
+       if (ret) {
+               block_ctx_out->start = 0;
+               block_ctx_out->dev_bytenr = 0;
+               block_ctx_out->len = 0;
+               block_ctx_out->dev = NULL;
+               block_ctx_out->datav = NULL;
+               block_ctx_out->pagev = NULL;
+               block_ctx_out->mem_to_free = NULL;
+
+               return ret;
+       }
+
        device = multi->stripes[0].dev;
        block_ctx_out->dev = btrfsic_dev_state_lookup(device->bdev);
        block_ctx_out->dev_bytenr = multi->stripes[0].physical;
@@ -1594,8 +1606,7 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len,
        block_ctx_out->pagev = NULL;
        block_ctx_out->mem_to_free = NULL;
 
-       if (0 == ret)
-               kfree(multi);
+       kfree(multi);
        if (NULL == block_ctx_out->dev) {
                ret = -ENXIO;
                printk(KERN_INFO "btrfsic: error, cannot lookup dev (#1)!\n");