Commit 620a324b authored by Jens Axboe's avatar Jens Axboe

splice: __generic_file_splice_read: fix read/truncate race

Original patch and description from Neil Brown <neilb@suse.de>,
merged and adapted to splice branch by me. Neils text follows:

__generic_file_splice_read() currently samples the i_size at the start
and doesn't do so again unless it needs to call ->readpage to load
a page.  After ->readpage it has to re-sample i_size as a truncate
may have caused that page to be filled with zeros, and the read()
call should not see these.

However there are other activities that might cause ->readpage to be
called on a page between the time that __generic_file_splice_read()
samples i_size and when it finds that it has an uptodate page. These
include at least read-ahead and possibly another thread performing a
read

So we must sample i_size *after* it has an uptodate page.  Thus the
current sampling at the start and after a read can be replaced with a
sampling before page addition into spd.
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 475ecade
......@@ -413,9 +413,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
break;
}
}
fill_it:
/*
* i_size must be checked after ->readpage().
* i_size must be checked after PageUptodate.
*/
isize = i_size_read(mapping->host);
end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
......@@ -442,8 +443,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
this_len = min(this_len, plen - loff);
len = this_len;
}
}
fill_it:
partial[page_nr].offset = loff;
partial[page_nr].len = this_len;
len -= this_len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment