Hi Chao,

On 2018/8/10 10:46, Chao Yu wrote:
> On 2018/8/1 14:04, Gao Xiang wrote:
>> this patch renames prepare_bio to erofs_grab_bio, and
>> adds a nofail option in order to retry in the bio allocator.
>>
>> Signed-off-by: Gao Xiang <[email protected]>
>> ---
>>  drivers/staging/erofs/data.c      | 12 ++++++++++--
>>  drivers/staging/erofs/internal.h  | 35 +++++++++++++++++------------------
>>  drivers/staging/erofs/unzip_vle.c |  4 ++--
>>  3 files changed, 29 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c
>> index ac263a1..2426eda 100644
>> --- a/drivers/staging/erofs/data.c
>> +++ b/drivers/staging/erofs/data.c
>> @@ -60,7 +60,8 @@ struct page *erofs_get_meta_page(struct super_block *sb,
>>              struct bio *bio;
>>              int err;
>>  
>> -            bio = prepare_bio(sb, blkaddr, 1, read_endio);
>> +            bio = erofs_grab_bio(sb, blkaddr, 1, read_endio, true);
>> +
>>              err = bio_add_page(bio, page, PAGE_SIZE, 0);
>>              BUG_ON(err != PAGE_SIZE);
>>  
>> @@ -278,7 +279,14 @@ static inline struct bio *erofs_read_raw_page(
>>              if (nblocks > BIO_MAX_PAGES)
>>                      nblocks = BIO_MAX_PAGES;
>>  
>> -            bio = prepare_bio(inode->i_sb, blknr, nblocks, read_endio);
>> +            bio = erofs_grab_bio(inode->i_sb,
>> +                    blknr, nblocks, read_endio, false);
>> +
>> +            if (unlikely(IS_ERR(bio))) {
>> +                    err = PTR_ERR(bio);
>> +                    bio = NULL;
>> +                    goto err_out;
>> +            }
>>      }
>>  
>>      err = bio_add_page(bio, page, PAGE_SIZE, 0);
>> diff --git a/drivers/staging/erofs/internal.h 
>> b/drivers/staging/erofs/internal.h
>> index 4518729..acce2d6 100644
>> --- a/drivers/staging/erofs/internal.h
>> +++ b/drivers/staging/erofs/internal.h
>> @@ -419,26 +419,25 @@ struct erofs_map_blocks {
>>  #define EROFS_GET_BLOCKS_RAW    0x0001
>>  
>>  /* data.c */
>> -static inline struct bio *prepare_bio(
>> -    struct super_block *sb,
>> -    erofs_blk_t blkaddr, unsigned nr_pages,
>> -    bio_end_io_t endio)
>> +static inline struct bio *
>> +erofs_grab_bio(struct super_block *sb,
>> +           erofs_blk_t blkaddr, unsigned nr_pages,
>> +           bio_end_io_t endio, bool nofail)
>>  {
>> -    gfp_t gfp = GFP_NOIO;
>> -    struct bio *bio = bio_alloc(gfp, nr_pages);
>> -
>> -    if (unlikely(bio == NULL) &&
>> -            (current->flags & PF_MEMALLOC)) {
>> -            do {
>> -                    nr_pages /= 2;
>> -                    if (unlikely(!nr_pages)) {
>> -                            bio = bio_alloc(gfp | __GFP_NOFAIL, 1);
>> -                            BUG_ON(bio == NULL);
>> -                            break;
>> +    const gfp_t gfp = GFP_NOIO;
>> +    struct bio *bio;
>> +
>> +    do {
>> +            if (nr_pages == 1) {
>> +                    bio = bio_alloc(gfp | (nofail ? __GFP_NOFAIL : 0), 1);
>> +                    if (unlikely(bio == NULL)) {
>> +                            DBG_BUGON(nofail);
>> +                            return ERR_PTR(-ENOMEM);
>>                      }
>> -                    bio = bio_alloc(gfp, nr_pages);
>> -            } while (bio == NULL);
>> -    }
>> +            }
>> +            bio = bio_alloc(gfp, nr_pages);
> 
> Need to cover this bio_alloc, so should initialize gfp as:
> 
> gfp_t gfp = GFP_NOIO | (nofail ? __GFP_NOFAIL : 0);
> 
> Thanks,
This patch means if bio = bio_alloc(gfp, nr_pages); fails, try to bio_alloc 
with nr_pages/2, nr_page/4... until 1...
and tag __GFP_NOFAIL with 1...

As you said offline, there is another bug :-(, let me send the next patch...

Thanks,
Gao Xiang

Reply via email to