Merge branch 'for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[cascardo/linux.git] / fs / btrfs / volumes.c
index 589f128..bb0addc 100644 (file)
@@ -140,7 +140,6 @@ 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);
@@ -462,7 +461,7 @@ loop_lock:
                        sync_pending = 0;
                }
 
-               btrfsic_submit_bio(cur->bi_rw, cur);
+               btrfsic_submit_bio(cur);
                num_run++;
                batch_run++;
 
@@ -853,6 +852,46 @@ static void free_device(struct rcu_head *head)
        schedule_work(&device->rcu_work);
 }
 
+static void btrfs_close_one_device(struct btrfs_device *device)
+{
+       struct btrfs_fs_devices *fs_devices = device->fs_devices;
+       struct btrfs_device *new_device;
+       struct rcu_string *name;
+
+       if (device->bdev)
+               fs_devices->open_devices--;
+
+       if (device->writeable &&
+           device->devid != BTRFS_DEV_REPLACE_DEVID) {
+               list_del_init(&device->dev_alloc_list);
+               fs_devices->rw_devices--;
+       }
+
+       if (device->missing)
+               fs_devices->missing_devices--;
+
+       if (device->bdev && device->writeable) {
+               sync_blockdev(device->bdev);
+               invalidate_bdev(device->bdev);
+       }
+
+       new_device = btrfs_alloc_device(NULL, &device->devid,
+                                       device->uuid);
+       BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
+
+       /* Safe because we are under uuid_mutex */
+       if (device->name) {
+               name = rcu_string_strdup(device->name->str, GFP_NOFS);
+               BUG_ON(!name); /* -ENOMEM */
+               rcu_assign_pointer(new_device->name, name);
+       }
+
+       list_replace_rcu(&device->dev_list, &new_device->dev_list);
+       new_device->fs_devices = device->fs_devices;
+
+       call_rcu(&device->rcu, free_device);
+}
+
 static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
        struct btrfs_device *device, *tmp;
@@ -2399,14 +2438,14 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
                ret = init_first_rw_device(trans, root, device);
                unlock_chunks(root);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto error_trans;
                }
        }
 
        ret = btrfs_add_device(trans, root, device);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto error_trans;
        }
 
@@ -2415,7 +2454,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
 
                ret = btrfs_finish_sprout(trans, root);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto error_trans;
                }
 
@@ -2801,7 +2840,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
                                            &dev_extent_len);
                if (ret) {
                        mutex_unlock(&fs_devices->device_list_mutex);
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
@@ -2820,7 +2859,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
                        ret = btrfs_update_device(trans, map->stripes[i].dev);
                        if (ret) {
                                mutex_unlock(&fs_devices->device_list_mutex);
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                goto out;
                        }
                }
@@ -2829,7 +2868,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
 
        ret = btrfs_free_chunk(trans, root, chunk_objectid, chunk_offset);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -2838,14 +2877,14 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
        if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
                ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
        }
 
        ret = btrfs_remove_block_group(trans, extent_root, chunk_offset, em);
        if (ret) {
-               btrfs_abort_transaction(trans, extent_root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -2902,7 +2941,7 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
         * chunk tree entries
         */
        ret = btrfs_remove_chunk(trans, root, chunk_offset);
-       btrfs_end_transaction(trans, root);
+       btrfs_end_transaction(trans, extent_root);
        return ret;
 }
 
@@ -3421,7 +3460,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
        u64 size_to_free;
        u64 chunk_type;
        struct btrfs_chunk *chunk;
-       struct btrfs_path *path;
+       struct btrfs_path *path = NULL;
        struct btrfs_key key;
        struct btrfs_key found_key;
        struct btrfs_trans_handle *trans;
@@ -3455,13 +3494,33 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
                ret = btrfs_shrink_device(device, old_size - size_to_free);
                if (ret == -ENOSPC)
                        break;
-               BUG_ON(ret);
+               if (ret) {
+                       /* btrfs_shrink_device never returns ret > 0 */
+                       WARN_ON(ret > 0);
+                       goto error;
+               }
 
                trans = btrfs_start_transaction(dev_root, 0);
-               BUG_ON(IS_ERR(trans));
+               if (IS_ERR(trans)) {
+                       ret = PTR_ERR(trans);
+                       btrfs_info_in_rcu(fs_info,
+                "resize: unable to start transaction after shrinking device %s (error %d), old size %llu, new size %llu",
+                                         rcu_str_deref(device->name), ret,
+                                         old_size, old_size - size_to_free);
+                       goto error;
+               }
 
                ret = btrfs_grow_device(trans, device, old_size);
-               BUG_ON(ret);
+               if (ret) {
+                       btrfs_end_transaction(trans, dev_root);
+                       /* btrfs_grow_device never returns ret > 0 */
+                       WARN_ON(ret > 0);
+                       btrfs_info_in_rcu(fs_info,
+                "resize: unable to grow device after shrinking device %s (error %d), old size %llu, new size %llu",
+                                         rcu_str_deref(device->name), ret,
+                                         old_size, old_size - size_to_free);
+                       goto error;
+               }
 
                btrfs_end_transaction(trans, dev_root);
        }
