diff options
| -rw-r--r-- | fs/f2fs/data.c | 5 | ||||
| -rw-r--r-- | fs/f2fs/f2fs.h | 2 | ||||
| -rw-r--r-- | fs/f2fs/segment.c | 33 | ||||
| -rw-r--r-- | fs/f2fs/segment.h | 3 |
4 files changed, 25 insertions, 18 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 444c2a6fbaa0..655aeabc1dd4 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
| @@ -343,11 +343,12 @@ int f2fs_readpage(struct f2fs_sb_info *sbi, struct page *page, | |||
| 343 | down_read(&sbi->bio_sem); | 343 | down_read(&sbi->bio_sem); |
| 344 | 344 | ||
| 345 | /* Allocate a new bio */ | 345 | /* Allocate a new bio */ |
| 346 | bio = f2fs_bio_alloc(bdev, blk_addr << (sbi->log_blocksize - 9), | 346 | bio = f2fs_bio_alloc(bdev, 1); |
| 347 | 1, GFP_NOFS | __GFP_HIGH); | ||
| 348 | 347 | ||
| 349 | /* Initialize the bio */ | 348 | /* Initialize the bio */ |
| 349 | bio->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); | ||
| 350 | bio->bi_end_io = read_end_io; | 350 | bio->bi_end_io = read_end_io; |
| 351 | |||
| 351 | if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) { | 352 | if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) { |
| 352 | kfree(bio->bi_private); | 353 | kfree(bio->bi_private); |
| 353 | bio_put(bio); | 354 | bio_put(bio); |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 8c3f1ef6ace2..2bce3a62c0ba 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
| @@ -924,7 +924,7 @@ void clear_prefree_segments(struct f2fs_sb_info *); | |||
| 924 | int npages_for_summary_flush(struct f2fs_sb_info *); | 924 | int npages_for_summary_flush(struct f2fs_sb_info *); |
| 925 | void allocate_new_segments(struct f2fs_sb_info *); | 925 | void allocate_new_segments(struct f2fs_sb_info *); |
| 926 | struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); | 926 | struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); |
| 927 | struct bio *f2fs_bio_alloc(struct block_device *, sector_t, int, gfp_t); | 927 | struct bio *f2fs_bio_alloc(struct block_device *, int); |
| 928 | void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync); | 928 | void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync); |
| 929 | int write_meta_page(struct f2fs_sb_info *, struct page *, | 929 | int write_meta_page(struct f2fs_sb_info *, struct page *, |
| 930 | struct writeback_control *); | 930 | struct writeback_control *); |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 8894b399770d..1b26e4ea1016 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
| @@ -643,23 +643,21 @@ static void f2fs_end_io_write(struct bio *bio, int err) | |||
| 643 | bio_put(bio); | 643 | bio_put(bio); |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | struct bio *f2fs_bio_alloc(struct block_device *bdev, sector_t first_sector, | 646 | struct bio *f2fs_bio_alloc(struct block_device *bdev, int npages) |
| 647 | int nr_vecs, gfp_t gfp_flags) | ||
| 648 | { | 647 | { |
| 649 | struct bio *bio; | 648 | struct bio *bio; |
| 650 | 649 | struct bio_private *priv; | |
| 651 | /* allocate new bio */ | ||
| 652 | bio = bio_alloc(gfp_flags, nr_vecs); | ||
| 653 | |||
| 654 | bio->bi_bdev = bdev; | ||
| 655 | bio->bi_sector = first_sector; | ||
| 656 | retry: | 650 | retry: |
| 657 | bio->bi_private = kmalloc(sizeof(struct bio_private), | 651 | priv = kmalloc(sizeof(struct bio_private), GFP_NOFS); |
| 658 | GFP_NOFS | __GFP_HIGH); | 652 | if (!priv) { |
| 659 | if (!bio->bi_private) { | ||
| 660 | cond_resched(); | 653 | cond_resched(); |
| 661 | goto retry; | 654 | goto retry; |
| 662 | } | 655 | } |
| 656 | |||
| 657 | /* No failure on bio allocation */ | ||
| 658 | bio = bio_alloc(GFP_NOIO, npages); | ||
| 659 | bio->bi_bdev = bdev; | ||
| 660 | bio->bi_private = priv; | ||
| 663 | return bio; | 661 | return bio; |
| 664 | } | 662 | } |
| 665 | 663 | ||
| @@ -711,10 +709,15 @@ static void submit_write_page(struct f2fs_sb_info *sbi, struct page *page, | |||
| 711 | if (sbi->bio[type] && sbi->last_block_in_bio[type] != blk_addr - 1) | 709 | if (sbi->bio[type] && sbi->last_block_in_bio[type] != blk_addr - 1) |
| 712 | do_submit_bio(sbi, type, false); | 710 | do_submit_bio(sbi, type, false); |
| 713 | alloc_new: | 711 | alloc_new: |
| 714 | if (sbi->bio[type] == NULL) | 712 | if (sbi->bio[type] == NULL) { |
| 715 | sbi->bio[type] = f2fs_bio_alloc(bdev, | 713 | sbi->bio[type] = f2fs_bio_alloc(bdev, bio_get_nr_vecs(bdev)); |
| 716 | blk_addr << (sbi->log_blocksize - 9), | 714 | sbi->bio[type]->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); |
| 717 | bio_get_nr_vecs(bdev), GFP_NOFS | __GFP_HIGH); | 715 | /* |
| 716 | * The end_io will be assigned at the sumbission phase. | ||
| 717 | * Until then, let bio_add_page() merge consecutive IOs as much | ||
| 718 | * as possible. | ||
| 719 | */ | ||
| 720 | } | ||
| 718 | 721 | ||
| 719 | if (bio_add_page(sbi->bio[type], page, PAGE_CACHE_SIZE, 0) < | 722 | if (bio_add_page(sbi->bio[type], page, PAGE_CACHE_SIZE, 0) < |
| 720 | PAGE_CACHE_SIZE) { | 723 | PAGE_CACHE_SIZE) { |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 2c445f8947c9..0948405af6f5 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
| @@ -82,6 +82,9 @@ | |||
| 82 | (BITS_TO_LONGS(nr) * sizeof(unsigned long)) | 82 | (BITS_TO_LONGS(nr) * sizeof(unsigned long)) |
| 83 | #define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments) | 83 | #define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments) |
| 84 | 84 | ||
| 85 | #define SECTOR_FROM_BLOCK(sbi, blk_addr) \ | ||
| 86 | (blk_addr << ((sbi)->log_blocksize - F2FS_LOG_SECTOR_SIZE)) | ||
| 87 | |||
| 85 | /* during checkpoint, bio_private is used to synchronize the last bio */ | 88 | /* during checkpoint, bio_private is used to synchronize the last bio */ |
| 86 | struct bio_private { | 89 | struct bio_private { |
| 87 | struct f2fs_sb_info *sbi; | 90 | struct f2fs_sb_info *sbi; |
