diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-08-29 22:39:56 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-12-10 14:25:19 -0500 |
commit | 04fff6416cb7876091f0b2f413caf43e3618d5ad (patch) | |
tree | cca90894761405119e26d5c53db01746770ceeb0 | |
parent | 92e50d2d42d7cb9fcd816b47b580622032d38293 (diff) | |
download | lwn-04fff6416cb7876091f0b2f413caf43e3618d5ad.tar.gz lwn-04fff6416cb7876091f0b2f413caf43e3618d5ad.zip |
simple_write_end(): don't zero in short copy into uptodate
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/libfs.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/libfs.c b/fs/libfs.c index 48826d4da189..76048705d922 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -465,6 +465,8 @@ EXPORT_SYMBOL(simple_write_begin); * is not called, so a filesystem that actually does store data in .write_inode * should extend on what's done here with a call to mark_inode_dirty() in the * case that i_size has changed. + * + * Use *ONLY* with simple_readpage() */ int simple_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, @@ -474,14 +476,14 @@ int simple_write_end(struct file *file, struct address_space *mapping, loff_t last_pos = pos + copied; /* zero the stale part of the page if we did a short copy */ - if (copied < len) { - unsigned from = pos & (PAGE_SIZE - 1); - - zero_user(page, from + copied, len - copied); - } + if (!PageUptodate(page)) { + if (copied < len) { + unsigned from = pos & (PAGE_SIZE - 1); - if (!PageUptodate(page)) + zero_user(page, from + copied, len - copied); + } SetPageUptodate(page); + } /* * No need to use i_size_read() here, the i_size * cannot change under us because we hold the i_mutex. |