diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-01-10 18:14:16 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2011-01-10 18:14:16 -0500 |
commit | 4c5cfd1b4157fb75d43b44a147c2feba6422fc4f (patch) | |
tree | d6511239f2bf9d56bb89f36c6da9ac3957f76cff /fs/xfs/linux-2.6/xfs_file.c | |
parent | edafb6da9aa725e4de5fe758fe81644b6167f9a2 (diff) |
xfs: factor post-write newsize updates
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Alex Elder <aelder@sgi.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_file.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index b3915bf25770..c47d7dc0a307 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -345,6 +345,25 @@ xfs_aio_write_isize_update( | |||
345 | } | 345 | } |
346 | } | 346 | } |
347 | 347 | ||
348 | /* | ||
349 | * If this was a direct or synchronous I/O that failed (such as ENOSPC) then | ||
350 | * part of the I/O may have been written to disk before the error occured. In | ||
351 | * this case the on-disk file size may have been adjusted beyond the in-memory | ||
352 | * file size and now needs to be truncated back. | ||
353 | */ | ||
354 | STATIC void | ||
355 | xfs_aio_write_newsize_update( | ||
356 | struct xfs_inode *ip) | ||
357 | { | ||
358 | if (ip->i_new_size) { | ||
359 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
360 | ip->i_new_size = 0; | ||
361 | if (ip->i_d.di_size > ip->i_size) | ||
362 | ip->i_d.di_size = ip->i_size; | ||
363 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
364 | } | ||
365 | } | ||
366 | |||
348 | STATIC ssize_t | 367 | STATIC ssize_t |
349 | xfs_file_splice_write( | 368 | xfs_file_splice_write( |
350 | struct pipe_inode_info *pipe, | 369 | struct pipe_inode_info *pipe, |
@@ -381,14 +400,7 @@ xfs_file_splice_write( | |||
381 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); | 400 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); |
382 | 401 | ||
383 | xfs_aio_write_isize_update(inode, ppos, ret); | 402 | xfs_aio_write_isize_update(inode, ppos, ret); |
384 | 403 | xfs_aio_write_newsize_update(ip); | |
385 | if (ip->i_new_size) { | ||
386 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
387 | ip->i_new_size = 0; | ||
388 | if (ip->i_d.di_size > ip->i_size) | ||
389 | ip->i_d.di_size = ip->i_size; | ||
390 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
391 | } | ||
392 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 404 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
393 | return ret; | 405 | return ret; |
394 | } | 406 | } |
@@ -781,20 +793,7 @@ write_retry: | |||
781 | } | 793 | } |
782 | 794 | ||
783 | out_unlock_internal: | 795 | out_unlock_internal: |
784 | if (ip->i_new_size) { | 796 | xfs_aio_write_newsize_update(ip); |
785 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
786 | ip->i_new_size = 0; | ||
787 | /* | ||
788 | * If this was a direct or synchronous I/O that failed (such | ||
789 | * as ENOSPC) then part of the I/O may have been written to | ||
790 | * disk before the error occured. In this case the on-disk | ||
791 | * file size may have been adjusted beyond the in-memory file | ||
792 | * size and now needs to be truncated back. | ||
793 | */ | ||
794 | if (ip->i_d.di_size > ip->i_size) | ||
795 | ip->i_d.di_size = ip->i_size; | ||
796 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
797 | } | ||
798 | xfs_iunlock(ip, iolock); | 797 | xfs_iunlock(ip, iolock); |
799 | out_unlock_mutex: | 798 | out_unlock_mutex: |
800 | if (need_i_mutex) | 799 | if (need_i_mutex) |