@@ -3885,7 +3944,7 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
        }
        spin_unlock(&fs_info->balance_lock);
 
-       if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
+       if (btrfs_test_opt(fs_info, SKIP_BALANCE)) {
                btrfs_info(fs_info, "force skipping balance");
                return 0;
        }
@@ -4240,7 +4299,7 @@ int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info)
                                      BTRFS_UUID_TREE_OBJECTID);
        if (IS_ERR(uuid_root)) {
                ret = PTR_ERR(uuid_root);
-               btrfs_abort_transaction(trans, tree_root, ret);
+               btrfs_abort_transaction(trans, ret);
                btrfs_end_transaction(trans, tree_root);
                return ret;
        }
@@ -4514,8 +4573,7 @@ static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type)
        btrfs_set_fs_incompat(info, RAID56);
 }
 
-#define BTRFS_MAX_DEVS(r) ((BTRFS_LEAF_DATA_SIZE(r)            \
-                       - sizeof(struct btrfs_item)             \
+#define BTRFS_MAX_DEVS(r) ((BTRFS_MAX_ITEM_SIZE(r)             \
                        - sizeof(struct btrfs_chunk))           \
                        / sizeof(struct btrfs_stripe) + 1)
 
@@ -5260,7 +5318,7 @@ void btrfs_put_bbio(struct btrfs_bio *bbio)
                kfree(bbio);
 }
 
-static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
+static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int op,
                             u64 logical, u64 *length,
                             struct btrfs_bio **bbio_ret,
                             int mirror_num, int need_raid_map)
@@ -5346,7 +5404,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                raid56_full_stripe_start *= full_stripe_len;
        }
 
