diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-10 20:29:45 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-10 20:29:45 -0700 |
commit | a47f5c56b2eb55290e2a8668e9ca9c029990dbf6 (patch) | |
tree | 14dbfd50de0ed36f1649a1b0a192865b09db343d /fs/iomap.c | |
parent | 682f7c5c465d7ac4107e51dbf2a847a026b384e8 (diff) | |
parent | 36a7347de097edf9c4d7203d09fa223c86479674 (diff) |
Merge tag 'iomap-5.3-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull iomap updates from Darrick Wong:
"There are a few fixes for gfs2 but otherwise it's pretty quiet so far.
- Only mark inode dirty at the end of writing to a file (instead of
once for every page written).
- Fix for an accounting error in the page_done callback"
* tag 'iomap-5.3-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
iomap: fix page_done callback for short writes
fs: fold __generic_write_end back into generic_write_end
iomap: don't mark the inode dirty in iomap_write_end
Diffstat (limited to 'fs/iomap.c')
-rw-r--r-- | fs/iomap.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/iomap.c b/fs/iomap.c index 7a147aa0c4d9..217c3e5a13d6 100644 --- a/fs/iomap.c +++ b/fs/iomap.c @@ -777,6 +777,7 @@ iomap_write_end(struct inode *inode, loff_t pos, unsigned len, unsigned copied, struct page *page, struct iomap *iomap) { const struct iomap_page_ops *page_ops = iomap->page_ops; + loff_t old_size = inode->i_size; int ret; if (iomap->type == IOMAP_INLINE) { @@ -788,9 +789,21 @@ iomap_write_end(struct inode *inode, loff_t pos, unsigned len, ret = __iomap_write_end(inode, pos, len, copied, page, iomap); } - __generic_write_end(inode, pos, ret, page); + /* + * Update the in-memory inode size after copying the data into the page + * cache. It's up to the file system to write the updated size to disk, + * preferably after I/O completion so that no stale data is exposed. + */ + if (pos + ret > old_size) { + i_size_write(inode, pos + ret); + iomap->flags |= IOMAP_F_SIZE_CHANGED; + } + unlock_page(page); + + if (old_size < pos) + pagecache_isize_extended(inode, old_size, pos); if (page_ops && page_ops->page_done) - page_ops->page_done(inode, pos, copied, page, iomap); + page_ops->page_done(inode, pos, ret, page, iomap); put_page(page); if (ret < len) |