diff options
author | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-11-29 20:10:31 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-12-22 20:18:05 -0500 |
commit | 187b5b8b3dfcfc73126f2743c89cc47df3bf07be (patch) | |
tree | 0be0b06f1c04b8d87037250317e09048643d0d12 /fs/f2fs | |
parent | 8f99a946f360c4083d6e323e10a5928e1ce385a4 (diff) |
f2fs: remove the own bi_private allocation
Previously f2fs allocates its own bi_private data structure all the time even
though we don't use it. But, can we remove this bi_private allocation?
This patch removes such the additional bi_private allocation.
1. Retrieve f2fs_sb_info from its page->mapping->host->i_sb.
- This removes the usecases of bi_private in end_io.
2. Use bi_private only when we really need it.
- The bi_private is used only when the checkpoint procedure is conducted.
- When conducting the checkpoint, f2fs submits a META_FLUSH bio to wait its bio
completion.
- Since we have no dependancies to remove bi_private now, let's just use
bi_private pointer as the completion pointer.
Reviewed-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/segment.c | 43 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 7 |
2 files changed, 16 insertions, 34 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 03878634a0fe..0db40271f0d8 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -791,7 +791,7 @@ static void f2fs_end_io_write(struct bio *bio, int err) | |||
791 | { | 791 | { |
792 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 792 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
793 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 793 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; |
794 | struct bio_private *p = bio->bi_private; | 794 | struct f2fs_sb_info *sbi = F2FS_SB(bvec->bv_page->mapping->host->i_sb); |
795 | 795 | ||
796 | do { | 796 | do { |
797 | struct page *page = bvec->bv_page; | 797 | struct page *page = bvec->bv_page; |
@@ -802,21 +802,21 @@ static void f2fs_end_io_write(struct bio *bio, int err) | |||
802 | SetPageError(page); | 802 | SetPageError(page); |
803 | if (page->mapping) | 803 | if (page->mapping) |
804 | set_bit(AS_EIO, &page->mapping->flags); | 804 | set_bit(AS_EIO, &page->mapping->flags); |
805 | set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG); | 805 | |
806 | p->sbi->sb->s_flags |= MS_RDONLY; | 806 | set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); |
807 | sbi->sb->s_flags |= MS_RDONLY; | ||
807 | } | 808 | } |
808 | end_page_writeback(page); | 809 | end_page_writeback(page); |
809 | dec_page_count(p->sbi, F2FS_WRITEBACK); | 810 | dec_page_count(sbi, F2FS_WRITEBACK); |
810 | } while (bvec >= bio->bi_io_vec); | 811 | } while (bvec >= bio->bi_io_vec); |
811 | 812 | ||
812 | if (p->is_sync) | 813 | if (bio->bi_private) |
813 | complete(p->wait); | 814 | complete(bio->bi_private); |
814 | 815 | ||
815 | if (!get_pages(p->sbi, F2FS_WRITEBACK) && | 816 | if (!get_pages(sbi, F2FS_WRITEBACK) && |
816 | !list_empty(&p->sbi->cp_wait.task_list)) | 817 | !list_empty(&sbi->cp_wait.task_list)) |
817 | wake_up(&p->sbi->cp_wait); | 818 | wake_up(&sbi->cp_wait); |
818 | 819 | ||
819 | kfree(p); | ||
820 | bio_put(bio); | 820 | bio_put(bio); |
821 | } | 821 | } |
822 | 822 | ||
@@ -838,7 +838,6 @@ static void do_submit_bio(struct f2fs_sb_info *sbi, | |||
838 | int rw = sync ? WRITE_SYNC : WRITE; | 838 | int rw = sync ? WRITE_SYNC : WRITE; |
839 | enum page_type btype = PAGE_TYPE_OF_BIO(type); | 839 | enum page_type btype = PAGE_TYPE_OF_BIO(type); |
840 | struct f2fs_bio_info *io = &sbi->write_io[btype]; | 840 | struct f2fs_bio_info *io = &sbi->write_io[btype]; |
841 | struct bio_private *p; | ||
842 | 841 | ||
843 | if (!io->bio) | 842 | if (!io->bio) |
844 | return; | 843 | return; |
@@ -851,18 +850,16 @@ static void do_submit_bio(struct f2fs_sb_info *sbi, | |||
851 | 850 | ||
852 | trace_f2fs_submit_write_bio(sbi->sb, rw, btype, io->bio); | 851 | trace_f2fs_submit_write_bio(sbi->sb, rw, btype, io->bio); |
853 | 852 | ||
854 | p = io->bio->bi_private; | 853 | /* |
855 | p->sbi = sbi; | 854 | * META_FLUSH is only from the checkpoint procedure, and we should wait |
856 | io->bio->bi_end_io = f2fs_end_io_write; | 855 | * this metadata bio for FS consistency. |
857 | 856 | */ | |
858 | if (type == META_FLUSH) { | 857 | if (type == META_FLUSH) { |
859 | DECLARE_COMPLETION_ONSTACK(wait); | 858 | DECLARE_COMPLETION_ONSTACK(wait); |
860 | p->is_sync = true; | 859 | io->bio->bi_private = &wait; |
861 | p->wait = &wait; | ||
862 | submit_bio(rw, io->bio); | 860 | submit_bio(rw, io->bio); |
863 | wait_for_completion(&wait); | 861 | wait_for_completion(&wait); |
864 | } else { | 862 | } else { |
865 | p->is_sync = false; | ||
866 | submit_bio(rw, io->bio); | 863 | submit_bio(rw, io->bio); |
867 | } | 864 | } |
868 | io->bio = NULL; | 865 | io->bio = NULL; |
@@ -897,18 +894,10 @@ static void submit_write_page(struct f2fs_sb_info *sbi, struct page *page, | |||
897 | do_submit_bio(sbi, type, false); | 894 | do_submit_bio(sbi, type, false); |
898 | alloc_new: | 895 | alloc_new: |
899 | if (io->bio == NULL) { | 896 | if (io->bio == NULL) { |
900 | struct bio_private *priv; | ||
901 | retry: | ||
902 | priv = kmalloc(sizeof(struct bio_private), GFP_NOFS); | ||
903 | if (!priv) { | ||
904 | cond_resched(); | ||
905 | goto retry; | ||
906 | } | ||
907 | |||
908 | bio_blocks = MAX_BIO_BLOCKS(max_hw_blocks(sbi)); | 897 | bio_blocks = MAX_BIO_BLOCKS(max_hw_blocks(sbi)); |
909 | io->bio = f2fs_bio_alloc(bdev, bio_blocks); | 898 | io->bio = f2fs_bio_alloc(bdev, bio_blocks); |
910 | io->bio->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); | 899 | io->bio->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); |
911 | io->bio->bi_private = priv; | 900 | io->bio->bi_end_io = f2fs_end_io_write; |
912 | /* | 901 | /* |
913 | * The end_io will be assigned at the sumbission phase. | 902 | * The end_io will be assigned at the sumbission phase. |
914 | * Until then, let bio_add_page() merge consecutive IOs as much | 903 | * Until then, let bio_add_page() merge consecutive IOs as much |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 7fea2ee8a5da..26812fc0fa12 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -92,13 +92,6 @@ | |||
92 | #define MAX_BIO_BLOCKS(max_hw_blocks) \ | 92 | #define MAX_BIO_BLOCKS(max_hw_blocks) \ |
93 | (min((int)max_hw_blocks, BIO_MAX_PAGES)) | 93 | (min((int)max_hw_blocks, BIO_MAX_PAGES)) |
94 | 94 | ||
95 | /* during checkpoint, bio_private is used to synchronize the last bio */ | ||
96 | struct bio_private { | ||
97 | struct f2fs_sb_info *sbi; | ||
98 | bool is_sync; | ||
99 | struct completion *wait; | ||
100 | }; | ||
101 | |||
102 | /* | 95 | /* |
103 | * indicate a block allocation direction: RIGHT and LEFT. | 96 | * indicate a block allocation direction: RIGHT and LEFT. |
104 | * RIGHT means allocating new sections towards the end of volume. | 97 | * RIGHT means allocating new sections towards the end of volume. |