|
@@ -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? */
|