diff options
author | David Chinner <dgc@sgi.com> | 2006-09-07 00:27:15 -0400 |
---|---|---|
committer | David Chatterton <chatz@sgi.com> | 2006-09-07 00:27:15 -0400 |
commit | 0a8d17d090a4939643a52194b7d4a4001b9b2d93 (patch) | |
tree | 6ebf7aeb35f528be9171c75fd4c0152894f13dda /fs/xfs | |
parent | 721259bce2851893155c6cb88a3f8ecb106b348c (diff) |
[XFS] Fix xfs_splice_write() so appended data gets to disk.
xfs_splice_write() failed to update the on disk inode size when extending
the so when the file was closed the range extended by splice was truncated
off. Hence any region of a file written to by splice would end up as a
hole full of zeros.
SGI-PV: 955939
SGI-Modid: xfs-linux-melb:xfs-kern:26920a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: David Chatterton <chatz@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 110c038910ff..ee788b1cb364 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -391,6 +391,8 @@ xfs_splice_write( | |||
391 | xfs_inode_t *ip = XFS_BHVTOI(bdp); | 391 | xfs_inode_t *ip = XFS_BHVTOI(bdp); |
392 | xfs_mount_t *mp = ip->i_mount; | 392 | xfs_mount_t *mp = ip->i_mount; |
393 | ssize_t ret; | 393 | ssize_t ret; |
394 | struct inode *inode = outfilp->f_mapping->host; | ||
395 | xfs_fsize_t isize; | ||
394 | 396 | ||
395 | XFS_STATS_INC(xs_write_calls); | 397 | XFS_STATS_INC(xs_write_calls); |
396 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 398 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
@@ -417,6 +419,20 @@ xfs_splice_write( | |||
417 | if (ret > 0) | 419 | if (ret > 0) |
418 | XFS_STATS_ADD(xs_write_bytes, ret); | 420 | XFS_STATS_ADD(xs_write_bytes, ret); |
419 | 421 | ||
422 | isize = i_size_read(inode); | ||
423 | if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize)) | ||
424 | *ppos = isize; | ||
425 | |||
426 | if (*ppos > ip->i_d.di_size) { | ||
427 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
428 | if (*ppos > ip->i_d.di_size) { | ||
429 | ip->i_d.di_size = *ppos; | ||
430 | i_size_write(inode, *ppos); | ||
431 | ip->i_update_core = 1; | ||
432 | ip->i_update_size = 1; | ||
433 | } | ||
434 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
435 | } | ||
420 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 436 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
421 | return ret; | 437 | return ret; |
422 | } | 438 | } |