From 7d4ce133ce3162172fa4a04d1e94cc7195f5a5bd Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 10 Feb 2004 13:39:45 +1100 Subject: [PATCH] [XFS] Fix data loss when writing into unwritten extents while memory is being reclaimed. SGI Modid: xfs-linux:xfs-kern:166324a --- fs/xfs/linux/xfs_aops.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c index 5e2c9a3d88095..1d13a91e3b37f 100644 --- a/fs/xfs/linux/xfs_aops.c +++ b/fs/xfs/linux/xfs_aops.c @@ -724,7 +724,7 @@ page_state_convert( iomp = match_offset_to_mapping(page, &iomap, p_offset); } - if (iomp) { + if (iomp && startio) { if (!bh->b_end_io) { err = map_unwritten(inode, page, head, bh, p_offset, @@ -734,13 +734,7 @@ page_state_convert( goto error; } } - if (startio) { - bh_arr[cnt++] = bh; - } else { - set_buffer_dirty(bh); - unlock_buffer(bh); - mark_buffer_dirty(bh); - } + bh_arr[cnt++] = bh; page_dirty = 0; } /* @@ -886,9 +880,9 @@ linvfs_get_block_core( loff_t delta; /* For unwritten extents do not report a disk address on - * the read case. + * the read case (treat as if we're reading into a hole). */ - if (create || ((iomap.iomap_flags & IOMAP_UNWRITTEN) == 0)) { + if (create || !(iomap.iomap_flags & IOMAP_UNWRITTEN)) { delta = offset - iomap.iomap_offset; delta >>= inode->i_blkbits; @@ -899,12 +893,9 @@ linvfs_get_block_core( bh_result->b_bdev = iomap.iomap_target->pbr_bdev; set_buffer_mapped(bh_result); } - if (iomap.iomap_flags & IOMAP_UNWRITTEN) { - if (create) { - if (direct) - bh_result->b_private = inode; - set_buffer_mapped(bh_result); - } + if (create && (iomap.iomap_flags & IOMAP_UNWRITTEN)) { + if (direct) + bh_result->b_private = inode; set_buffer_unwritten(bh_result); set_buffer_delay(bh_result); } @@ -1173,7 +1164,7 @@ linvfs_release_page( int gfp_mask) { struct inode *inode = page->mapping->host; - int delalloc, unmapped, unwritten; + int dirty, delalloc, unmapped, unwritten; count_page_state(page, &delalloc, &unmapped, &unwritten); if (!delalloc && !unwritten) @@ -1194,7 +1185,8 @@ linvfs_release_page( * Never need to allocate space here - we will always * come back to writepage in that case. */ - if (page_state_convert(inode, page, 0, 0) == 0) + dirty = page_state_convert(inode, page, 0, 0); + if (dirty == 0 && !unwritten) goto free_buffers; return 0; -- 2.53.0