This patch fixes data loss caused by the fallocate system call interrupted by a signal. Bug: https://lore.kernel.org/linux-mm/33b85d82.7764.1842e9ab207.Coremail.chenguoqic@xxxxxxx/ Fixes: b9a8a4195c7d ("truncate,shmem: Handle truncates that split large folios") Reported-by: Guoqi Chen <chenguoqic@xxxxxxx> Cc: Huacai Chen <chenhuacai@xxxxxxxxxxx> Signed-off-by: Rui Wang <kernel@xxxxxx> --- mm/shmem.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index bc9b84602eec..8c8dce34eafc 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -948,11 +948,13 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, folio = shmem_get_partial_folio(inode, lstart >> PAGE_SHIFT); if (folio) { same_folio = lend < folio_pos(folio) + folio_size(folio); - folio_mark_dirty(folio); - if (!truncate_inode_partial_folio(folio, lstart, lend)) { - start = folio->index + folio_nr_pages(folio); - if (same_folio) - end = folio->index; + if (!unfalloc || !folio_test_uptodate(folio)) { + folio_mark_dirty(folio); + if (!truncate_inode_partial_folio(folio, lstart, lend)) { + start = folio->index + folio_nr_pages(folio); + if (same_folio) + end = folio->index; + } } folio_unlock(folio); folio_put(folio); @@ -962,9 +964,11 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, if (!same_folio) folio = shmem_get_partial_folio(inode, lend >> PAGE_SHIFT); if (folio) { - folio_mark_dirty(folio); - if (!truncate_inode_partial_folio(folio, lstart, lend)) - end = folio->index; + if (!unfalloc || !folio_test_uptodate(folio)) { + folio_mark_dirty(folio); + if (!truncate_inode_partial_folio(folio, lstart, lend)) + end = folio->index; + } folio_unlock(folio); folio_put(folio); } -- 2.38.1