Commit 7d4ce133 authored by Nathan Scott's avatar Nathan Scott

[XFS] Fix data loss when writing into unwritten extents while memory is being reclaimed.

SGI Modid: xfs-linux:xfs-kern:166324a
parent 6fd1e845
...@@ -724,7 +724,7 @@ page_state_convert( ...@@ -724,7 +724,7 @@ page_state_convert(
iomp = match_offset_to_mapping(page, &iomap, iomp = match_offset_to_mapping(page, &iomap,
p_offset); p_offset);
} }
if (iomp) { if (iomp && startio) {
if (!bh->b_end_io) { if (!bh->b_end_io) {
err = map_unwritten(inode, page, err = map_unwritten(inode, page,
head, bh, p_offset, head, bh, p_offset,
...@@ -734,13 +734,7 @@ page_state_convert( ...@@ -734,13 +734,7 @@ page_state_convert(
goto error; goto error;
} }
} }
if (startio) { bh_arr[cnt++] = bh;
bh_arr[cnt++] = bh;
} else {
set_buffer_dirty(bh);
unlock_buffer(bh);
mark_buffer_dirty(bh);
}
page_dirty = 0; page_dirty = 0;
} }
/* /*
...@@ -886,9 +880,9 @@ linvfs_get_block_core( ...@@ -886,9 +880,9 @@ linvfs_get_block_core(
loff_t delta; loff_t delta;
/* For unwritten extents do not report a disk address on /* 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 = offset - iomap.iomap_offset;
delta >>= inode->i_blkbits; delta >>= inode->i_blkbits;
...@@ -899,12 +893,9 @@ linvfs_get_block_core( ...@@ -899,12 +893,9 @@ linvfs_get_block_core(
bh_result->b_bdev = iomap.iomap_target->pbr_bdev; bh_result->b_bdev = iomap.iomap_target->pbr_bdev;
set_buffer_mapped(bh_result); set_buffer_mapped(bh_result);
} }
if (iomap.iomap_flags & IOMAP_UNWRITTEN) { if (create && (iomap.iomap_flags & IOMAP_UNWRITTEN)) {
if (create) { if (direct)
if (direct) bh_result->b_private = inode;
bh_result->b_private = inode;
set_buffer_mapped(bh_result);
}
set_buffer_unwritten(bh_result); set_buffer_unwritten(bh_result);
set_buffer_delay(bh_result); set_buffer_delay(bh_result);
} }
...@@ -1173,7 +1164,7 @@ linvfs_release_page( ...@@ -1173,7 +1164,7 @@ linvfs_release_page(
int gfp_mask) int gfp_mask)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
int delalloc, unmapped, unwritten; int dirty, delalloc, unmapped, unwritten;
count_page_state(page, &delalloc, &unmapped, &unwritten); count_page_state(page, &delalloc, &unmapped, &unwritten);
if (!delalloc && !unwritten) if (!delalloc && !unwritten)
...@@ -1194,7 +1185,8 @@ linvfs_release_page( ...@@ -1194,7 +1185,8 @@ linvfs_release_page(
* Never need to allocate space here - we will always * Never need to allocate space here - we will always
* come back to writepage in that case. * 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; goto free_buffers;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment