]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/btrfs/volumes.c
btrfs: sysfs: check initialization state before updating features
[mirror_ubuntu-bionic-kernel.git] / fs / btrfs / volumes.c
index a6df8fdc1312ce78e97f9f90037ff5b236a58a92..5b505f61929e3141b799f9798a79eaba9b18466e 100644 (file)
@@ -108,7 +108,7 @@ const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
        },
 };
 
-const u64 const btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
+const u64 btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
        [BTRFS_RAID_RAID10] = BTRFS_BLOCK_GROUP_RAID10,
        [BTRFS_RAID_RAID1]  = BTRFS_BLOCK_GROUP_RAID1,
        [BTRFS_RAID_DUP]    = BTRFS_BLOCK_GROUP_DUP,
@@ -125,6 +125,7 @@ static int btrfs_relocate_sys_chunks(struct btrfs_root *root);
 static void __btrfs_reset_dev_stats(struct btrfs_device *dev);
 static void btrfs_dev_stat_print_on_error(struct btrfs_device *dev);
 static void btrfs_dev_stat_print_on_load(struct btrfs_device *device);
+static void btrfs_close_one_device(struct btrfs_device *device);
 
 DEFINE_MUTEX(uuid_mutex);
 static LIST_HEAD(fs_uuids);
@@ -232,6 +233,7 @@ static struct btrfs_device *__alloc_device(void)
        spin_lock_init(&dev->reada_lock);
        atomic_set(&dev->reada_in_flight, 0);
        atomic_set(&dev->dev_stats_ccnt, 0);
+       btrfs_device_data_ordered_init(dev);
        INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
        INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
 
@@ -1102,7 +1104,7 @@ int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start,
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
-       path->reada = 2;
+       path->reada = READA_FORWARD;
 
        key.objectid = device->devid;
        key.offset = start;
@@ -1182,7 +1184,7 @@ again:
                struct map_lookup *map;
                int i;
 
-               map = (struct map_lookup *)em->bdev;
+               map = em->map_lookup;
                for (i = 0; i < map->num_stripes; i++) {
                        u64 end;
 
@@ -1257,6 +1259,15 @@ int find_free_dev_extent_start(struct btrfs_transaction *transaction,
        int ret;
        int slot;
        struct extent_buffer *l;
+       u64 min_search_start;
+
+       /*
+        * We don't want to overwrite the superblock on the drive nor any area
+        * used by the boot loader (grub for example), so we make sure to start
+        * at an offset of at least 1MB.
+        */
+       min_search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
+       search_start = max(search_start, min_search_start);
 
        path = btrfs_alloc_path();
        if (!path)
@@ -1271,7 +1282,7 @@ again:
                goto out;
        }
 
-       path->reada = 2;
+       path->reada = READA_FORWARD;
        path->search_commit_root = 1;
        path->skip_locking = 1;
 
@@ -1397,18 +1408,9 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans,
                         struct btrfs_device *device, u64 num_bytes,
                         u64 *start, u64 *len)
 {
-       struct btrfs_root *root = device->dev_root;
-       u64 search_start;
-
        /* FIXME use last free of some kind */
-
-       /*
-        * we don't want to overwrite the superblock on the drive,
-        * so we make sure to start at an offset of at least 1MB
-        */
-       search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
        return find_free_dev_extent_start(trans->transaction, device,
-                                         num_bytes, search_start, start, len);
+                                         num_bytes, 0, start, len);
 }
 
 static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
@@ -1642,7 +1644,6 @@ static void update_dev_time(char *path_name)
                return;
        file_update_time(filp);
        filp_close(filp, NULL);
-       return;
 }
 
 static int btrfs_rm_dev_item(struct btrfs_root *root,
@@ -1973,8 +1974,7 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
        if (srcdev->writeable) {
                fs_devices->rw_devices--;
                /* zero out the old super if it is writable */
-               btrfs_scratch_superblocks(srcdev->bdev,
-                                       rcu_str_deref(srcdev->name));
+               btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str);
        }
 
        if (srcdev->bdev)
