Re: [PATCH 3/5] btrfs: extent_io: Kill the BUG_ON() in flush_write_bio()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2019/1/17 下午4:22, Nikolay Borisov wrote:
> 
> 
> On 17.01.19 г. 9:48 ч., Qu Wenruo wrote:
>> This BUG_ON() is really just a crappy way to workaround the _must_check
>> attribute of submit_one_bio().
>>
>> Now kill the BUG_ON() and allow flush_write_bio() to return error
>> number.
>>
>> Also add _must_check attribute to flush_write_bio(), and modify all
>> callers to handle the possible error returned.
>>
>> Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
>> ---
>>  fs/btrfs/extent_io.c | 64 +++++++++++++++++++++++++++++++-------------
>>  1 file changed, 46 insertions(+), 18 deletions(-)
>>
>> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
>> index 8a2335713a2d..a773bc46badc 100644
>> --- a/fs/btrfs/extent_io.c
>> +++ b/fs/btrfs/extent_io.c
>> @@ -169,15 +169,15 @@ static int __must_check submit_one_bio(struct bio *bio, int mirror_num,
>>  	return blk_status_to_errno(ret);
>>  }
>>  
>> -static void flush_write_bio(struct extent_page_data *epd)
>> +static int __must_check flush_write_bio(struct extent_page_data *epd)
>>  {
>> -	if (epd->bio) {
>> -		int ret;
>> +	int ret = 0;
>>  
>> +	if (epd->bio) {
>>  		ret = submit_one_bio(epd->bio, 0, 0);
>> -		BUG_ON(ret < 0); /* -ENOMEM */
>>  		epd->bio = NULL;
>>  	}
>> +	return ret;
>>  }
>>  
>>  int __init extent_io_init(void)
>> @@ -3509,8 +3509,10 @@ lock_extent_buffer_for_io(struct extent_buffer *eb,
>>  	int ret = 0;
>>  
>>  	if (!btrfs_try_tree_write_lock(eb)) {
>> +		ret = flush_write_bio(epd);
>> +		if (ret < 0)
>> +			return ret;
>>  		flush = 1;
>> -		flush_write_bio(epd);
>>  		btrfs_tree_lock(eb);
>>  	}
>>  
>> @@ -3519,7 +3521,9 @@ lock_extent_buffer_for_io(struct extent_buffer *eb,
>>  		if (!epd->sync_io)
>>  			return 0;
>>  		if (!flush) {
>> -			flush_write_bio(epd);
>> +			ret = flush_write_bio(epd);
>> +			if (ret < 0)
>> +				return ret;
>>  			flush = 1;
>>  		}
>>  		while (1) {
>> @@ -3560,7 +3564,9 @@ lock_extent_buffer_for_io(struct extent_buffer *eb,
>>  
>>  		if (!trylock_page(p)) {
>>  			if (!flush) {
>> -				flush_write_bio(epd);
>> +				ret = flush_write_bio(epd);
>> +				if (ret < 0)
>> +					return ret;
> 
> Can't you end up with partially locked pages here? Are you sure that
> flush_write_bio will ALWAYS be executed when i = 0? If that\'s the case
> then I think an assert(i == 0) is in order there.

An ASSERT() indeed makes sense here.

Although I could also make it better by recording the failed page number
and unlock those already locked pages.

I'm OK either way.

Thanks,
Qu

> 
>>  				flush = 1;
>>  			}
>>  			lock_page(p);
> 
> <snip>
> 



[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux