struct scrub_ctx {
struct scrub_bio *bios[SCRUB_BIOS_PER_SCTX];
- struct btrfs_root *dev_root;
+ struct btrfs_fs_info *fs_info;
int first_free;
int curr;
atomic_t bios_in_flight;
*/
static void scrub_pending_trans_workers_inc(struct scrub_ctx *sctx)
{
- struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
atomic_inc(&sctx->refs);
/*
/* used for workers that require transaction commits */
static void scrub_pending_trans_workers_dec(struct scrub_ctx *sctx)
{
- struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
/*
* see scrub_pending_trans_workers_inc() why we're pretending
{
struct scrub_ctx *sctx;
int i;
- struct btrfs_fs_info *fs_info = dev->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = dev->fs_info;
int ret;
sctx = kzalloc(sizeof(*sctx), GFP_KERNEL);
sctx->is_dev_replace = is_dev_replace;
sctx->pages_per_rd_bio = SCRUB_PAGES_PER_RD_BIO;
sctx->curr = -1;
- sctx->dev_root = dev->dev_root;
+ sctx->fs_info = dev->fs_info;
for (i = 0; i < SCRUB_BIOS_PER_SCTX; ++i) {
struct scrub_bio *sbio;
sctx->bios[i]->next_free = -1;
}
sctx->first_free = 0;
- sctx->nodesize = dev->dev_root->nodesize;
- sctx->sectorsize = dev->dev_root->sectorsize;
+ sctx->nodesize = dev->fs_info->dev_root->nodesize;
+ sctx->sectorsize = dev->fs_info->dev_root->sectorsize;
atomic_set(&sctx->bios_in_flight, 0);
atomic_set(&sctx->workers_pending, 0);
atomic_set(&sctx->cancel_req, 0);
struct extent_buffer *eb;
struct btrfs_inode_item *inode_item;
struct scrub_warning *swarn = warn_ctx;
- struct btrfs_fs_info *fs_info = swarn->dev->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = swarn->dev->fs_info;
struct inode_fs_paths *ipath = NULL;
struct btrfs_root *local_root;
struct btrfs_key root_key;
WARN_ON(sblock->page_count < 1);
dev = sblock->pagev[0]->dev;
- fs_info = sblock->sctx->dev_root->fs_info;
+ fs_info = sblock->sctx->fs_info;
path = btrfs_alloc_path();
if (!path)
spin_lock(&sctx->stat_lock);
++sctx->stat.uncorrectable_errors;
spin_unlock(&sctx->stat_lock);
- btrfs_dev_replace_stats_inc(
- &sctx->dev_root->fs_info->dev_replace.
- num_uncorrectable_read_errors);
- btrfs_err_rl_in_rcu(sctx->dev_root->fs_info,
+ btrfs_dev_replace_stats_inc(&sctx->fs_info->dev_replace.
+ num_uncorrectable_read_errors);
+ btrfs_err_rl_in_rcu(sctx->fs_info,
"unable to fixup (nodatasum) error at logical %llu on dev %s",
fixup->logical, rcu_str_deref(fixup->dev->name));
}
DEFAULT_RATELIMIT_BURST);
BUG_ON(sblock_to_check->page_count < 1);
- fs_info = sctx->dev_root->fs_info;
+ fs_info = sctx->fs_info;
if (sblock_to_check->pagev[0]->flags & BTRFS_EXTENT_FLAG_SUPER) {
/*
* if we find an error in a super block, we just report it.
if (scrub_write_page_to_dev_replace(sblock_other,
page_num) != 0) {
btrfs_dev_replace_stats_inc(
- &sctx->dev_root->
- fs_info->dev_replace.
+ &sctx->fs_info->dev_replace.
num_write_errors);
success = 0;
}
struct scrub_block *sblocks_for_recheck)
{
struct scrub_ctx *sctx = original_sblock->sctx;
- struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
u64 length = original_sblock->page_count * PAGE_SIZE;
u64 logical = original_sblock->pagev[0]->logical;
u64 generation = original_sblock->pagev[0]->generation;
int ret;
if (!page_bad->dev->bdev) {
- btrfs_warn_rl(sblock_bad->sctx->dev_root->fs_info,
+ btrfs_warn_rl(sblock_bad->sctx->fs_info,
"scrub_repair_page_from_good_copy(bdev == NULL) is unexpected");
return -EIO;
}
btrfs_dev_stat_inc_and_print(page_bad->dev,
BTRFS_DEV_STAT_WRITE_ERRS);
btrfs_dev_replace_stats_inc(
- &sblock_bad->sctx->dev_root->fs_info->
+ &sblock_bad->sctx->fs_info->
dev_replace.num_write_errors);
bio_put(bio);
return -EIO;
ret = scrub_write_page_to_dev_replace(sblock, page_num);
if (ret)
btrfs_dev_replace_stats_inc(
- &sblock->sctx->dev_root->fs_info->dev_replace.
+ &sblock->sctx->fs_info->dev_replace.
num_write_errors);
}
}
static void scrub_wr_bio_end_io(struct bio *bio)
{
struct scrub_bio *sbio = bio->bi_private;
- struct btrfs_fs_info *fs_info = sbio->dev->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sbio->dev->fs_info;
sbio->err = bio->bi_error;
sbio->bio = bio;
WARN_ON(sbio->page_count > SCRUB_PAGES_PER_WR_BIO);
if (sbio->err) {
struct btrfs_dev_replace *dev_replace =
- &sbio->sctx->dev_root->fs_info->dev_replace;
+ &sbio->sctx->fs_info->dev_replace;
for (i = 0; i < sbio->page_count; i++) {
struct scrub_page *spage = sbio->pagev[i];
{
struct scrub_ctx *sctx = sblock->sctx;
struct btrfs_header *h;
- struct btrfs_root *root = sctx->dev_root;
+ struct btrfs_root *root = sctx->fs_info->dev_root;
struct btrfs_fs_info *fs_info = root->fs_info;
u8 calculated_csum[BTRFS_CSUM_SIZE];
u8 on_disk_csum[BTRFS_CSUM_SIZE];
static void scrub_missing_raid56_end_io(struct bio *bio)
{
struct scrub_block *sblock = bio->bi_private;
- struct btrfs_fs_info *fs_info = sblock->sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sblock->sctx->fs_info;
if (bio->bi_error)
sblock->no_io_error_seen = 0;
spin_lock(&sctx->stat_lock);
sctx->stat.read_errors++;
spin_unlock(&sctx->stat_lock);
- btrfs_err_rl_in_rcu(sctx->dev_root->fs_info,
+ btrfs_err_rl_in_rcu(sctx->fs_info,
"IO error rebuilding logical %llu for dev %s",
logical, rcu_str_deref(dev->name));
} else if (sblock->header_error || sblock->checksum_error) {
spin_lock(&sctx->stat_lock);
sctx->stat.uncorrectable_errors++;
spin_unlock(&sctx->stat_lock);
- btrfs_err_rl_in_rcu(sctx->dev_root->fs_info,
+ btrfs_err_rl_in_rcu(sctx->fs_info,
"failed to rebuild valid logical %llu for dev %s",
logical, rcu_str_deref(dev->name));
} else {
static void scrub_missing_raid56_pages(struct scrub_block *sblock)
{
struct scrub_ctx *sctx = sblock->sctx;
- struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
+ struct btrfs_root *dev_root = fs_info->dev_root;
u64 length = sblock->page_count * PAGE_SIZE;
u64 logical = sblock->pagev[0]->logical;
struct btrfs_bio *bbio = NULL;
bio->bi_private = sblock;
bio->bi_end_io = scrub_missing_raid56_end_io;
- rbio = raid56_alloc_missing_rbio(sctx->dev_root, bio, bbio, length);
+ rbio = raid56_alloc_missing_rbio(dev_root, bio, bbio, length);
if (!rbio)
goto rbio_out;
static void scrub_bio_end_io(struct bio *bio)
{
struct scrub_bio *sbio = bio->bi_private;
- struct btrfs_fs_info *fs_info = sbio->dev->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sbio->dev->fs_info;
sbio->err = bio->bi_error;
sbio->bio = bio;
{
u32 offset;
int nsectors;
- int sectorsize = sparity->sctx->dev_root->sectorsize;
+ int sectorsize = sparity->sctx->fs_info->dev_root->sectorsize;
if (len >= sparity->stripe_len) {
bitmap_set(bitmap, 0, sparity->nsectors);
btrfs_init_work(&sparity->work, btrfs_scrubparity_helper,
scrub_parity_bio_endio_worker, NULL, NULL);
- btrfs_queue_work(sparity->sctx->dev_root->fs_info->scrub_parity_workers,
+ btrfs_queue_work(sparity->sctx->fs_info->scrub_parity_workers,
&sparity->work);
}
static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
{
struct scrub_ctx *sctx = sparity->sctx;
+ struct btrfs_root *dev_root = sctx->fs_info->dev_root;
struct bio *bio;
struct btrfs_raid_bio *rbio;
struct scrub_page *spage;
goto out;
length = sparity->logic_end - sparity->logic_start;
- ret = btrfs_map_sblock(sctx->dev_root->fs_info, BTRFS_MAP_WRITE,
+ ret = btrfs_map_sblock(sctx->fs_info, BTRFS_MAP_WRITE,
sparity->logic_start,
&length, &bbio, 0, 1);
if (ret || !bbio || !bbio->raid_map)
bio->bi_private = sparity;
bio->bi_end_io = scrub_parity_bio_endio;
- rbio = raid56_parity_alloc_scrub_rbio(sctx->dev_root, bio, bbio,
+ rbio = raid56_parity_alloc_scrub_rbio(dev_root, bio, bbio,
length, sparity->scrub_dev,
sparity->dbitmap,
sparity->nsectors);
u64 logic_start,
u64 logic_end)
{
- struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
struct btrfs_root *root = fs_info->extent_root;
struct btrfs_root *csum_root = fs_info->csum_root;
struct btrfs_extent_item *extent;
int is_dev_replace)
{
struct btrfs_path *path, *ppath;
- struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
struct btrfs_root *root = fs_info->extent_root;
struct btrfs_root *csum_root = fs_info->csum_root;
struct btrfs_extent_item *extent;
struct btrfs_block_group_cache *cache,
int is_dev_replace)
{
- struct btrfs_mapping_tree *map_tree =
- &sctx->dev_root->fs_info->mapping_tree;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
+ struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
struct map_lookup *map;
struct extent_map *em;
int i;
{
struct btrfs_dev_extent *dev_extent = NULL;
struct btrfs_path *path;
- struct btrfs_root *root = sctx->dev_root;
+ struct btrfs_root *root = sctx->fs_info->dev_root;
struct btrfs_fs_info *fs_info = root->fs_info;
u64 length;
u64 chunk_offset;
u64 bytenr;
u64 gen;
int ret;
- struct btrfs_root *root = sctx->dev_root;
+ struct btrfs_root *root = sctx->fs_info->dev_root;
if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state))
return -EIO;
int mirror_num, u64 physical_for_dev_replace)
{
struct scrub_copy_nocow_ctx *nocow_ctx;
- struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
nocow_ctx = kzalloc(sizeof(*nocow_ctx), GFP_NOFS);
if (!nocow_ctx) {
struct btrfs_root *root;
int not_written = 0;
- fs_info = sctx->dev_root->fs_info;
+ fs_info = sctx->fs_info;
root = fs_info->extent_root;
path = btrfs_alloc_path();
static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root,
struct scrub_copy_nocow_ctx *nocow_ctx)
{
- struct btrfs_fs_info *fs_info = nocow_ctx->sctx->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = nocow_ctx->sctx->fs_info;
struct btrfs_key key;
struct inode *inode;
struct page *page;
if (!dev)
return -EIO;
if (!dev->bdev) {
- btrfs_warn_rl(dev->dev_root->fs_info,
+ btrfs_warn_rl(dev->fs_info,
"scrub write_page_nocow(bdev == NULL) is unexpected");
return -EIO;
}
blk_start_plug(&plug);
bdi = blk_get_backing_dev_info(device->bdev);
- fs_info = device->dev_root->fs_info;
+ fs_info = device->fs_info;
limit = btrfs_async_submit_limit(fs_info);
limit = limit * 2 / 3;
u64 end, u64 *length)
{
struct btrfs_key key;
- struct btrfs_root *root = device->dev_root;
+ struct btrfs_root *root = device->fs_info->dev_root;
struct btrfs_dev_extent *dev_extent;
struct btrfs_path *path;
u64 extent_end;
struct btrfs_device *device,
u64 *start, u64 len)
{
- struct btrfs_fs_info *fs_info = device->dev_root->fs_info;
+ struct btrfs_fs_info *fs_info = device->fs_info;
struct extent_map *em;
struct list_head *search_list = &fs_info->pinned_chunks;
int ret = 0;
struct btrfs_device *device, u64 num_bytes,
u64 search_start, u64 *start, u64 *len)
{
+ struct btrfs_root *root = device->fs_info->dev_root;
struct btrfs_key key;
- struct btrfs_root *root = device->dev_root;
struct btrfs_dev_extent *dev_extent;
struct btrfs_path *path;
u64 hole_size;
struct btrfs_device *device,
u64 start, u64 *dev_extent_len)
{
+ struct btrfs_root *root = device->fs_info->dev_root;
int ret;
struct btrfs_path *path;
- struct btrfs_root *root = device->dev_root;
struct btrfs_key key;
struct btrfs_key found_key;
struct extent_buffer *leaf = NULL;
{
int ret;
struct btrfs_path *path;
- struct btrfs_root *root = device->dev_root;
+ struct btrfs_root *root = device->fs_info->dev_root;
struct btrfs_dev_extent *extent;
struct extent_buffer *leaf;
struct btrfs_key key;
device->total_bytes = i_size_read(bdev->bd_inode);
device->disk_total_bytes = device->total_bytes;
device->commit_total_bytes = device->total_bytes;
- device->dev_root = root->fs_info->dev_root;
+ device->fs_info = fs_info;
device->bdev = bdev;
device->in_fs_metadata = 1;
device->is_tgtdev_for_dev_replace = 0;
ASSERT(list_empty(&srcdev->resized_list));
device->commit_total_bytes = srcdev->commit_total_bytes;
device->commit_bytes_used = device->bytes_used;
- device->dev_root = fs_info->dev_root;
+ device->fs_info = fs_info;
device->bdev = bdev;
device->in_fs_metadata = 1;
device->is_tgtdev_for_dev_replace = 1;
tgtdev->io_width = fs_info->dev_root->sectorsize;
tgtdev->io_align = fs_info->dev_root->sectorsize;
tgtdev->sector_size = fs_info->dev_root->sectorsize;
- tgtdev->dev_root = fs_info->dev_root;
+ tgtdev->fs_info = fs_info;
tgtdev->in_fs_metadata = 1;
}
struct extent_buffer *leaf;
struct btrfs_key key;
- root = device->dev_root->fs_info->chunk_root;
+ root = device->fs_info->chunk_root;
path = btrfs_alloc_path();
if (!path)
int btrfs_grow_device(struct btrfs_trans_handle *trans,
struct btrfs_device *device, u64 new_size)
{
- struct btrfs_super_block *super_copy =
- device->dev_root->fs_info->super_copy;
+ struct btrfs_super_block *super_copy = device->fs_info->super_copy;
struct btrfs_fs_devices *fs_devices;
u64 old_total;
u64 diff;
if (!device->writeable)
return -EACCES;
- lock_chunks(device->dev_root);
+ lock_chunks(device->fs_info->dev_root);
old_total = btrfs_super_total_bytes(super_copy);
diff = new_size - device->total_bytes;
if (new_size <= device->total_bytes ||
device->is_tgtdev_for_dev_replace) {
- unlock_chunks(device->dev_root);
+ unlock_chunks(device->fs_info->dev_root);
return -EINVAL;
}
- fs_devices = device->dev_root->fs_info->fs_devices;
+ fs_devices = device->fs_info->fs_devices;
btrfs_set_super_total_bytes(super_copy, old_total + diff);
device->fs_devices->total_rw_bytes += diff;
btrfs_device_set_total_bytes(device, new_size);
btrfs_device_set_disk_total_bytes(device, new_size);
- btrfs_clear_space_info_full(device->dev_root->fs_info);
+ btrfs_clear_space_info_full(device->fs_info);
if (list_empty(&device->resized_list))
list_add_tail(&device->resized_list,
&fs_devices->resized_devices);
- unlock_chunks(device->dev_root);
+ unlock_chunks(device->fs_info->dev_root);
return btrfs_update_device(trans, device);
}
int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
{
struct btrfs_trans_handle *trans;
- struct btrfs_root *root = device->dev_root;
+ struct btrfs_root *root = device->fs_info->dev_root;
struct btrfs_dev_extent *dev_extent = NULL;
struct btrfs_path *path;
u64 length;
while (fs_devices) {
mutex_lock(&fs_devices->device_list_mutex);
list_for_each_entry(device, &fs_devices->devices, dev_list)
- device->dev_root = fs_info->dev_root;
+ device->fs_info = fs_info;
mutex_unlock(&fs_devices->device_list_mutex);
fs_devices = fs_devices->seed;
{
if (!dev->dev_stats_valid)
return;
- btrfs_err_rl_in_rcu(dev->dev_root->fs_info,
+ btrfs_err_rl_in_rcu(dev->fs_info,
"bdev %s errs: wr %u, rd %u, flush %u, corrupt %u, gen %u",
rcu_str_deref(dev->name),
btrfs_dev_stat_read(dev, BTRFS_DEV_STAT_WRITE_ERRS),
if (i == BTRFS_DEV_STAT_VALUES_MAX)
return; /* all values == 0, suppress message */
- btrfs_info_in_rcu(dev->dev_root->fs_info,
+ btrfs_info_in_rcu(dev->fs_info,
"bdev %s errs: wr %u, rd %u, flush %u, corrupt %u, gen %u",
rcu_str_deref(dev->name),
btrfs_dev_stat_read(dev, BTRFS_DEV_STAT_WRITE_ERRS),