@@ -2024,8 +2024,7 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
        btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev);
 
        if (tgtdev->bdev) {
-               btrfs_scratch_superblocks(tgtdev->bdev,
-                                       rcu_str_deref(tgtdev->name));
+               btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str);
                fs_info->fs_devices->open_devices--;
        }
        fs_info->fs_devices->num_devices--;
@@ -2757,7 +2756,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
                        free_extent_map(em);
                return -EINVAL;
        }
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        lock_chunks(root->fs_info->chunk_root);
        check_system_chunk(trans, extent_root, map->type);
        unlock_chunks(root->fs_info->chunk_root);
@@ -2853,7 +2852,8 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
        if (ret)
                return ret;
 
-       trans = btrfs_start_transaction(root, 0);
+       trans = btrfs_start_trans_remove_block_group(root->fs_info,
+                                                    chunk_offset);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
                btrfs_std_error(root->fs_info, ret, NULL);
@@ -3123,7 +3123,7 @@ static int chunk_profiles_filter(u64 chunk_type,
        return 1;
 }
 
-static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
+static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
                              struct btrfs_balance_args *bargs)
 {
        struct btrfs_block_group_cache *cache;
@@ -3156,7 +3156,7 @@ static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
        return ret;
 }
 
-static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info,
+static int chunk_usage_filter(struct btrfs_fs_info *fs_info,
                u64 chunk_offset, struct btrfs_balance_args *bargs)
 {
        struct btrfs_block_group_cache *cache;
@@ -3407,7 +3407,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
        list_for_each_entry(device, devices, dev_list) {
                old_size = btrfs_device_get_total_bytes(device);
                size_to_free = div_factor(old_size, 1);
-               size_to_free = min(size_to_free, (u64)1 * 1024 * 1024);
+               size_to_free = min_t(u64, size_to_free, SZ_1M);
                if (!device->writeable ||
                    btrfs_device_get_total_bytes(device) -
                    btrfs_device_get_bytes_used(device) > size_to_free ||
@@ -3549,12 +3549,11 @@ again:
 
                        ret = btrfs_force_chunk_alloc(trans, chunk_root,
                                                      BTRFS_BLOCK_GROUP_DATA);
+                       btrfs_end_transaction(trans, chunk_root);
                        if (ret < 0) {
                                mutex_unlock(&fs_info->delete_unused_bgs_mutex);
                                goto error;
                        }
-
-                       btrfs_end_transaction(trans, chunk_root);
                        chunk_reserved = 1;
                }
 
@@ -3725,14 +3724,6 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
                goto out;
        }
 
-       /* allow dup'ed data chunks only in mixed mode */
-       if (!mixed && (bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
-           (bctl->data.target & BTRFS_BLOCK_GROUP_DUP)) {
-               btrfs_err(fs_info, "dup for data is not allowed");
-               ret = -EINVAL;
-               goto out;
-       }
-
        /* allow to reduce meta or sys integrity only if force set */
        allowed = BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1 |
                        BTRFS_BLOCK_GROUP_RAID10 |
@@ -3758,6 +3749,13 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
                }
        } while (read_seqretry(&fs_info->profiles_lock, seq));
 
+       if (btrfs_get_num_tolerated_disk_barrier_failures(bctl->meta.target) <
+               btrfs_get_num_tolerated_disk_barrier_failures(bctl->data.target)) {
+               btrfs_warn(fs_info,
+       "metadata profile 0x%llx has lower redundancy than data profile 0x%llx",
+                       bctl->meta.target, bctl->data.target);
+       }
+
        if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
                fs_info->num_tolerated_disk_barrier_failures = min(
                        btrfs_calc_num_tolerated_disk_barrier_failures(fs_info),
@@ -4270,7 +4268,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
        if (!path)
                return -ENOMEM;
 
-       path->reada = 2;
+       path->reada = READA_FORWARD;
 
        lock_chunks(root);
 
@@ -4462,7 +4460,7 @@ static int btrfs_cmp_device_info(const void *a, const void *b)
 static u32 find_raid56_stripe_len(u32 data_devices, u32 dev_stripe_target)
 {
        /* TODO allow them to set a preferred stripe size */
-       return 64 * 1024;
+       return SZ_64K;
 }
 
 static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type)
