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 | |
parent | 87354e5de04fe727227ff619af164202adcfa4d4 (diff) | |
download | linux-76341cabbdad65c10a4162e9dfa82a6342afc02f.tar.gz linux-76341cabbdad65c10a4162e9dfa82a6342afc02f.tar.bz2 linux-76341cabbdad65c10a4162e9dfa82a6342afc02f.zip |
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')
-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) } EXPORT_SYMBOL(filemap_check_errors); +static int filemap_check_and_keep_errors(struct address_space *mapping) +{ + /* Check for outstanding write errors */ + if (test_bit(AS_EIO, &mapping->flags)) + return -EIO; + if (test_bit(AS_ENOSPC, &mapping->flags)) + return -ENOSPC; + return 0; +} + /** * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range * @mapping: address space structure to write @@ -453,15 +463,17 @@ EXPORT_SYMBOL(filemap_fdatawait_range); * call sites are system-wide / filesystem-wide data flushers: e.g. sync(2), * fsfreeze(8) */ -void filemap_fdatawait_keep_errors(struct address_space *mapping) +int filemap_fdatawait_keep_errors(struct address_space *mapping) { loff_t i_size = i_size_read(mapping->host); if (i_size == 0) - return; + return 0; __filemap_fdatawait_range(mapping, 0, i_size - 1); + return filemap_check_and_keep_errors(mapping); } +EXPORT_SYMBOL(filemap_fdatawait_keep_errors); /** * filemap_fdatawait - wait for all under-writeback pages to complete |