diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-01-05 19:02:20 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-01-09 20:02:27 -0500 |
commit | 38aa0889b2504bbe68e47f51cf73bf7f0a7246bd (patch) | |
tree | bfe9f9ed78dfd70dfec64a83a87835279ecefbf3 /fs/f2fs/segment.c | |
parent | 41ef94b35c8df8e01780b4a3362246c51f3aa79b (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.c | 27 |
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 | ||
1027 | static 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 | |||
1027 | void allocate_new_segments(struct f2fs_sb_info *sbi) | 1037 | void 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 | ||
1041 | static const struct segment_allocation default_salloc_ops = { | 1045 | static 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 | /* |