@@ -4471,6 +4469,8 @@ static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type)
                return;
 
        btrfs_set_fs_incompat(info, RAID56);
+       btrfs_sysfs_feature_update(info, BTRFS_FEATURE_INCOMPAT_RAID56,
+               FEAT_INCOMPAT);
 }
 
 #define BTRFS_MAX_DEVS(r) ((BTRFS_LEAF_DATA_SIZE(r)            \
@@ -4530,21 +4530,21 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
        ncopies = btrfs_raid_array[index].ncopies;
 
        if (type & BTRFS_BLOCK_GROUP_DATA) {
-               max_stripe_size = 1024 * 1024 * 1024;
+               max_stripe_size = SZ_1G;
                max_chunk_size = 10 * max_stripe_size;
                if (!devs_max)
                        devs_max = BTRFS_MAX_DEVS(info->chunk_root);
        } else if (type & BTRFS_BLOCK_GROUP_METADATA) {
                /* for larger filesystems, use larger metadata chunks */
-               if (fs_devices->total_rw_bytes > 50ULL * 1024 * 1024 * 1024)
-                       max_stripe_size = 1024 * 1024 * 1024;
+               if (fs_devices->total_rw_bytes > 50ULL * SZ_1G)
+                       max_stripe_size = SZ_1G;
                else
-                       max_stripe_size = 256 * 1024 * 1024;
+                       max_stripe_size = SZ_256M;
                max_chunk_size = max_stripe_size;
                if (!devs_max)
                        devs_max = BTRFS_MAX_DEVS(info->chunk_root);
        } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) {
-               max_stripe_size = 32 * 1024 * 1024;
+               max_stripe_size = SZ_32M;
                max_chunk_size = 2 * max_stripe_size;
                if (!devs_max)
                        devs_max = BTRFS_MAX_DEVS_SYS_CHUNK;
@@ -4721,7 +4721,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                goto error;
        }
        set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
-       em->bdev = (struct block_device *)map;
+       em->map_lookup = map;
        em->start = start;
        em->len = num_bytes;
        em->block_start = 0;
@@ -4795,7 +4795,7 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
        u64 dev_offset;
        u64 stripe_size;
        int i = 0;
-       int ret;
+       int ret = 0;
 
        em_tree = &extent_root->fs_info->mapping_tree.map_tree;
        read_lock(&em_tree->lock);
@@ -4816,7 +4816,7 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
                return -EINVAL;
        }
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        item_size = btrfs_chunk_item_size(map->num_stripes);
        stripe_size = em->orig_block_len;
 
@@ -4826,20 +4826,32 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
                goto out;
        }
 
+       /*
+        * Take the device list mutex to prevent races with the final phase of
+        * a device replace operation that replaces the device object associated
+        * with the map's stripes, because the device object's id can change
+        * at any time during that final phase of the device replace operation
+        * (dev-replace.c:btrfs_dev_replace_finishing()).
+        */
+       mutex_lock(&chunk_root->fs_info->fs_devices->device_list_mutex);
        for (i = 0; i < map->num_stripes; i++) {
                device = map->stripes[i].dev;
                dev_offset = map->stripes[i].physical;
 
                ret = btrfs_update_device(trans, device);
                if (ret)
-                       goto out;
+                       break;
                ret = btrfs_alloc_dev_extent(trans, device,
                                             chunk_root->root_key.objectid,
                                             BTRFS_FIRST_CHUNK_TREE_OBJECTID,
                                             chunk_offset, dev_offset,
                                             stripe_size);
                if (ret)
-                       goto out;
+                       break;
+       }
+       if (ret) {
+               mutex_unlock(&chunk_root->fs_info->fs_devices->device_list_mutex);
+               goto out;
        }
 
        stripe = &chunk->stripe;
@@ -4852,6 +4864,7 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
                memcpy(stripe->dev_uuid, device->uuid, BTRFS_UUID_SIZE);
                stripe++;
        }
+       mutex_unlock(&chunk_root->fs_info->fs_devices->device_list_mutex);
 
        btrfs_set_stack_chunk_length(chunk, chunk_size);
        btrfs_set_stack_chunk_owner(chunk, extent_root->root_key.objectid);