-       if (rw & REQ_DISCARD) {
+       if (op == REQ_OP_DISCARD) {
                /* we don't discard raid56 yet */
                if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
                        ret = -EOPNOTSUPP;
@@ -5359,7 +5417,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                   For other RAID types and for RAID[56] reads, just allow a single
                   stripe (on a single disk). */
                if ((map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) &&
-                   (rw & REQ_WRITE)) {
+                   (op == REQ_OP_WRITE)) {
                        max_len = stripe_len * nr_data_stripes(map) -
                                (offset - raid56_full_stripe_start);
                } else {
@@ -5384,8 +5442,8 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                btrfs_dev_replace_set_lock_blocking(dev_replace);
 
        if (dev_replace_is_ongoing && mirror_num == map->num_stripes + 1 &&
-           !(rw & (REQ_WRITE | REQ_DISCARD | REQ_GET_READ_MIRRORS)) &&
-           dev_replace->tgtdev != NULL) {
+           op != REQ_OP_WRITE && op != REQ_OP_DISCARD &&
+           op != REQ_GET_READ_MIRRORS && dev_replace->tgtdev != NULL) {
                /*
                 * in dev-replace case, for repair case (that's the only
                 * case where the mirror is selected explicitly when
@@ -5472,15 +5530,17 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                            (offset + *length);
 
        if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
-               if (rw & REQ_DISCARD)
+               if (op == REQ_OP_DISCARD)
                        num_stripes = min_t(u64, map->num_stripes,
                                            stripe_nr_end - stripe_nr_orig);
                stripe_nr = div_u64_rem(stripe_nr, map->num_stripes,
                                &stripe_index);
-               if (!(rw & (REQ_WRITE | REQ_DISCARD | REQ_GET_READ_MIRRORS)))
+               if (op != REQ_OP_WRITE && op != REQ_OP_DISCARD &&
+                   op != REQ_GET_READ_MIRRORS)
                        mirror_num = 1;
        } else if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
-               if (rw & (REQ_WRITE | REQ_DISCARD | REQ_GET_READ_MIRRORS))
+               if (op == REQ_OP_WRITE || op == REQ_OP_DISCARD ||
+                   op == REQ_GET_READ_MIRRORS)
                        num_stripes = map->num_stripes;
                else if (mirror_num)
                        stripe_index = mirror_num - 1;
@@ -5493,7 +5553,8 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                }
 
        } else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
-               if (rw & (REQ_WRITE | REQ_DISCARD | REQ_GET_READ_MIRRORS)) {
+               if (op == REQ_OP_WRITE || op == REQ_OP_DISCARD ||
+                   op == REQ_GET_READ_MIRRORS) {
                        num_stripes = map->num_stripes;
                } else if (mirror_num) {
                        stripe_index = mirror_num - 1;
@@ -5507,9 +5568,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                stripe_nr = div_u64_rem(stripe_nr, factor, &stripe_index);
                stripe_index *= map->sub_stripes;
 
-               if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS))
+               if (op == REQ_OP_WRITE || op == REQ_GET_READ_MIRRORS)
                        num_stripes = map->sub_stripes;
-               else if (rw & REQ_DISCARD)
+               else if (op == REQ_OP_DISCARD)
                        num_stripes = min_t(u64, map->sub_stripes *
                                            (stripe_nr_end - stripe_nr_orig),
                                            map->num_stripes);
@@ -5527,7 +5588,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
 
        } else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
                if (need_raid_map &&
-                   ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) ||
+                   (op == REQ_OP_WRITE || op == REQ_GET_READ_MIRRORS ||
                     mirror_num > 1)) {
                        /* push stripe_nr back to the start of the full stripe */
                        stripe_nr = div_u64(raid56_full_stripe_start,
@@ -5555,8 +5616,8 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                        /* We distribute the parity blocks across stripes */
                        div_u64_rem(stripe_nr + stripe_index, map->num_stripes,
                                        &stripe_index);
-                       if (!(rw & (REQ_WRITE | REQ_DISCARD |
-                                   REQ_GET_READ_MIRRORS)) && mirror_num <= 1)
+                       if ((op != REQ_OP_WRITE && op != REQ_OP_DISCARD &&
+                           op != REQ_GET_READ_MIRRORS) && mirror_num <= 1)
                                mirror_num = 1;
                }
        } else {
@@ -5579,9 +5640,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
 
        num_alloc_stripes = num_stripes;
        if (dev_replace_is_ongoing) {
-               if (rw & (REQ_WRITE | REQ_DISCARD))
+               if (op == REQ_OP_WRITE || op == REQ_OP_DISCARD)
                        num_alloc_stripes <<= 1;
-               if (rw & REQ_GET_READ_MIRRORS)
+               if (op == REQ_GET_READ_MIRRORS)
                        num_alloc_stripes++;
                tgtdev_indexes = num_stripes;
        }
@@ -5596,7 +5657,8 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
 
        /* build raid_map */
        if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK &&
-           need_raid_map && ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) ||
+           need_raid_map &&
+           ((op == REQ_OP_WRITE || op == REQ_GET_READ_MIRRORS) ||
            mirror_num > 1)) {
                u64 tmp;
                unsigned rot;
@@ -5621,7 +5683,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                                RAID6_Q_STRIPE;
        }
 
-       if (rw & REQ_DISCARD) {
+       if (op == REQ_OP_DISCARD) {
                u32 factor = 0;
                u32 sub_stripes = 0;
                u64 stripes_per_dev = 0;
@@ -5701,14 +5763,15 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                }
        }
 
-       if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS))
+       if (op == REQ_OP_WRITE || op == REQ_GET_READ_MIRRORS)
                max_errors = btrfs_chunk_max_errors(map);
 
        if (bbio->raid_map)
                sort_parity_stripes(bbio, num_stripes);
 
        tgtdev_indexes = 0;
-       if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) &&
+       if (dev_replace_is_ongoing &&
+          (op == REQ_OP_WRITE || op == REQ_OP_DISCARD) &&
            dev_replace->tgtdev != NULL) {
                int index_where_to_add;
                u64 srcdev_devid = dev_replace->srcdev->devid;
@@ -5743,7 +5806,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                        }
                }
                num_stripes = index_where_to_add;
-       } else if (dev_replace_is_ongoing && (rw & REQ_GET_READ_MIRRORS) &&
+       } else if (dev_replace_is_ongoing && (op == REQ_GET_READ_MIRRORS) &&
                   dev_replace->tgtdev != NULL) {
                u64 srcdev_devid = dev_replace->srcdev->devid;
                int index_srcdev = 0;
@@ -5815,21 +5878,21 @@ out:
        return ret;
 }
 
