diff options
| -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) |
