sync: don't block the flusher thread waiting on IO
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / fs-writeback.c
index 3be5718..a85ac4e 100644 (file)
@@ -45,6 +45,7 @@ struct wb_writeback_work {
        unsigned int for_kupdate:1;
        unsigned int range_cyclic:1;
        unsigned int for_background:1;
+       unsigned int for_sync:1;        /* sync(2) WB_SYNC_ALL writeback */
        enum wb_reason reason;          /* why was writeback initiated? */
 
        struct list_head list;          /* pending work list */
@@ -443,9 +444,11 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
        /*
         * Make sure to wait on the data before writing out the metadata.
         * This is important for filesystems that modify metadata on data
-        * I/O completion.
+        * I/O completion. We don't do it for sync(2) writeback because it has a
+        * separate, external IO completion path and ->sync_fs for guaranteeing
+        * inode metadata is written back correctly.
         */
-       if (wbc->sync_mode == WB_SYNC_ALL) {
+       if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync) {
                int err = filemap_fdatawait(mapping);
                if (ret == 0)
                        ret = err;
@@ -578,6 +581,7 @@ static long writeback_sb_inodes(struct super_block *sb,
                .tagged_writepages      = work->tagged_writepages,
                .for_kupdate            = work->for_kupdate,
                .for_background         = work->for_background,
+               .for_sync               = work->for_sync,
                .range_cyclic           = work->range_cyclic,
                .range_start            = 0,
                .range_end              = LLONG_MAX,
@@ -1362,6 +1366,7 @@ void sync_inodes_sb(struct super_block *sb)
                .range_cyclic   = 0,
                .done           = &done,
                .reason         = WB_REASON_SYNC,
+               .for_sync       = 1,
        };
 
        /* Nothing to do? */