diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-fs-f2fs | 7 | ||||
-rw-r--r-- | Documentation/filesystems/f2fs.txt | 9 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 1 | ||||
-rw-r--r-- | fs/f2fs/file.c | 7 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 3 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 14 | ||||
-rw-r--r-- | fs/f2fs/super.c | 2 |
7 files changed, 33 insertions, 10 deletions
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 62dd72522d6e..6f9157f16725 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs | |||
@@ -44,6 +44,13 @@ Description: | |||
44 | Controls the FS utilization condition for the in-place-update | 44 | Controls the FS utilization condition for the in-place-update |
45 | policies. | 45 | policies. |
46 | 46 | ||
47 | What: /sys/fs/f2fs/<disk>/min_fsync_blocks | ||
48 | Date: September 2014 | ||
49 | Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> | ||
50 | Description: | ||
51 | Controls the dirty page count condition for the in-place-update | ||
52 | policies. | ||
53 | |||
47 | What: /sys/fs/f2fs/<disk>/max_small_discards | 54 | What: /sys/fs/f2fs/<disk>/max_small_discards |
48 | Date: November 2013 | 55 | Date: November 2013 |
49 | Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com> | 56 | Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com> |
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index a2046a7d0a9d..d010da85a769 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt | |||
@@ -194,13 +194,20 @@ Files in /sys/fs/f2fs/<devname> | |||
194 | updates in f2fs. There are five policies: | 194 | updates in f2fs. There are five policies: |
195 | 0: F2FS_IPU_FORCE, 1: F2FS_IPU_SSR, | 195 | 0: F2FS_IPU_FORCE, 1: F2FS_IPU_SSR, |
196 | 2: F2FS_IPU_UTIL, 3: F2FS_IPU_SSR_UTIL, | 196 | 2: F2FS_IPU_UTIL, 3: F2FS_IPU_SSR_UTIL, |
197 | 4: F2FS_IPU_DISABLE. | 197 | 4: F2FS_IPU_FSYNC, 5: F2FS_IPU_DISABLE. |
198 | 198 | ||
199 | min_ipu_util This parameter controls the threshold to trigger | 199 | min_ipu_util This parameter controls the threshold to trigger |
200 | in-place-updates. The number indicates percentage | 200 | in-place-updates. The number indicates percentage |
201 | of the filesystem utilization, and used by | 201 | of the filesystem utilization, and used by |
202 | F2FS_IPU_UTIL and F2FS_IPU_SSR_UTIL policies. | 202 | F2FS_IPU_UTIL and F2FS_IPU_SSR_UTIL policies. |
203 | 203 | ||
204 | min_fsync_blocks This parameter controls the threshold to trigger | ||
205 | in-place-updates when F2FS_IPU_FSYNC mode is set. | ||
206 | The number indicates the number of dirty pages | ||
207 | when fsync needs to flush on its call path. If | ||
208 | the number is less than this value, it triggers | ||
209 | in-place-updates. | ||
210 | |||
204 | max_victim_search This parameter controls the number of trials to | 211 | max_victim_search This parameter controls the number of trials to |
205 | find a victim segment when conducting SSR and | 212 | find a victim segment when conducting SSR and |
206 | cleaning operations. The default value is 4096 | 213 | cleaning operations. The default value is 4096 |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index ad7e9b369319..8efa170352ff 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -386,6 +386,7 @@ struct f2fs_sm_info { | |||
386 | 386 | ||
387 | unsigned int ipu_policy; /* in-place-update policy */ | 387 | unsigned int ipu_policy; /* in-place-update policy */ |
388 | unsigned int min_ipu_util; /* in-place-update threshold */ | 388 | unsigned int min_ipu_util; /* in-place-update threshold */ |
389 | unsigned int min_fsync_blocks; /* threshold for fsync */ | ||
389 | 390 | ||
390 | /* for flush command control */ | 391 | /* for flush command control */ |
391 | struct flush_cmd_control *cmd_control_info; | 392 | struct flush_cmd_control *cmd_control_info; |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 77426c7eb0f1..af06e22a0dbd 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -154,12 +154,11 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
154 | trace_f2fs_sync_file_enter(inode); | 154 | trace_f2fs_sync_file_enter(inode); |
155 | 155 | ||
156 | /* if fdatasync is triggered, let's do in-place-update */ | 156 | /* if fdatasync is triggered, let's do in-place-update */ |
157 | if (datasync) | 157 | if (get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) |
158 | set_inode_flag(fi, FI_NEED_IPU); | 158 | set_inode_flag(fi, FI_NEED_IPU); |
159 | |||
160 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 159 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
161 | if (datasync) | 160 | clear_inode_flag(fi, FI_NEED_IPU); |
162 | clear_inode_flag(fi, FI_NEED_IPU); | 161 | |
163 | if (ret) { | 162 | if (ret) { |
164 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); | 163 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); |
165 | return ret; | 164 | return ret; |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index e158d6358474..c6f627b492cd 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -1928,8 +1928,9 @@ int build_segment_manager(struct f2fs_sb_info *sbi) | |||
1928 | sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr); | 1928 | sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr); |
1929 | sm_info->rec_prefree_segments = sm_info->main_segments * | 1929 | sm_info->rec_prefree_segments = sm_info->main_segments * |
1930 | DEF_RECLAIM_PREFREE_SEGMENTS / 100; | 1930 | DEF_RECLAIM_PREFREE_SEGMENTS / 100; |
1931 | sm_info->ipu_policy = F2FS_IPU_DISABLE; | 1931 | sm_info->ipu_policy = F2FS_IPU_FSYNC; |
1932 | sm_info->min_ipu_util = DEF_MIN_IPU_UTIL; | 1932 | sm_info->min_ipu_util = DEF_MIN_IPU_UTIL; |
1933 | sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS; | ||
1933 | 1934 | ||
1934 | INIT_LIST_HEAD(&sm_info->discard_list); | 1935 | INIT_LIST_HEAD(&sm_info->discard_list); |
1935 | sm_info->nr_discards = 0; | 1936 | sm_info->nr_discards = 0; |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index bed0dc967f29..013aed2f3539 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -472,15 +472,20 @@ static inline int utilization(struct f2fs_sb_info *sbi) | |||
472 | * F2FS_IPU_UTIL - if FS utilization is over threashold, | 472 | * F2FS_IPU_UTIL - if FS utilization is over threashold, |
473 | * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over | 473 | * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over |
474 | * threashold, | 474 | * threashold, |
475 | * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash | ||
476 | * storages. IPU will be triggered only if the # of dirty | ||
477 | * pages over min_fsync_blocks. | ||
475 | * F2FS_IPUT_DISABLE - disable IPU. (=default option) | 478 | * F2FS_IPUT_DISABLE - disable IPU. (=default option) |
476 | */ | 479 | */ |
477 | #define DEF_MIN_IPU_UTIL 70 | 480 | #define DEF_MIN_IPU_UTIL 70 |
481 | #define DEF_MIN_FSYNC_BLOCKS 8 | ||
478 | 482 | ||
479 | enum { | 483 | enum { |
480 | F2FS_IPU_FORCE, | 484 | F2FS_IPU_FORCE, |
481 | F2FS_IPU_SSR, | 485 | F2FS_IPU_SSR, |
482 | F2FS_IPU_UTIL, | 486 | F2FS_IPU_UTIL, |
483 | F2FS_IPU_SSR_UTIL, | 487 | F2FS_IPU_SSR_UTIL, |
488 | F2FS_IPU_FSYNC, | ||
484 | F2FS_IPU_DISABLE, | 489 | F2FS_IPU_DISABLE, |
485 | }; | 490 | }; |
486 | 491 | ||
@@ -492,10 +497,6 @@ static inline bool need_inplace_update(struct inode *inode) | |||
492 | if (S_ISDIR(inode->i_mode)) | 497 | if (S_ISDIR(inode->i_mode)) |
493 | return false; | 498 | return false; |
494 | 499 | ||
495 | /* this is only set during fdatasync */ | ||
496 | if (is_inode_flag_set(F2FS_I(inode), FI_NEED_IPU)) | ||
497 | return true; | ||
498 | |||
499 | switch (SM_I(sbi)->ipu_policy) { | 500 | switch (SM_I(sbi)->ipu_policy) { |
500 | case F2FS_IPU_FORCE: | 501 | case F2FS_IPU_FORCE: |
501 | return true; | 502 | return true; |
@@ -511,6 +512,11 @@ static inline bool need_inplace_update(struct inode *inode) | |||
511 | if (need_SSR(sbi) && utilization(sbi) > SM_I(sbi)->min_ipu_util) | 512 | if (need_SSR(sbi) && utilization(sbi) > SM_I(sbi)->min_ipu_util) |
512 | return true; | 513 | return true; |
513 | break; | 514 | break; |
515 | case F2FS_IPU_FSYNC: | ||
516 | /* this is only set during fdatasync */ | ||
517 | if (is_inode_flag_set(F2FS_I(inode), FI_NEED_IPU)) | ||
518 | return true; | ||
519 | break; | ||
514 | case F2FS_IPU_DISABLE: | 520 | case F2FS_IPU_DISABLE: |
515 | break; | 521 | break; |
516 | } | 522 | } |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index b5af9be94a4d..ed4095e5e8a7 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -190,6 +190,7 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); | |||
190 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); | 190 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); |
191 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); | 191 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); |
192 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); | 192 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); |
193 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); | ||
193 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); | 194 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); |
194 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); | 195 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); |
195 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); | 196 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); |
@@ -204,6 +205,7 @@ static struct attribute *f2fs_attrs[] = { | |||
204 | ATTR_LIST(max_small_discards), | 205 | ATTR_LIST(max_small_discards), |
205 | ATTR_LIST(ipu_policy), | 206 | ATTR_LIST(ipu_policy), |
206 | ATTR_LIST(min_ipu_util), | 207 | ATTR_LIST(min_ipu_util), |
208 | ATTR_LIST(min_fsync_blocks), | ||
207 | ATTR_LIST(max_victim_search), | 209 | ATTR_LIST(max_victim_search), |
208 | ATTR_LIST(dir_level), | 210 | ATTR_LIST(dir_level), |
209 | ATTR_LIST(ram_thresh), | 211 | ATTR_LIST(ram_thresh), |