From: Anand Jain anand.jain@oracle.com
mainline inclusion from mainline-v5.16-rc1 commit d24fa5c1da08026be9959baca309fa0adf8708bf category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IA77UW CVE: CVE-2021-47599
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
In preparation to fix a bug in btrfs_show_devname().
Convert fs_devices::latest_bdev type from struct block_device to struct btrfs_device and, rename the member to fs_devices::latest_dev. So that btrfs_show_devname() can use fs_devices::latest_dev::name.
Tested-by: Su Yue l@damenly.su Signed-off-by: Anand Jain anand.jain@oracle.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Conflicts: fs/btrfs/inode.c fs/btrfs/disk-io.c fs/btrfs/extent_io.c fs/btrfs/volumes.c [Resolve conflicts due to several refactor patches not merged.] Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/btrfs/volumes.h | 6 +++++- fs/btrfs/disk-io.c | 6 +++--- fs/btrfs/extent_io.c | 2 +- fs/btrfs/inode.c | 2 +- fs/btrfs/super.c | 2 +- fs/btrfs/volumes.c | 10 +++++----- 6 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index b2046e92b914..90472e3116ac 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -228,7 +228,11 @@ struct btrfs_fs_devices { /* Highest generation number of seen devices */ u64 latest_generation;
- struct block_device *latest_bdev; + /* + * The mount device or a device with highest generation after removal + * or replace. + */ + struct btrfs_device *latest_dev;
/* all of the devices in the FS, protected by a mutex * so we can safely walk it to write out the supers without diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 2c07f78a50b4..707344288b1c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2970,12 +2970,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); btrfs_init_btree_inode(fs_info);
- invalidate_bdev(fs_devices->latest_bdev); + invalidate_bdev(fs_devices->latest_dev->bdev);
/* * Read super block and check the signature bytes only */ - disk_super = btrfs_read_dev_super(fs_devices->latest_bdev); + disk_super = btrfs_read_dev_super(fs_devices->latest_dev->bdev); if (IS_ERR(disk_super)) { err = PTR_ERR(disk_super); goto fail_alloc; @@ -3199,7 +3199,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device */ btrfs_free_extra_devids(fs_devices, 0);
- if (!fs_devices->latest_bdev) { + if (!fs_devices->latest_dev->bdev) { btrfs_err(fs_info, "failed to read devices"); goto fail_tree_roots; } diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 685a375bb6af..104e2f1fe4f7 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3080,7 +3080,7 @@ static int submit_extent_page(unsigned int opf, if (wbc) { struct block_device *bdev;
- bdev = BTRFS_I(page->mapping->host)->root->fs_info->fs_devices->latest_bdev; + bdev = BTRFS_I(page->mapping->host)->root->fs_info->fs_devices->latest_dev->bdev; bio_set_dev(bio, bdev); wbc_init_bio(wbc, bio); wbc_account_cgroup_owner(wbc, page, page_size); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fa00580b6678..1db28dc76b06 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7560,7 +7560,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start, iomap->type = IOMAP_MAPPED; } iomap->offset = start; - iomap->bdev = fs_info->fs_devices->latest_bdev; + iomap->bdev = fs_info->fs_devices->latest_dev->bdev; iomap->length = len;
free_extent_map(em); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index ea731fa8bd35..0d9a2f70d5d3 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1676,7 +1676,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, goto error_close_devices; }
- bdev = fs_devices->latest_bdev; + bdev = fs_devices->latest_dev->bdev; s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC, fs_info); if (IS_ERR(s)) { diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 6f5735bec8e2..5088fd10a434 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1142,7 +1142,7 @@ void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices, int step) list_for_each_entry(seed_dev, &fs_devices->seed_list, seed_list) __btrfs_free_extra_devids(seed_dev, step, &latest_dev);
- fs_devices->latest_bdev = latest_dev->bdev; + fs_devices->latest_dev = latest_dev;
mutex_unlock(&uuid_mutex); } @@ -1287,7 +1287,7 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices, return -EINVAL;
fs_devices->opened = 1; - fs_devices->latest_bdev = latest_dev->bdev; + fs_devices->latest_dev = latest_dev; fs_devices->total_rw_bytes = 0; fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_REGULAR;
@@ -2049,7 +2049,7 @@ static struct btrfs_device * btrfs_find_next_active_device( }
/* - * Helper function to check if the given device is part of s_bdev / latest_bdev + * Helper function to check if the given device is part of s_bdev / latest_dev * and replace it with the provided or the next active device, in the context * where this function called, there should be always be another device (or * this_dev) which is active. @@ -2068,8 +2068,8 @@ void __cold btrfs_assign_next_active_device(struct btrfs_device *device, (fs_info->sb->s_bdev == device->bdev)) fs_info->sb->s_bdev = next_device->bdev;
- if (fs_info->fs_devices->latest_bdev == device->bdev) - fs_info->fs_devices->latest_bdev = next_device->bdev; + if (fs_info->fs_devices->latest_dev->bdev == device->bdev) + fs_info->fs_devices->latest_dev = next_device; }
/*