aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/segment.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2015-01-05 19:02:20 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2015-01-09 20:02:27 -0500
commit38aa0889b2504bbe68e47f51cf73bf7f0a7246bd (patch)
treebfe9f9ed78dfd70dfec64a83a87835279ecefbf3 /fs/f2fs/segment.c
parent41ef94b35c8df8e01780b4a3362246c51f3aa79b (diff)
f2fs: align direct_io'ed data to section
This patch aligns the start block address of a file for direct io to the f2fs's section size. Some flash devices manage an over 4KB-sized page as a write unit, and if the direct_io'ed data are written but not aligned to that unit, the performance can be degraded due to the partial page copies. Thus, since f2fs has a section that is well aligned to FTL units, we can align the block address to the section size so that f2fs avoids this misalignment. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r--fs/f2fs/segment.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 8144a30b1567..31c4e5702c7d 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1024,18 +1024,22 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
1024 stat_inc_seg_type(sbi, curseg); 1024 stat_inc_seg_type(sbi, curseg);
1025} 1025}
1026 1026
1027static void __allocate_new_segments(struct f2fs_sb_info *sbi, int type)
1028{
1029 struct curseg_info *curseg = CURSEG_I(sbi, type);
1030 unsigned int old_segno;
1031
1032 old_segno = curseg->segno;
1033 SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
1034 locate_dirty_segment(sbi, old_segno);
1035}
1036
1027void allocate_new_segments(struct f2fs_sb_info *sbi) 1037void allocate_new_segments(struct f2fs_sb_info *sbi)
1028{ 1038{
1029 struct curseg_info *curseg;
1030 unsigned int old_curseg;
1031 int i; 1039 int i;
1032 1040
1033 for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { 1041 for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
1034 curseg = CURSEG_I(sbi, i); 1042 __allocate_new_segments(sbi, i);
1035 old_curseg = curseg->segno;
1036 SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
1037 locate_dirty_segment(sbi, old_curseg);
1038 }
1039} 1043}
1040 1044
1041static const struct segment_allocation default_salloc_ops = { 1045static const struct segment_allocation default_salloc_ops = {
@@ -1148,11 +1152,18 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
1148{ 1152{
1149 struct sit_info *sit_i = SIT_I(sbi); 1153 struct sit_info *sit_i = SIT_I(sbi);
1150 struct curseg_info *curseg; 1154 struct curseg_info *curseg;
1155 bool direct_io = (type == CURSEG_DIRECT_IO);
1156
1157 type = direct_io ? CURSEG_WARM_DATA : type;
1151 1158
1152 curseg = CURSEG_I(sbi, type); 1159 curseg = CURSEG_I(sbi, type);
1153 1160
1154 mutex_lock(&curseg->curseg_mutex); 1161 mutex_lock(&curseg->curseg_mutex);
1155 1162
1163 /* direct_io'ed data is aligned to the segment for better performance */
1164 if (direct_io && curseg->next_blkoff)
1165 __allocate_new_segments(sbi, type);
1166
1156 *new_blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); 1167 *new_blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
1157 1168
1158 /* 1169 /*