aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@redhat.com>2010-10-27 21:30:13 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-10-27 21:30:13 -0400
commit72f84e6560d18d60a091df27edf81409be6641cb (patch)
treee2fa11476b074f8526d620820f8b2e86e8a11412 /fs/ext4/inode.c
parent5b41d92437f1ae19b3f3ffa3b16589fd5df50ac0 (diff)
ext4: update writeback_index based on last page scanned
As pointed out in a prior patch, updating the mapping's writeback_index based on pages written isn't quite right; what the writeback index is really supposed to reflect is the next page which should be scanned for writeback during periodic flush. As in write_cache_pages(), write_cache_pages_da() does this scanning for us as we assemble the mpd for later writeout. If we keep track of the next page after the current scan, we can easily update writeback_index without worrying about pages written vs. pages skipped, etc. Without this, an fsync will reset writeback_index to 0 (its starting index) + however many pages it wrote, which can mess up the progress of periodic flush. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c9ea95ba5fde..45fc5bdb7d67 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2800,12 +2800,13 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode)
2800 */ 2800 */
2801static int write_cache_pages_da(struct address_space *mapping, 2801static int write_cache_pages_da(struct address_space *mapping,
2802 struct writeback_control *wbc, 2802 struct writeback_control *wbc,
2803 struct mpage_da_data *mpd) 2803 struct mpage_da_data *mpd,
2804 pgoff_t *done_index)
2804{ 2805{
2805 int ret = 0; 2806 int ret = 0;
2806 int done = 0; 2807 int done = 0;
2807 struct pagevec pvec; 2808 struct pagevec pvec;
2808 int nr_pages; 2809 unsigned nr_pages;
2809 pgoff_t index; 2810 pgoff_t index;
2810 pgoff_t end; /* Inclusive */ 2811 pgoff_t end; /* Inclusive */
2811 long nr_to_write = wbc->nr_to_write; 2812 long nr_to_write = wbc->nr_to_write;
@@ -2820,6 +2821,7 @@ static int write_cache_pages_da(struct address_space *mapping,
2820 else 2821 else
2821 tag = PAGECACHE_TAG_DIRTY; 2822 tag = PAGECACHE_TAG_DIRTY;
2822 2823
2824 *done_index = index;
2823 while (!done && (index <= end)) { 2825 while (!done && (index <= end)) {
2824 int i; 2826 int i;
2825 2827
@@ -2843,6 +2845,8 @@ static int write_cache_pages_da(struct address_space *mapping,
2843 break; 2845 break;
2844 } 2846 }
2845 2847
2848 *done_index = page->index + 1;
2849
2846 lock_page(page); 2850 lock_page(page);
2847 2851
2848 /* 2852 /*
@@ -2928,6 +2932,7 @@ static int ext4_da_writepages(struct address_space *mapping,
2928 long desired_nr_to_write, nr_to_writebump = 0; 2932 long desired_nr_to_write, nr_to_writebump = 0;
2929 loff_t range_start = wbc->range_start; 2933 loff_t range_start = wbc->range_start;
2930 struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); 2934 struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
2935 pgoff_t done_index = 0;
2931 pgoff_t end; 2936 pgoff_t end;
2932 2937
2933 trace_ext4_da_writepages(inode, wbc); 2938 trace_ext4_da_writepages(inode, wbc);
@@ -3050,7 +3055,7 @@ retry:
3050 mpd.io_done = 0; 3055 mpd.io_done = 0;
3051 mpd.pages_written = 0; 3056 mpd.pages_written = 0;
3052 mpd.retval = 0; 3057 mpd.retval = 0;
3053 ret = write_cache_pages_da(mapping, wbc, &mpd); 3058 ret = write_cache_pages_da(mapping, wbc, &mpd, &done_index);
3054 /* 3059 /*
3055 * If we have a contiguous extent of pages and we 3060 * If we have a contiguous extent of pages and we
3056 * haven't done the I/O yet, map the blocks and submit 3061 * haven't done the I/O yet, map the blocks and submit
@@ -3104,14 +3109,13 @@ retry:
3104 __func__, wbc->nr_to_write, ret); 3109 __func__, wbc->nr_to_write, ret);
3105 3110
3106 /* Update index */ 3111 /* Update index */
3107 index += pages_written;
3108 wbc->range_cyclic = range_cyclic; 3112 wbc->range_cyclic = range_cyclic;
3109 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) 3113 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
3110 /* 3114 /*
3111 * set the writeback_index so that range_cyclic 3115 * set the writeback_index so that range_cyclic
3112 * mode will write it back later 3116 * mode will write it back later
3113 */ 3117 */
3114 mapping->writeback_index = index; 3118 mapping->writeback_index = done_index;
3115 3119
3116out_writepages: 3120out_writepages:
3117 wbc->nr_to_write -= nr_to_writebump; 3121 wbc->nr_to_write -= nr_to_writebump;