-int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
+int btrfs_map_block(struct btrfs_fs_info *fs_info, int op,
                      u64 logical, u64 *length,
                      struct btrfs_bio **bbio_ret, int mirror_num)
 {
-       return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret,
+       return __btrfs_map_block(fs_info, op, logical, length, bbio_ret,
                                 mirror_num, 0);
 }
 
 /* For Scrub/replace */
-int btrfs_map_sblock(struct btrfs_fs_info *fs_info, int rw,
+int btrfs_map_sblock(struct btrfs_fs_info *fs_info, int op,
                     u64 logical, u64 *length,
                     struct btrfs_bio **bbio_ret, int mirror_num,
                     int need_raid_map)
 {
-       return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret,
+       return __btrfs_map_block(fs_info, op, logical, length, bbio_ret,
                                 mirror_num, need_raid_map);
 }
 
@@ -5943,7 +6006,7 @@ static void btrfs_end_bio(struct bio *bio)
                        BUG_ON(stripe_index >= bbio->num_stripes);
                        dev = bbio->stripes[stripe_index].dev;
                        if (dev->bdev) {
-                               if (bio->bi_rw & WRITE)
+                               if (bio_op(bio) == REQ_OP_WRITE)
                                        btrfs_dev_stat_inc(dev,
                                                BTRFS_DEV_STAT_WRITE_ERRS);
                                else
@@ -5997,7 +6060,7 @@ static void btrfs_end_bio(struct bio *bio)
  */
 static noinline void btrfs_schedule_bio(struct btrfs_root *root,
                                        struct btrfs_device *device,
-                                       int rw, struct bio *bio)
+                                       struct bio *bio)
 {
        int should_queue = 1;
        struct btrfs_pending_bios *pending_bios;
@@ -6008,9 +6071,9 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root,
        }
 
        /* don't bother with additional async steps for reads, right now */
-       if (!(rw & REQ_WRITE)) {
+       if (bio_op(bio) == REQ_OP_READ) {
                bio_get(bio);
-               btrfsic_submit_bio(rw, bio);
+               btrfsic_submit_bio(bio);
                bio_put(bio);
                return;
        }
@@ -6024,7 +6087,6 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root,
        atomic_inc(&root->fs_info->nr_async_bios);
        WARN_ON(bio->bi_next);
        bio->bi_next = NULL;
-       bio->bi_rw |= rw;
 
        spin_lock(&device->io_lock);
        if (bio->bi_rw & REQ_SYNC)
@@ -6050,7 +6112,7 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root,
 
 static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio,
                              struct bio *bio, u64 physical, int dev_nr,
-                             int rw, int async)
+                             int async)
 {
        struct btrfs_device *dev = bbio->stripes[dev_nr].dev;
 
@@ -6064,8 +6126,8 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio,
 
                rcu_read_lock();
                name = rcu_dereference(dev->name);
-               pr_debug("btrfs_map_bio: rw %d, sector=%llu, dev=%lu "
-                        "(%s id %llu), size=%u\n", rw,
+               pr_debug("btrfs_map_bio: rw %d 0x%x, sector=%llu, dev=%lu "
+                        "(%s id %llu), size=%u\n", bio_op(bio), bio->bi_rw,
                         (u64)bio->bi_iter.bi_sector, (u_long)dev->bdev->bd_dev,
                         name->str, dev->devid, bio->bi_iter.bi_size);
                rcu_read_unlock();
@@ -6076,9 +6138,9 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio,
        btrfs_bio_counter_inc_noblocked(root->fs_info);
 
        if (async)
-               btrfs_schedule_bio(root, dev, rw, bio);
+               btrfs_schedule_bio(root, dev, bio);
        else
-               btrfsic_submit_bio(rw, bio);
+               btrfsic_submit_bio(bio);
 }
 
 static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
@@ -6095,7 +6157,7 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
        }
 }
 
