Skip to content

Commit 943bc08

Browse files
zhangyi089brauner
authored andcommitted
iomap: don't increase i_size if it's not a write operation
Increase i_size in iomap_zero_range() and iomap_unshare_iter() is not needed, the caller should handle it. Especially, when truncate partial block, we should not increase i_size beyond the new EOF here. It doesn't affect xfs and gfs2 now because they set the new file size after zero out, it doesn't matter that a transient increase in i_size, but it will affect ext4 because it set file size before truncate. So move the i_size updating logic to iomap_write_iter(). Signed-off-by: Zhang Yi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 89c6c1d commit 943bc08

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

fs/iomap/buffered-io.c

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -875,32 +875,13 @@ static size_t iomap_write_end(struct iomap_iter *iter, loff_t pos, size_t len,
875875
size_t copied, struct folio *folio)
876876
{
877877
const struct iomap *srcmap = iomap_iter_srcmap(iter);
878-
loff_t old_size = iter->inode->i_size;
879-
size_t ret;
880-
881-
if (srcmap->type == IOMAP_INLINE) {
882-
ret = iomap_write_end_inline(iter, folio, pos, copied);
883-
} else if (srcmap->flags & IOMAP_F_BUFFER_HEAD) {
884-
ret = block_write_end(NULL, iter->inode->i_mapping, pos, len,
885-
copied, &folio->page, NULL);
886-
} else {
887-
ret = __iomap_write_end(iter->inode, pos, len, copied, folio);
888-
}
889-
890-
/*
891-
* Update the in-memory inode size after copying the data into the page
892-
* cache. It's up to the file system to write the updated size to disk,
893-
* preferably after I/O completion so that no stale data is exposed.
894-
*/
895-
if (pos + ret > old_size) {
896-
i_size_write(iter->inode, pos + ret);
897-
iter->iomap.flags |= IOMAP_F_SIZE_CHANGED;
898-
}
899-
__iomap_put_folio(iter, pos, ret, folio);
900878

901-
if (old_size < pos)
902-
pagecache_isize_extended(iter->inode, old_size, pos);
903-
return ret;
879+
if (srcmap->type == IOMAP_INLINE)
880+
return iomap_write_end_inline(iter, folio, pos, copied);
881+
if (srcmap->flags & IOMAP_F_BUFFER_HEAD)
882+
return block_write_end(NULL, iter->inode->i_mapping, pos, len,
883+
copied, &folio->page, NULL);
884+
return __iomap_write_end(iter->inode, pos, len, copied, folio);
904885
}
905886

906887
static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
@@ -915,6 +896,7 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
915896

916897
do {
917898
struct folio *folio;
899+
loff_t old_size;
918900
size_t offset; /* Offset into folio */
919901
size_t bytes; /* Bytes to write to folio */
920902
size_t copied; /* Bytes copied from user */
@@ -964,6 +946,22 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
964946
copied = copy_folio_from_iter_atomic(folio, offset, bytes, i);
965947
status = iomap_write_end(iter, pos, bytes, copied, folio);
966948

949+
/*
950+
* Update the in-memory inode size after copying the data into
951+
* the page cache. It's up to the file system to write the
952+
* updated size to disk, preferably after I/O completion so that
953+
* no stale data is exposed. Only once that's done can we
954+
* unlock and release the folio.
955+
*/
956+
old_size = iter->inode->i_size;
957+
if (pos + status > old_size) {
958+
i_size_write(iter->inode, pos + status);
959+
iter->iomap.flags |= IOMAP_F_SIZE_CHANGED;
960+
}
961+
__iomap_put_folio(iter, pos, status, folio);
962+
963+
if (old_size < pos)
964+
pagecache_isize_extended(iter->inode, old_size, pos);
967965
if (status < bytes)
968966
iomap_write_failed(iter->inode, pos + status,
969967
bytes - status);
@@ -1336,6 +1334,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
13361334
bytes = folio_size(folio) - offset;
13371335

13381336
bytes = iomap_write_end(iter, pos, bytes, bytes, folio);
1337+
__iomap_put_folio(iter, pos, bytes, folio);
13391338
if (WARN_ON_ONCE(bytes == 0))
13401339
return -EIO;
13411340

@@ -1400,6 +1399,7 @@ static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero)
14001399
folio_mark_accessed(folio);
14011400

14021401
bytes = iomap_write_end(iter, pos, bytes, bytes, folio);
1402+
__iomap_put_folio(iter, pos, bytes, folio);
14031403
if (WARN_ON_ONCE(bytes == 0))
14041404
return -EIO;
14051405

0 commit comments

Comments
 (0)