On Fri, Oct 5, 2018 at 10:46 AM Qu Wenruo <wqu@xxxxxxxx> wrote:
>
> Add extra dev extent end check against device boundary.
>
> Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
> ---
> fs/btrfs/volumes.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index bf0b2c16847a..bc3ac4715694 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -7371,6 +7371,7 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info,
> struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree;
> struct extent_map *em;
> struct map_lookup *map;
> + struct btrfs_device *dev;
> u64 stripe_len;
> bool found = false;
> int ret = 0;
> @@ -7420,6 +7421,22 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info,
> physical_offset, devid);
> ret = -EUCLEAN;
> }
> +
> + /* Make sure no dev extent is beyond device bondary */
> + dev = btrfs_find_device(fs_info, devid, NULL, NULL);
Qu,
This breaks use cases including seed devices. In those cases we need
to find a device by ID and FSID (not not return the first device we
find with a specific ID, ignoring the FSID).
Fstest btrfs/163 now fails in 5.0-rc1 because of this change.
Thanks.
> + if (!dev) {
> + btrfs_err(fs_info, "failed to find devid %llu", devid);
> + ret = -EUCLEAN;
> + goto out;
> + }
> + if (physical_offset + physical_len > dev->disk_total_bytes) {
> + btrfs_err(fs_info,
> +"dev extent devid %llu physical offset %llu len %llu is beyond device boundary %llu",
> + devid, physical_offset, physical_len,
> + dev->disk_total_bytes);
> + ret = -EUCLEAN;
> + goto out;
> + }
> out:
> free_extent_map(em);
> return ret;
> --
> 2.19.0
>
--
Filipe David Manana,
“Whether you think you can, or you think you can't — you're right.”