diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2019-09-06 11:02:38 +0100 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2019-09-06 22:54:23 +0200 |
commit | b473bc2dcd5ad7c487f252d9d2b74ace70308b1f (patch) | |
tree | b8c5b584423feb174c308cce5c51544cd95004b8 | |
parent | ad26967b9afa7faee22c3b79370cb5d9ab553493 (diff) | |
download | linux-b473bc2dcd5ad7c487f252d9d2b74ace70308b1f.tar.bz2 |
gfs2: Improve mmap write vs. truncate consistency
On filesystems with a block size smaller than PAGE_SIZE, page_mkwrite is
called for each memory-mapped page before that page can be written to.
When such a memory-mapped file is truncated down to size x which is not
a multiple of the page size and then back to a larger size, the page
straddling size x can end up with a partial block mapping. In that
case, make sure to mark that page read-only so that page_mkwrite will be
called before the page can be written to the next time.
(There is no point in marking the page straddling size x read-only when
truncating down as writing to memory beyond the end of the file will
result in SIGBUS instead of growing the file.)
Fixes xfstests generic/029, generic/030 on filesystems with a block size
smaller than PAGE_SIZE.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
-rw-r--r-- | fs/gfs2/bmap.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 2043a728f281..9ef543dd38e2 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -2139,7 +2139,7 @@ static int do_grow(struct inode *inode, u64 size) if (error) goto do_end_trans; - i_size_write(inode, size); + truncate_setsize(inode, size); ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode); gfs2_trans_add_meta(ip->i_gl, dibh); gfs2_dinode_out(ip, dibh->b_data); |