diff options
| author | Jeff Layton <jlayton@redhat.com> | 2017-07-06 07:02:22 -0400 |
|---|---|---|
| committer | Jeff Layton <jlayton@redhat.com> | 2017-07-06 07:02:22 -0400 |
| commit | 76341cabbdad65c10a4162e9dfa82a6342afc02f (patch) | |
| tree | 92413633a5fc6554fecd37842a4bcfd06fde0adb /mm/filemap.c | |
| parent | 87354e5de04fe727227ff619af164202adcfa4d4 (diff) | |
jbd2: don't clear and reset errors after waiting on writeback
Resetting this flag is almost certainly racy, and will be problematic
with some coming changes.
Make filemap_fdatawait_keep_errors return int, but not clear the flag(s).
Have jbd2 call it instead of filemap_fdatawait and don't attempt to
re-set the error flag if it fails.
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'mm/filemap.c')
| -rw-r--r-- | mm/filemap.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 6f1be573a5e6..e5711b2728f4 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -309,6 +309,16 @@ int filemap_check_errors(struct address_space *mapping) | |||
| 309 | } | 309 | } |
| 310 | EXPORT_SYMBOL(filemap_check_errors); | 310 | EXPORT_SYMBOL(filemap_check_errors); |
| 311 | 311 | ||
| 312 | static int filemap_check_and_keep_errors(struct address_space *mapping) | ||
| 313 | { | ||
| 314 | /* Check for outstanding write errors */ | ||
| 315 | if (test_bit(AS_EIO, &mapping->flags)) | ||
| 316 | return -EIO; | ||
| 317 | if (test_bit(AS_ENOSPC, &mapping->flags)) | ||
| 318 | return -ENOSPC; | ||
| 319 | return 0; | ||
| 320 | } | ||
| 321 | |||
| 312 | /** | 322 | /** |
| 313 | * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range | 323 | * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range |
| 314 | * @mapping: address space structure to write | 324 | * @mapping: address space structure to write |
| @@ -453,15 +463,17 @@ EXPORT_SYMBOL(filemap_fdatawait_range); | |||
| 453 | * call sites are system-wide / filesystem-wide data flushers: e.g. sync(2), | 463 | * call sites are system-wide / filesystem-wide data flushers: e.g. sync(2), |
| 454 | * fsfreeze(8) | 464 | * fsfreeze(8) |
| 455 | */ | 465 | */ |
| 456 | void filemap_fdatawait_keep_errors(struct address_space *mapping) | 466 | int filemap_fdatawait_keep_errors(struct address_space *mapping) |
| 457 | { | 467 | { |
| 458 | loff_t i_size = i_size_read(mapping->host); | 468 | loff_t i_size = i_size_read(mapping->host); |
| 459 | 469 | ||
| 460 | if (i_size == 0) | 470 | if (i_size == 0) |
| 461 | return; | 471 | return 0; |
| 462 | 472 | ||
| 463 | __filemap_fdatawait_range(mapping, 0, i_size - 1); | 473 | __filemap_fdatawait_range(mapping, 0, i_size - 1); |
| 474 | return filemap_check_and_keep_errors(mapping); | ||
| 464 | } | 475 | } |
| 476 | EXPORT_SYMBOL(filemap_fdatawait_keep_errors); | ||
| 465 | 477 | ||
| 466 | /** | 478 | /** |
| 467 | * filemap_fdatawait - wait for all under-writeback pages to complete | 479 | * filemap_fdatawait - wait for all under-writeback pages to complete |
