summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2006-09-07 06:27:15 +0200
committerDavid Chatterton <chatz@sgi.com>2006-09-07 06:27:15 +0200
commit0a8d17d090a4939643a52194b7d4a4001b9b2d93 (patch)
tree6ebf7aeb35f528be9171c75fd4c0152894f13dda
parent[XFS] Fix ABBA deadlock between i_mutex and iolock. Avoid calling (diff)
downloadlinux-0a8d17d090a4939643a52194b7d4a4001b9b2d93.tar.xz
linux-0a8d17d090a4939643a52194b7d4a4001b9b2d93.zip
[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>
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c16
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(
xfs_inode_t *ip = XFS_BHVTOI(bdp);
xfs_mount_t *mp = ip->i_mount;
ssize_t ret;
+ struct inode *inode = outfilp->f_mapping->host;
+ xfs_fsize_t isize;
XFS_STATS_INC(xs_write_calls);
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -417,6 +419,20 @@ xfs_splice_write(
if (ret > 0)
XFS_STATS_ADD(xs_write_bytes, ret);
+ isize = i_size_read(inode);
+ if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
+ *ppos = isize;
+
+ if (*ppos > ip->i_d.di_size) {
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ if (*ppos > ip->i_d.di_size) {
+ ip->i_d.di_size = *ppos;
+ i_size_write(inode, *ppos);
+ ip->i_update_core = 1;
+ ip->i_update_size = 1;
+ }
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ }
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return ret;
}