@@ -4958,7 +4971,7 @@ int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset)
        if (!em)
                return 1;
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        for (i = 0; i < map->num_stripes; i++) {
                if (map->stripes[i].dev->missing) {
                        miss_ndevs++;
@@ -5038,7 +5051,7 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
                return 1;
        }
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        if (map->type & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1))
                ret = map->num_stripes;
        else if (map->type & BTRFS_BLOCK_GROUP_RAID10)
@@ -5074,7 +5087,7 @@ unsigned long btrfs_full_stripe_len(struct btrfs_root *root,
        BUG_ON(!em);
 
        BUG_ON(em->start > logical || em->start + em->len < logical);
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
                len = map->stripe_len * nr_data_stripes(map);
        free_extent_map(em);
@@ -5095,7 +5108,7 @@ int btrfs_is_parity_mirror(struct btrfs_mapping_tree *map_tree,
        BUG_ON(!em);
 
        BUG_ON(em->start > logical || em->start + em->len < logical);
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
                ret = 1;
        free_extent_map(em);
@@ -5254,7 +5267,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                return -EINVAL;
        }
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        offset = logical - em->start;
 
        stripe_len = map->stripe_len;
@@ -5368,35 +5381,33 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                 * target drive.
                 */
                for (i = 0; i < tmp_num_stripes; i++) {
-                       if (tmp_bbio->stripes[i].dev->devid == srcdev_devid) {
-                               /*
-                                * In case of DUP, in order to keep it
-                                * simple, only add the mirror with the
-                                * lowest physical address
-                                */
-                               if (found &&
-                                   physical_of_found <=
-                                    tmp_bbio->stripes[i].physical)
-                                       continue;
-                               index_srcdev = i;
-                               found = 1;
-                               physical_of_found =
-                                       tmp_bbio->stripes[i].physical;
-                       }
+                       if (tmp_bbio->stripes[i].dev->devid != srcdev_devid)
+                               continue;
+
+                       /*
+                        * In case of DUP, in order to keep it simple, only add
+                        * the mirror with the lowest physical address
+                        */
+                       if (found &&
+                           physical_of_found <= tmp_bbio->stripes[i].physical)
+                               continue;
+
+                       index_srcdev = i;
+                       found = 1;
+                       physical_of_found = tmp_bbio->stripes[i].physical;
                }
 
-               if (found) {
-                       mirror_num = index_srcdev + 1;
-                       patch_the_first_stripe_for_dev_replace = 1;
-                       physical_to_patch_in_first_stripe = physical_of_found;
-               } else {
+               btrfs_put_bbio(tmp_bbio);
+
+               if (!found) {
                        WARN_ON(1);
                        ret = -EIO;
-                       btrfs_put_bbio(tmp_bbio);
                        goto out;
                }
 
-               btrfs_put_bbio(tmp_bbio);
+               mirror_num = index_srcdev + 1;
+               patch_the_first_stripe_for_dev_replace = 1;
+               physical_to_patch_in_first_stripe = physical_of_found;
        } else if (mirror_num > map->num_stripes) {
                mirror_num = 0;
        }
@@ -5796,7 +5807,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
                free_extent_map(em);
                return -EIO;
        }
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
 
        length = em->len;
        rmap_len = map->stripe_len;
@@ -6059,7 +6070,8 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
        bbio->fs_info = root->fs_info;
        atomic_set(&bbio->stripes_pending, bbio->num_stripes);
 
