diff options
author | Eric Sandeen <sandeen@redhat.com> | 2010-10-28 05:30:13 +0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-10-28 05:30:13 +0400 |
commit | 5b41d92437f1ae19b3f3ffa3b16589fd5df50ac0 (patch) | |
tree | ed7e1999a2349811e3cae0f0bdd53a93aea413d7 /include | |
parent | bbd08344e3df8c7c1d7aa04bc0c8c9367806e12d (diff) | |
download | linux-5b41d92437f1ae19b3f3ffa3b16589fd5df50ac0.tar.xz |
ext4: implement writeback livelock avoidance using page tagging
This is analogous to Jan Kara's commit,
f446daaea9d4a420d16c606f755f3689dcb2d0ce
mm: implement writeback livelock avoidance using page tagging
but since we forked write_cache_pages, we need to reimplement
it there (and in ext4_da_writepages, since range_cyclic handling
was moved to there)
If you start a large buffered IO to a file, and then set
fsync after it, you'll find that fsync does not complete
until the other IO stops.
If you continue re-dirtying the file (say, putting dd
with conv=notrunc in a loop), when fsync finally completes
(after all IO is done), it reports via tracing that
it has written many more pages than the file contains;
in other words it has synced and re-synced pages in
the file multiple times.
This then leads to problems with our writeback_index
update, since it advances it by pages written, and
essentially sets writeback_index off the end of the
file...
With the following patch, we only sync as much as was
dirty at the time of the sync.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/writeback.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 72a5d647a5f2..3d132bfb4f3d 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -143,6 +143,8 @@ typedef int (*writepage_t)(struct page *page, struct writeback_control *wbc, int generic_writepages(struct address_space *mapping, struct writeback_control *wbc); +void tag_pages_for_writeback(struct address_space *mapping, + pgoff_t start, pgoff_t end); int write_cache_pages(struct address_space *mapping, struct writeback_control *wbc, writepage_t writepage, void *data); |