Skip to content

Commit

Permalink
xfs: xfs_vm_write_end truncates too much on failure
Browse files Browse the repository at this point in the history
Similar to the write_begin problem, xfs-vm_write_end will truncate
back to the old EOF, potentially removing page cache from over the
top of delalloc blocks with valid data in them. Fix this by
truncating back to just the start of the failed write.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Tested-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
  • Loading branch information
Dave Chinner authored and Dave Chinner committed Apr 14, 2014
1 parent 72ab70a commit aad3f37
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions fs/xfs/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1634,9 +1634,12 @@ xfs_vm_write_begin(
}

/*
* On failure, we only need to kill delalloc blocks beyond EOF because they
* will never be written. For blocks within EOF, generic_write_end() zeros them
* so they are safe to leave alone and be written with all the other valid data.
* On failure, we only need to kill delalloc blocks beyond EOF in the range of
* this specific write because they will never be written. Previous writes
* beyond EOF where block allocation succeeded do not need to be trashed, so
* only new blocks from this write should be trashed. For blocks within
* EOF, generic_write_end() zeros them so they are safe to leave alone and be
* written with all the other valid data.
*/
STATIC int
xfs_vm_write_end(
Expand All @@ -1659,8 +1662,11 @@ xfs_vm_write_end(
loff_t to = pos + len;

if (to > isize) {
truncate_pagecache(inode, isize);
/* only kill blocks in this write beyond EOF */
if (pos > isize)
isize = pos;
xfs_vm_kill_delalloc_range(inode, isize, to);
truncate_pagecache_range(inode, isize, to);
}
}
return ret;
Expand Down

0 comments on commit aad3f37

Please sign in to comment.