diff options
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r-- | fs/fs-writeback.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 3be57189efd5..68851ff2fd41 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -45,6 +45,7 @@ struct wb_writeback_work { | |||
45 | unsigned int for_kupdate:1; | 45 | unsigned int for_kupdate:1; |
46 | unsigned int range_cyclic:1; | 46 | unsigned int range_cyclic:1; |
47 | unsigned int for_background:1; | 47 | unsigned int for_background:1; |
48 | unsigned int for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ | ||
48 | enum wb_reason reason; /* why was writeback initiated? */ | 49 | enum wb_reason reason; /* why was writeback initiated? */ |
49 | 50 | ||
50 | struct list_head list; /* pending work list */ | 51 | struct list_head list; /* pending work list */ |
@@ -443,9 +444,11 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
443 | /* | 444 | /* |
444 | * Make sure to wait on the data before writing out the metadata. | 445 | * Make sure to wait on the data before writing out the metadata. |
445 | * This is important for filesystems that modify metadata on data | 446 | * This is important for filesystems that modify metadata on data |
446 | * I/O completion. | 447 | * I/O completion. We don't do it for sync(2) writeback because it has a |
448 | * separate, external IO completion path and ->sync_fs for guaranteeing | ||
449 | * inode metadata is written back correctly. | ||
447 | */ | 450 | */ |
448 | if (wbc->sync_mode == WB_SYNC_ALL) { | 451 | if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync) { |
449 | int err = filemap_fdatawait(mapping); | 452 | int err = filemap_fdatawait(mapping); |
450 | if (ret == 0) | 453 | if (ret == 0) |
451 | ret = err; | 454 | ret = err; |
@@ -578,6 +581,7 @@ static long writeback_sb_inodes(struct super_block *sb, | |||
578 | .tagged_writepages = work->tagged_writepages, | 581 | .tagged_writepages = work->tagged_writepages, |
579 | .for_kupdate = work->for_kupdate, | 582 | .for_kupdate = work->for_kupdate, |
580 | .for_background = work->for_background, | 583 | .for_background = work->for_background, |
584 | .for_sync = work->for_sync, | ||
581 | .range_cyclic = work->range_cyclic, | 585 | .range_cyclic = work->range_cyclic, |
582 | .range_start = 0, | 586 | .range_start = 0, |
583 | .range_end = LLONG_MAX, | 587 | .range_end = LLONG_MAX, |
@@ -959,7 +963,7 @@ static long wb_check_old_data_flush(struct bdi_writeback *wb) | |||
959 | /* | 963 | /* |
960 | * Retrieve work items and do the writeback they describe | 964 | * Retrieve work items and do the writeback they describe |
961 | */ | 965 | */ |
962 | long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | 966 | static long wb_do_writeback(struct bdi_writeback *wb) |
963 | { | 967 | { |
964 | struct backing_dev_info *bdi = wb->bdi; | 968 | struct backing_dev_info *bdi = wb->bdi; |
965 | struct wb_writeback_work *work; | 969 | struct wb_writeback_work *work; |
@@ -967,12 +971,6 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
967 | 971 | ||
968 | set_bit(BDI_writeback_running, &wb->bdi->state); | 972 | set_bit(BDI_writeback_running, &wb->bdi->state); |
969 | while ((work = get_next_work_item(bdi)) != NULL) { | 973 | while ((work = get_next_work_item(bdi)) != NULL) { |
970 | /* | ||
971 | * Override sync mode, in case we must wait for completion | ||
972 | * because this thread is exiting now. | ||
973 | */ | ||
974 | if (force_wait) | ||
975 | work->sync_mode = WB_SYNC_ALL; | ||
976 | 974 | ||
977 | trace_writeback_exec(bdi, work); | 975 | trace_writeback_exec(bdi, work); |
978 | 976 | ||
@@ -1021,7 +1019,7 @@ void bdi_writeback_workfn(struct work_struct *work) | |||
1021 | * rescuer as work_list needs to be drained. | 1019 | * rescuer as work_list needs to be drained. |
1022 | */ | 1020 | */ |
1023 | do { | 1021 | do { |
1024 | pages_written = wb_do_writeback(wb, 0); | 1022 | pages_written = wb_do_writeback(wb); |
1025 | trace_writeback_pages_written(pages_written); | 1023 | trace_writeback_pages_written(pages_written); |
1026 | } while (!list_empty(&bdi->work_list)); | 1024 | } while (!list_empty(&bdi->work_list)); |
1027 | } else { | 1025 | } else { |
@@ -1362,6 +1360,7 @@ void sync_inodes_sb(struct super_block *sb) | |||
1362 | .range_cyclic = 0, | 1360 | .range_cyclic = 0, |
1363 | .done = &done, | 1361 | .done = &done, |
1364 | .reason = WB_REASON_SYNC, | 1362 | .reason = WB_REASON_SYNC, |
1363 | .for_sync = 1, | ||
1365 | }; | 1364 | }; |
1366 | 1365 | ||
1367 | /* Nothing to do? */ | 1366 | /* Nothing to do? */ |