aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-03-18 00:47:11 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-03-18 03:37:53 -0400
commit50c8cdb35ad8016c52fb2326ef9d65542e3a3e1b (patch)
treedb261148aaa96080b35d61f8b1ac09d1fecb87a4 /fs
parentd3baf95da5b0bce9fe980eeff6140817d63fabdf (diff)
f2fs: introduce nr_pages_to_write for segment alignment
This patch introduces nr_pages_to_write to align page writes to the segment or other operational unit size, which can be tuned according to the system environment. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/checkpoint.c11
-rw-r--r--fs/f2fs/data.c12
-rw-r--r--fs/f2fs/node.c8
-rw-r--r--fs/f2fs/segment.h24
4 files changed, 36 insertions, 19 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index aef32f36e2f3..2a00c94726fb 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -187,18 +187,19 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
187 struct writeback_control *wbc) 187 struct writeback_control *wbc)
188{ 188{
189 struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); 189 struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb);
190 int nrpages = nr_pages_to_skip(sbi, META); 190 long diff, written;
191 long written;
192 191
193 /* collect a number of dirty meta pages and write together */ 192 /* collect a number of dirty meta pages and write together */
194 if (wbc->for_kupdate || get_pages(sbi, F2FS_DIRTY_META) < nrpages) 193 if (wbc->for_kupdate ||
194 get_pages(sbi, F2FS_DIRTY_META) < nr_pages_to_skip(sbi, META))
195 goto skip_write; 195 goto skip_write;
196 196
197 /* if mounting is failed, skip writing node pages */ 197 /* if mounting is failed, skip writing node pages */
198 mutex_lock(&sbi->cp_mutex); 198 mutex_lock(&sbi->cp_mutex);
199 written = sync_meta_pages(sbi, META, nrpages); 199 diff = nr_pages_to_write(sbi, META, wbc);
200 written = sync_meta_pages(sbi, META, wbc->nr_to_write);
200 mutex_unlock(&sbi->cp_mutex); 201 mutex_unlock(&sbi->cp_mutex);
201 wbc->nr_to_write -= written; 202 wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff);
202 return 0; 203 return 0;
203 204
204skip_write: 205skip_write:
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 3bc380942068..b0c923aef229 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -844,8 +844,6 @@ redirty_out:
844 return AOP_WRITEPAGE_ACTIVATE; 844 return AOP_WRITEPAGE_ACTIVATE;
845} 845}
846 846
847#define MAX_DESIRED_PAGES_WP 4096
848
849static int __f2fs_writepage(struct page *page, struct writeback_control *wbc, 847static int __f2fs_writepage(struct page *page, struct writeback_control *wbc,
850 void *data) 848 void *data)
851{ 849{
@@ -862,7 +860,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
862 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 860 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
863 bool locked = false; 861 bool locked = false;
864 int ret; 862 int ret;
865 long excess_nrtw = 0, desired_nrtw; 863 long diff;
866 864
867 /* deal with chardevs and other special file */ 865 /* deal with chardevs and other special file */
868 if (!mapping->a_ops->writepage) 866 if (!mapping->a_ops->writepage)
@@ -872,11 +870,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
872 get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA)) 870 get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA))
873 goto skip_write; 871 goto skip_write;
874 872
875 if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) { 873 diff = nr_pages_to_write(sbi, DATA, wbc);
876 desired_nrtw = MAX_DESIRED_PAGES_WP;
877 excess_nrtw = desired_nrtw - wbc->nr_to_write;
878 wbc->nr_to_write = desired_nrtw;
879 }
880 874
881 if (!S_ISDIR(inode->i_mode)) { 875 if (!S_ISDIR(inode->i_mode)) {
882 mutex_lock(&sbi->writepages); 876 mutex_lock(&sbi->writepages);
@@ -890,7 +884,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
890 884
891 remove_dirty_dir_inode(inode); 885 remove_dirty_dir_inode(inode);
892 886
893 wbc->nr_to_write -= excess_nrtw; 887 wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff);
894 return ret; 888 return ret;
895 889
896skip_write: 890skip_write:
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 7cc146bcbfed..5e9c38e846a5 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1202,7 +1202,7 @@ static int f2fs_write_node_pages(struct address_space *mapping,
1202 struct writeback_control *wbc) 1202 struct writeback_control *wbc)
1203{ 1203{
1204 struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); 1204 struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb);
1205 long nr_to_write = wbc->nr_to_write; 1205 long diff;
1206 1206
1207 /* balancing f2fs's metadata in background */ 1207 /* balancing f2fs's metadata in background */
1208 f2fs_balance_fs_bg(sbi); 1208 f2fs_balance_fs_bg(sbi);
@@ -1211,12 +1211,10 @@ static int f2fs_write_node_pages(struct address_space *mapping,
1211 if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE)) 1211 if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE))
1212 goto skip_write; 1212 goto skip_write;
1213 1213
1214 /* if mounting is failed, skip writing node pages */ 1214 diff = nr_pages_to_write(sbi, NODE, wbc);
1215 wbc->nr_to_write = 3 * max_hw_blocks(sbi);
1216 wbc->sync_mode = WB_SYNC_NONE; 1215 wbc->sync_mode = WB_SYNC_NONE;
1217 sync_node_pages(sbi, 0, wbc); 1216 sync_node_pages(sbi, 0, wbc);
1218 wbc->nr_to_write = nr_to_write - (3 * max_hw_blocks(sbi) - 1217 wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff);
1219 wbc->nr_to_write);
1220 return 0; 1218 return 0;
1221 1219
1222skip_write: 1220skip_write:
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index bbd976100d14..9fc46ee27bb8 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -683,3 +683,27 @@ static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type)
683 else 683 else
684 return 0; 684 return 0;
685} 685}
686
687/*
688 * When writing pages, it'd better align nr_to_write for segment size.
689 */
690static inline long nr_pages_to_write(struct f2fs_sb_info *sbi, int type,
691 struct writeback_control *wbc)
692{
693 long nr_to_write, desired;
694
695 if (wbc->sync_mode != WB_SYNC_NONE)
696 return 0;
697
698 nr_to_write = wbc->nr_to_write;
699
700 if (type == DATA)
701 desired = 4096;
702 else if (type == NODE)
703 desired = 3 * max_hw_blocks(sbi);
704 else
705 desired = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
706
707 wbc->nr_to_write = desired;
708 return desired - nr_to_write;
709}