-       if (bbio->raid_map) {
+       if ((bbio->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK) &&
+           ((rw & WRITE) || (mirror_num > 1))) {
                /* In this case, map_length has been set to the length of
                   a single stripe; not the whole write */
                if (rw & WRITE) {
@@ -6200,6 +6212,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
        struct extent_map *em;
        u64 logical;
        u64 length;
+       u64 stripe_len;
        u64 devid;
        u8 uuid[BTRFS_UUID_SIZE];
        int num_stripes;
@@ -6208,6 +6221,37 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
 
        logical = key->offset;
        length = btrfs_chunk_length(leaf, chunk);
+       stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
+       num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
+       /* Validation check */
+       if (!num_stripes) {
+               btrfs_err(root->fs_info, "invalid chunk num_stripes: %u",
+                         num_stripes);
+               return -EIO;
+       }
+       if (!IS_ALIGNED(logical, root->sectorsize)) {
+               btrfs_err(root->fs_info,
+                         "invalid chunk logical %llu", logical);
+               return -EIO;
+       }
+       if (!length || !IS_ALIGNED(length, root->sectorsize)) {
+               btrfs_err(root->fs_info,
+                       "invalid chunk length %llu", length);
+               return -EIO;
+       }
+       if (!is_power_of_2(stripe_len)) {
+               btrfs_err(root->fs_info, "invalid chunk stripe length: %llu",
+                         stripe_len);
+               return -EIO;
+       }
+       if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) &
+           btrfs_chunk_type(leaf, chunk)) {
+               btrfs_err(root->fs_info, "unrecognized chunk type: %llu",
+                         ~(BTRFS_BLOCK_GROUP_TYPE_MASK |
+                           BTRFS_BLOCK_GROUP_PROFILE_MASK) &
+                         btrfs_chunk_type(leaf, chunk));
+               return -EIO;
+       }
 
        read_lock(&map_tree->map_tree.lock);
        em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
@@ -6224,7 +6268,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
        em = alloc_extent_map();
        if (!em)
                return -ENOMEM;
-       num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
        map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS);
        if (!map) {
                free_extent_map(em);
@@ -6232,7 +6275,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
        }
 
        set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
-       em->bdev = (struct block_device *)map;
+       em->map_lookup = map;
        em->start = logical;
        em->len = length;
        em->orig_start = 0;
@@ -6467,11 +6510,11 @@ int btrfs_read_sys_array(struct btrfs_root *root)
        sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET);
        if (!sb)
                return -ENOMEM;
-       btrfs_set_buffer_uptodate(sb);
+       set_extent_buffer_uptodate(sb);
        btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0);
        /*
         * The sb extent buffer is artifical and just used to read the system array.
-        * btrfs_set_buffer_uptodate() call does not properly mark all it's
+        * set_extent_buffer_uptodate() call does not properly mark all it's
         * pages up-to-date when the page is larger: extent does not cover the
         * whole page and consequently check_page_uptodate does not find all
         * the page's extents up-to-date (the hole beyond sb),
@@ -6514,6 +6557,14 @@ int btrfs_read_sys_array(struct btrfs_root *root)
                                goto out_short_read;
 
                        num_stripes = btrfs_chunk_num_stripes(sb, chunk);
+                       if (!num_stripes) {
+                               printk(KERN_ERR
+           "BTRFS: invalid number of stripes %u in sys_array at offset %u\n",
+                                       num_stripes, cur_offset);
+                               ret = -EIO;
+                               break;
+                       }
+
                        len = btrfs_chunk_item_size(num_stripes);
                        if (cur_offset + len > array_size)
                                goto out_short_read;
@@ -6522,6 +6573,9 @@ int btrfs_read_sys_array(struct btrfs_root *root)
                        if (ret)
                                break;
                } else {
+                       printk(KERN_ERR
+               "BTRFS: unexpected item type %u in sys_array at offset %u\n",
+                               (u32)key.type, cur_offset);
                        ret = -EIO;
                        break;
                }
@@ -6923,7 +6977,7 @@ void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
        /* In order to kick the device replace finish process */
        lock_chunks(root);
        list_for_each_entry(em, &transaction->pending_chunks, list) {
-               map = (struct map_lookup *)em->bdev;
+               map = em->map_lookup;
 
                for (i = 0; i < map->num_stripes; i++) {
                        dev = map->stripes[i].dev;
@@ -6951,7 +7005,7 @@ void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info)
        }
 }
 
-void btrfs_close_one_device(struct btrfs_device *device)
+static void btrfs_close_one_device(struct btrfs_device *device)
 {
        struct btrfs_fs_devices *fs_devices = device->fs_devices;
        struct btrfs_device *new_device;