diff mbox series

[v2,1/2] btrfs: drop never met condition of disk_total_bytes == 0

Message ID 2b54dd9a6634a833cff4e4ac8ff030a6b802652e.1601988260.git.anand.jain@oracle.com (mailing list archive)
State New, archived
Headers show
Series [v2,1/2] btrfs: drop never met condition of disk_total_bytes == 0 | expand

Commit Message

Anand Jain Oct. 6, 2020, 12:54 p.m. UTC
btrfs_device::disk_total_bytes is set even for a seed device (the
comment is wrong).

The function fill_device_from_item() does the job of reading it from the
item and updating btrfs_device::disk_total_bytes. So both the missing
device and the seed devices do have their disk_total_bytes updated.

Furthermore, while removing the device if there is a power loss, we could
have a device with its total_bytes = 0, that's still valid.

So this patch removes the check dev->disk_total_bytes == 0 in the
function verify_one_dev_extent(), which it does nothing in it.

And take this opportunity to introduce a check if the device::total_bytes
is more than the max device size in read_one_dev().

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v2: add check if the total_bytes is more than the actual device size in
    read_one_dev().
    update change log.

 fs/btrfs/volumes.c | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

Comments

Josef Bacik Oct. 21, 2020, 2:35 p.m. UTC | #1
On 10/21/20 12:16 AM, Anand Jain wrote:
> btrfs_device::disk_total_bytes is set even for a seed device (the
> comment is wrong).
> 
> The function fill_device_from_item() does the job of reading it from the
> item and updating btrfs_device::disk_total_bytes. So both the missing
> device and the seed devices do have their disk_total_bytes updated.
> 
> Furthermore, while removing the device if there is a power loss, we could
> have a device with its total_bytes = 0, that's still valid.
> 
> So this patch removes the check dev->disk_total_bytes == 0 in the
> function verify_one_dev_extent(), which it does nothing in it.
> 
> And take this opportunity to introduce a check if the device::total_bytes
> is more than the max device size in read_one_dev().
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> Reviewed-by: Nikolay Borisov <nborisov@suse.com>
> ---
> v2: add check if the total_bytes is more than the actual device size in
>      read_one_dev().
>      update change log.
> 
>   fs/btrfs/volumes.c | 25 ++++++++++---------------
>   1 file changed, 10 insertions(+), 15 deletions(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 2a5397fb4175..0c6049f9ace3 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -6847,6 +6847,16 @@ static int read_one_dev(struct extent_buffer *leaf,
>   	}
>   
>   	fill_device_from_item(leaf, dev_item, device);
> +	if (device->bdev) {
> +		u64 max_total_bytes = i_size_read(device->bdev->bd_inode);
> +
> +		if (device->total_bytes > max_total_bytes) {
> +			btrfs_err(fs_info,
> +			"device total_bytes should be below %llu but found %llu",

"should be less than or equal to"

Thanks,

Josef
Anand Jain Oct. 22, 2020, 9:40 a.m. UTC | #2
On 21/10/20 10:35 pm, Josef Bacik wrote:
> On 10/21/20 12:16 AM, Anand Jain wrote:
>> btrfs_device::disk_total_bytes is set even for a seed device (the
>> comment is wrong).
>>
>> The function fill_device_from_item() does the job of reading it from the
>> item and updating btrfs_device::disk_total_bytes. So both the missing
>> device and the seed devices do have their disk_total_bytes updated.
>>
>> Furthermore, while removing the device if there is a power loss, we could
>> have a device with its total_bytes = 0, that's still valid.
>>
>> So this patch removes the check dev->disk_total_bytes == 0 in the
>> function verify_one_dev_extent(), which it does nothing in it.
>>
>> And take this opportunity to introduce a check if the device::total_bytes
>> is more than the max device size in read_one_dev().
>>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>> Reviewed-by: Nikolay Borisov <nborisov@suse.com>
>> ---
>> v2: add check if the total_bytes is more than the actual device size in
>>      read_one_dev().
>>      update change log.
>>
>>   fs/btrfs/volumes.c | 25 ++++++++++---------------
>>   1 file changed, 10 insertions(+), 15 deletions(-)
>>
>> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
>> index 2a5397fb4175..0c6049f9ace3 100644
>> --- a/fs/btrfs/volumes.c
>> +++ b/fs/btrfs/volumes.c
>> @@ -6847,6 +6847,16 @@ static int read_one_dev(struct extent_buffer 
>> *leaf,
>>       }
>>       fill_device_from_item(leaf, dev_item, device);
>> +    if (device->bdev) {
>> +        u64 max_total_bytes = i_size_read(device->bdev->bd_inode);
>> +
>> +        if (device->total_bytes > max_total_bytes) {
>> +            btrfs_err(fs_info,
>> +            "device total_bytes should be below %llu but found %llu",
> 
> "should be less than or equal to"
> 

Hm. Do you mean to say..

-               if (device->total_bytes > max_total_bytes) {
+               if (max_total_bytes <= device->total_bytes) {

OR

-               if (device->total_bytes > max_total_bytes) {
+               if (device->total_bytes <= max_total_bytes) {

The former is correct.
As device->total_bytes is the total_bytes as read from the dev_item.
And the max_total_bytes is the actual device size.



Thanks, Anand



> Thanks,
> 
> Josef
diff mbox series

Patch

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 2a5397fb4175..0c6049f9ace3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -6847,6 +6847,16 @@  static int read_one_dev(struct extent_buffer *leaf,
 	}
 
 	fill_device_from_item(leaf, dev_item, device);
+	if (device->bdev) {
+		u64 max_total_bytes = i_size_read(device->bdev->bd_inode);
+
+		if (device->total_bytes > max_total_bytes) {
+			btrfs_err(fs_info,
+			"device total_bytes should be below %llu but found %llu",
+				  max_total_bytes, device->total_bytes);
+			return -EINVAL;
+		}
+	}
 	set_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);
 	if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) &&
 	   !test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) {
@@ -7579,21 +7589,6 @@  static int verify_one_dev_extent(struct btrfs_fs_info *fs_info,
 		goto out;
 	}
 
-	/* It's possible this device is a dummy for seed device */
-	if (dev->disk_total_bytes == 0) {
-		struct btrfs_fs_devices *devs;
-
-		devs = list_first_entry(&fs_info->fs_devices->seed_list,
-					struct btrfs_fs_devices, seed_list);
-		dev = btrfs_find_device(devs, devid, NULL, NULL, false);
-		if (!dev) {
-			btrfs_err(fs_info, "failed to find seed 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",