-int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
+int btrfs_map_bio(struct btrfs_root *root, struct bio *bio,
                  int mirror_num, int async_submit)
 {
        struct btrfs_device *dev;
@@ -6112,8 +6174,8 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
        map_length = length;
 
        btrfs_bio_counter_inc_blocked(root->fs_info);
-       ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio,
-                             mirror_num, 1);
+       ret = __btrfs_map_block(root->fs_info, bio_op(bio), logical,
+                               &map_length, &bbio, mirror_num, 1);
        if (ret) {
                btrfs_bio_counter_dec(root->fs_info);
                return ret;
@@ -6127,10 +6189,10 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
        atomic_set(&bbio->stripes_pending, bbio->num_stripes);
 
        if ((bbio->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK) &&
-           ((rw & WRITE) || (mirror_num > 1))) {
+           ((bio_op(bio) == REQ_OP_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) {
+               if (bio_op(bio) == REQ_OP_WRITE) {
                        ret = raid56_parity_write(root, bio, bbio, map_length);
                } else {
                        ret = raid56_parity_recover(root, bio, bbio, map_length,
@@ -6149,7 +6211,8 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
 
        for (dev_nr = 0; dev_nr < total_devs; dev_nr++) {
                dev = bbio->stripes[dev_nr].dev;
-               if (!dev || !dev->bdev || (rw & WRITE && !dev->writeable)) {
+               if (!dev || !dev->bdev ||
+                   (bio_op(bio) == REQ_OP_WRITE && !dev->writeable)) {
                        bbio_error(bbio, first_bio, logical);
                        continue;
                }
@@ -6161,7 +6224,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
                        bio = first_bio;
 
                submit_stripe_bio(root, bbio, bio,
-                                 bbio->stripes[dev_nr].physical, dev_nr, rw,
+                                 bbio->stripes[dev_nr].physical, dev_nr,
                                  async_submit);
        }
        btrfs_bio_counter_dec(root->fs_info);
@@ -6396,7 +6459,8 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
                                   BTRFS_UUID_SIZE);
                map->stripes[i].dev = btrfs_find_device(root->fs_info, devid,
                                                        uuid, NULL);
-               if (!map->stripes[i].dev && !btrfs_test_opt(root, DEGRADED)) {
+               if (!map->stripes[i].dev &&
+                   !btrfs_test_opt(root->fs_info, DEGRADED)) {
                        free_extent_map(em);
                        return -EIO;
                }
@@ -6464,7 +6528,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_root *root,
 
        fs_devices = find_fsid(fsid);
        if (!fs_devices) {
-               if (!btrfs_test_opt(root, DEGRADED))
+               if (!btrfs_test_opt(root->fs_info, DEGRADED))
                        return ERR_PTR(-ENOENT);
 
                fs_devices = alloc_fs_devices(fsid);
@@ -6526,7 +6590,7 @@ static int read_one_dev(struct btrfs_root *root,
 
        device = btrfs_find_device(root->fs_info, devid, dev_uuid, fs_uuid);
        if (!device) {
-               if (!btrfs_test_opt(root, DEGRADED))
+               if (!btrfs_test_opt(root->fs_info, DEGRADED))
                        return -EIO;
 
                device = add_missing_dev(root, fs_devices, devid, dev_uuid);
@@ -6535,7 +6599,7 @@ static int read_one_dev(struct btrfs_root *root,
                btrfs_warn(root->fs_info, "devid %llu uuid %pU missing",
                                devid, dev_uuid);
        } else {
-               if (!device->bdev && !btrfs_test_opt(root, DEGRADED))
+               if (!device->bdev && !btrfs_test_opt(root->fs_info, DEGRADED))
                        return -EIO;
 
                if(!device->bdev && !device->missing) {
@@ -7138,38 +7202,3 @@ void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info)
                fs_devices = fs_devices->seed;
        }
 }
-
-static void btrfs_close_one_device(struct btrfs_device *device)
-{
-       struct btrfs_fs_devices *fs_devices = device->fs_devices;
-       struct btrfs_device *new_device;
-       struct rcu_string *name;
-
-       if (device->bdev)
-               fs_devices->open_devices--;
-
-       if (device->writeable &&
-           device->devid != BTRFS_DEV_REPLACE_DEVID) {
-               list_del_init(&device->dev_alloc_list);
-               fs_devices->rw_devices--;
-       }
-
-       if (device->missing)
-               fs_devices->missing_devices--;
-
-       new_device = btrfs_alloc_device(NULL, &device->devid,
-                                       device->uuid);
-       BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
-
-       /* Safe because we are under uuid_mutex */
-       if (device->name) {
-               name = rcu_string_strdup(device->name->str, GFP_NOFS);
-               BUG_ON(!name); /* -ENOMEM */
-               rcu_assign_pointer(new_device->name, name);
-       }
-
-       list_replace_rcu(&device->dev_list, &new_device->dev_list);
-       new_device->fs_devices = device->fs_devices;
-
-       call_rcu(&device->rcu, free_device);
-}