aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/segment.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-12-16 05:04:05 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-12-22 20:18:07 -0500
commitbfad7c2d40332be6a1d7a89660bceb0f6ea1d73a (patch)
tree893b2d6ab84cdc2a7ae3b1381cf7c394711a0cce /fs/f2fs/segment.c
parent216fbd64437452d23db54ae845916facd7215caa (diff)
f2fs: introduce a new direct_IO write path
Previously, f2fs doesn't support direct IOs with high performance, which throws every write requests via the buffered write path, resulting in highly performance degradation due to memory opeations like copy_from_user. This patch introduces a new direct IO path in which every write requests are processed by generic blockdev_direct_IO() with enhanced get_block function. The get_data_block() in f2fs handles: 1. if original data blocks are allocates, then give them to blockdev. 2. otherwise, a. preallocate requested block addresses b. do not use extent cache for better performance c. give the block addresses to blockdev This policy induces that: - new allocated data are sequentially written to the disk - updated data are randomly written to the disk. - f2fs gives consistency on its file meta, not file data. Reviewed-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r--fs/f2fs/segment.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 5b890ce74b15..9f8bdd02e3a8 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -854,16 +854,14 @@ static int __get_segment_type(struct page *page, enum page_type p_type)
854 return __get_segment_type_6(page, p_type); 854 return __get_segment_type_6(page, p_type);
855} 855}
856 856
857static void do_write_page(struct f2fs_sb_info *sbi, struct page *page, 857void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
858 block_t old_blkaddr, block_t *new_blkaddr, 858 block_t old_blkaddr, block_t *new_blkaddr,
859 struct f2fs_summary *sum, struct f2fs_io_info *fio) 859 struct f2fs_summary *sum, int type)
860{ 860{
861 struct sit_info *sit_i = SIT_I(sbi); 861 struct sit_info *sit_i = SIT_I(sbi);
862 struct curseg_info *curseg; 862 struct curseg_info *curseg;
863 unsigned int old_cursegno; 863 unsigned int old_cursegno;
864 int type;
865 864
866 type = __get_segment_type(page, fio->type);
867 curseg = CURSEG_I(sbi, type); 865 curseg = CURSEG_I(sbi, type);
868 866
869 mutex_lock(&curseg->curseg_mutex); 867 mutex_lock(&curseg->curseg_mutex);
@@ -896,13 +894,22 @@ static void do_write_page(struct f2fs_sb_info *sbi, struct page *page,
896 locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr)); 894 locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr));
897 mutex_unlock(&sit_i->sentry_lock); 895 mutex_unlock(&sit_i->sentry_lock);
898 896
899 if (fio->type == NODE) 897 if (page && IS_NODESEG(type))
900 fill_node_footer_blkaddr(page, NEXT_FREE_BLKADDR(sbi, curseg)); 898 fill_node_footer_blkaddr(page, NEXT_FREE_BLKADDR(sbi, curseg));
901 899
900 mutex_unlock(&curseg->curseg_mutex);
901}
902
903static void do_write_page(struct f2fs_sb_info *sbi, struct page *page,
904 block_t old_blkaddr, block_t *new_blkaddr,
905 struct f2fs_summary *sum, struct f2fs_io_info *fio)
906{
907 int type = __get_segment_type(page, fio->type);
908
909 allocate_data_block(sbi, page, old_blkaddr, new_blkaddr, sum, type);
910
902 /* writeout dirty page into bdev */ 911 /* writeout dirty page into bdev */
903 f2fs_submit_page_mbio(sbi, page, *new_blkaddr, fio); 912 f2fs_submit_page_mbio(sbi, page, *new_blkaddr, fio);
904
905 mutex_unlock(&curseg->curseg_mutex);
906} 913}
907 914
908void write_meta_page(struct f2fs_sb_info *sbi, struct page *page) 915void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)