Skip to content

Commit c1d51ae

Browse files
zhangyi089opsiff
authored andcommitted
iomap: keep on increasing i_size in iomap_write_end()
mainline inclusion from mainline-v6.10-rc4 category: bugfix Commit '943bc0882ceb ("iomap: don't increase i_size if it's not a write operation")' breaks xfs with realtime device on generic/561, the problem is when unaligned truncate down a xfs realtime inode with rtextsize > 1 fs block, xfs only zero out the EOF block but doesn't zero out the tail blocks that aligned to rtextsize, so if we don't increase i_size in iomap_write_end(), it could expose stale data after we do an append write beyond the aligned EOF block. xfs should zero out the tail blocks when truncate down, but before we finish that, let's fix the issue by just revert the changes in iomap_write_end(). Fixes: 943bc08 ("iomap: don't increase i_size if it's not a write operation") Reported-by: Chandan Babu R <chandanbabu@kernel.org> Link: https://lore.kernel.org/linux-xfs/0b92a215-9d9b-3788-4504-a520778953c2@huaweicloud.com Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Link: https://lore.kernel.org/r/20240603112222.2109341-1-yi.zhang@huaweicloud.com Tested-by: Chandan Babu R <chandanbabu@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner <brauner@kernel.org> (cherry picked from commit 0841ea4) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent 3f59c75 commit c1d51ae

1 file changed

Lines changed: 24 additions & 29 deletions

File tree

fs/iomap/buffered-io.c

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -875,22 +875,37 @@ static bool 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 written;
878880

879881
if (srcmap->type == IOMAP_INLINE) {
880882
iomap_write_end_inline(iter, folio, pos, copied);
881-
return true;
883+
written = copied;
884+
} else if (srcmap->flags & IOMAP_F_BUFFER_HEAD) {
885+
written = block_write_end(NULL, iter->inode->i_mapping, pos,
886+
len, copied, &folio->page, NULL);
887+
WARN_ON_ONCE(written != copied && written != 0);
888+
} else {
889+
written = __iomap_write_end(iter->inode, pos, len, copied,
890+
folio) ? copied : 0;
882891
}
883892

884-
if (srcmap->flags & IOMAP_F_BUFFER_HEAD) {
885-
size_t bh_written;
886-
887-
bh_written = block_write_end(NULL, iter->inode->i_mapping, pos,
888-
len, copied, &folio->page, NULL);
889-
WARN_ON_ONCE(bh_written != copied && bh_written != 0);
890-
return bh_written == copied;
893+
/*
894+
* Update the in-memory inode size after copying the data into the page
895+
* cache. It's up to the file system to write the updated size to disk,
896+
* preferably after I/O completion so that no stale data is exposed.
897+
* Only once that's done can we unlock and release the folio.
898+
*/
899+
if (pos + written > old_size) {
900+
i_size_write(iter->inode, pos + written);
901+
iter->iomap.flags |= IOMAP_F_SIZE_CHANGED;
891902
}
903+
__iomap_put_folio(iter, pos, written, folio);
892904

893-
return __iomap_write_end(iter->inode, pos, len, copied, folio);
905+
if (old_size < pos)
906+
pagecache_isize_extended(iter->inode, old_size, pos);
907+
908+
return written == copied;
894909
}
895910

896911
static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
@@ -905,7 +920,6 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
905920

906921
do {
907922
struct folio *folio;
908-
loff_t old_size;
909923
size_t offset; /* Offset into folio */
910924
size_t bytes; /* Bytes to write to folio */
911925
size_t copied; /* Bytes copied from user */
@@ -957,23 +971,6 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
957971
written = iomap_write_end(iter, pos, bytes, copied, folio) ?
958972
copied : 0;
959973

960-
/*
961-
* Update the in-memory inode size after copying the data into
962-
* the page cache. It's up to the file system to write the
963-
* updated size to disk, preferably after I/O completion so that
964-
* no stale data is exposed. Only once that's done can we
965-
* unlock and release the folio.
966-
*/
967-
old_size = iter->inode->i_size;
968-
if (pos + written > old_size) {
969-
i_size_write(iter->inode, pos + written);
970-
iter->iomap.flags |= IOMAP_F_SIZE_CHANGED;
971-
}
972-
__iomap_put_folio(iter, pos, written, folio);
973-
974-
if (old_size < pos)
975-
pagecache_isize_extended(iter->inode, old_size, pos);
976-
977974
cond_resched();
978975
if (unlikely(written == 0)) {
979976
/*
@@ -1347,7 +1344,6 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
13471344
bytes = folio_size(folio) - offset;
13481345

13491346
ret = iomap_write_end(iter, pos, bytes, bytes, folio);
1350-
__iomap_put_folio(iter, pos, bytes, folio);
13511347
if (WARN_ON_ONCE(!ret))
13521348
return -EIO;
13531349

@@ -1417,7 +1413,6 @@ static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero)
14171413
folio_mark_accessed(folio);
14181414

14191415
ret = iomap_write_end(iter, pos, bytes, bytes, folio);
1420-
__iomap_put_folio(iter, pos, bytes, folio);
14211416
if (WARN_ON_ONCE(!ret))
14221417
return -EIO;
14231418

0 commit comments

Comments
 (0)