diff options
author | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2014-03-18 13:47:11 +0900 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2014-03-18 16:37:53 +0900 |
commit | 50c8cdb35ad8016c52fb2326ef9d65542e3a3e1b (patch) | |
tree | db261148aaa96080b35d61f8b1ac09d1fecb87a4 /fs/f2fs | |
parent | d3baf95da5b0bce9fe980eeff6140817d63fabdf (diff) | |
download | op-kernel-dev-50c8cdb35ad8016c52fb2326ef9d65542e3a3e1b.zip op-kernel-dev-50c8cdb35ad8016c52fb2326ef9d65542e3a3e1b.tar.gz |
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/f2fs')
-rw-r--r-- | fs/f2fs/checkpoint.c | 11 | ||||
-rw-r--r-- | fs/f2fs/data.c | 12 | ||||
-rw-r--r-- | fs/f2fs/node.c | 8 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 24 |
4 files changed, 36 insertions, 19 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index aef32f3..2a00c94 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, struct writeback_control *wbc) { struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); - int nrpages = nr_pages_to_skip(sbi, META); - long written; + long diff, written; /* collect a number of dirty meta pages and write together */ - if (wbc->for_kupdate || get_pages(sbi, F2FS_DIRTY_META) < nrpages) + if (wbc->for_kupdate || + get_pages(sbi, F2FS_DIRTY_META) < nr_pages_to_skip(sbi, META)) goto skip_write; /* if mounting is failed, skip writing node pages */ mutex_lock(&sbi->cp_mutex); - written = sync_meta_pages(sbi, META, nrpages); + diff = nr_pages_to_write(sbi, META, wbc); + written = sync_meta_pages(sbi, META, wbc->nr_to_write); mutex_unlock(&sbi->cp_mutex); - wbc->nr_to_write -= written; + wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); return 0; skip_write: diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3bc3809..b0c923a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -844,8 +844,6 @@ redirty_out: return AOP_WRITEPAGE_ACTIVATE; } -#define MAX_DESIRED_PAGES_WP 4096 - static int __f2fs_writepage(struct page *page, struct writeback_control *wbc, void *data) { @@ -862,7 +860,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); bool locked = false; int ret; - long excess_nrtw = 0, desired_nrtw; + long diff; /* deal with chardevs and other special file */ if (!mapping->a_ops->writepage) @@ -872,11 +870,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA)) goto skip_write; - if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) { - desired_nrtw = MAX_DESIRED_PAGES_WP; - excess_nrtw = desired_nrtw - wbc->nr_to_write; - wbc->nr_to_write = desired_nrtw; - } + diff = nr_pages_to_write(sbi, DATA, wbc); if (!S_ISDIR(inode->i_mode)) { mutex_lock(&sbi->writepages); @@ -890,7 +884,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, remove_dirty_dir_inode(inode); - wbc->nr_to_write -= excess_nrtw; + wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff); return ret; skip_write: diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 7cc146b..5e9c38e 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, struct writeback_control *wbc) { struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); - long nr_to_write = wbc->nr_to_write; + long diff; /* balancing f2fs's metadata in background */ f2fs_balance_fs_bg(sbi); @@ -1211,12 +1211,10 @@ static int f2fs_write_node_pages(struct address_space *mapping, if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE)) goto skip_write; - /* if mounting is failed, skip writing node pages */ - wbc->nr_to_write = 3 * max_hw_blocks(sbi); + diff = nr_pages_to_write(sbi, NODE, wbc); wbc->sync_mode = WB_SYNC_NONE; sync_node_pages(sbi, 0, wbc); - wbc->nr_to_write = nr_to_write - (3 * max_hw_blocks(sbi) - - wbc->nr_to_write); + wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff); return 0; skip_write: diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index bbd9761..9fc46ee 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) else return 0; } + +/* + * When writing pages, it'd better align nr_to_write for segment size. + */ +static inline long nr_pages_to_write(struct f2fs_sb_info *sbi, int type, + struct writeback_control *wbc) +{ + long nr_to_write, desired; + + if (wbc->sync_mode != WB_SYNC_NONE) + return 0; + + nr_to_write = wbc->nr_to_write; + + if (type == DATA) + desired = 4096; + else if (type == NODE) + desired = 3 * max_hw_blocks(sbi); + else + desired = MAX_BIO_BLOCKS(max_hw_blocks(sbi)); + + wbc->nr_to_write = desired; + return desired - nr_to_write; +} |