f2fs: avoid small data writes by skipping writepages
authorJaegeuk Kim <jaegeuk.kim@samsung.com>
Tue, 18 Mar 2014 03:40:49 +0000 (12:40 +0900)
committerJaegeuk Kim <jaegeuk.kim@samsung.com>
Tue, 18 Mar 2014 04:58:59 +0000 (13:58 +0900)
This patch introduces nr_pages_to_skip(sbi, type) to determine writepages can
be skipped.
The dentry, node, and meta pages can be conrolled by F2FS without breaking the
FS consistency.

Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/node.c
fs/f2fs/segment.h

index 4c0e98ddf3dbb60b322c2225f913ffe18bc923ac..1f52b70ff9d19575b18d8ea24f80ec9023490e43 100644 (file)
@@ -187,7 +187,7 @@ 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 = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
+       int nrpages = nr_pages_to_skip(sbi, META);
        long written;
 
        if (wbc->for_kupdate)
@@ -682,7 +682,7 @@ retry:
        inode = igrab(entry->inode);
        spin_unlock(&sbi->dir_inode_lock);
        if (inode) {
-               filemap_flush(inode->i_mapping);
+               filemap_fdatawrite(inode->i_mapping);
                iput(inode);
        } else {
                /*
index 101b4cd4170df13470626f0b0f6ad6a154230ac4..e3b7cfa17b99c2568666eb201360cc6d538344cf 100644 (file)
@@ -868,6 +868,10 @@ static int f2fs_write_data_pages(struct address_space *mapping,
        if (!mapping->a_ops->writepage)
                return 0;
 
+       if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
+                       get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA))
+               return 0;
+
        if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) {
                desired_nrtw = MAX_DESIRED_PAGES_WP;
                excess_nrtw = desired_nrtw - wbc->nr_to_write;
index 3e36240d81c107109957d224f314a0c3f9b83581..cb514f1896abc27d672c7d52ef320968b3d8bb0b 100644 (file)
@@ -1198,12 +1198,6 @@ redirty_out:
        return AOP_WRITEPAGE_ACTIVATE;
 }
 
-/*
- * It is very important to gather dirty pages and write at once, so that we can
- * submit a big bio without interfering other data writes.
- * Be default, 512 pages (2MB) * 3 node types, is more reasonable.
- */
-#define COLLECT_DIRTY_NODES    1536
 static int f2fs_write_node_pages(struct address_space *mapping,
                            struct writeback_control *wbc)
 {
@@ -1214,7 +1208,7 @@ static int f2fs_write_node_pages(struct address_space *mapping,
        f2fs_balance_fs_bg(sbi);
 
        /* collect a number of dirty node pages and write together */
-       if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES)
+       if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE))
                return 0;
 
        /* if mounting is failed, skip writing node pages */
index c3d5e3689ffc184eed3bda338efe6ca90c5351de..bbd976100d142f6053c9ef346022e75e2084ec01 100644 (file)
@@ -664,3 +664,22 @@ static inline unsigned int max_hw_blocks(struct f2fs_sb_info *sbi)
        struct request_queue *q = bdev_get_queue(bdev);
        return SECTOR_TO_BLOCK(sbi, queue_max_sectors(q));
 }
+
+/*
+ * It is very important to gather dirty pages and write at once, so that we can
+ * submit a big bio without interfering other data writes.
+ * By default, 512 pages for directory data,
+ * 512 pages (2MB) * 3 for three types of nodes, and
+ * max_bio_blocks for meta are set.
+ */
+static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type)
+{
+       if (type == DATA)
+               return sbi->blocks_per_seg;
+       else if (type == NODE)
+               return 3 * sbi->blocks_per_seg;
+       else if (type == META)
+               return MAX_BIO_BLOCKS(max_hw_blocks(sbi));
+       else
+               return 0;
+}