diff options
| author | Dave Chinner <dchinner@redhat.com> | 2011-01-10 18:14:06 -0500 |
|---|---|---|
| committer | Dave Chinner <david@fromorbit.com> | 2011-01-10 18:14:06 -0500 |
| commit | edafb6da9aa725e4de5fe758fe81644b6167f9a2 (patch) | |
| tree | f79f7b2de496daf757c89528309e3a17b0636c6a | |
| parent | a363f0c2030cb9781e7e458f4a9e354b6c43d7ce (diff) | |
xfs: factor common post-write isize handling code
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Alex Elder <aelder@sgi.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 10b7fb4807a6..b3915bf25770 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -321,6 +321,30 @@ xfs_file_splice_read( | |||
| 321 | return ret; | 321 | return ret; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | STATIC void | ||
| 325 | xfs_aio_write_isize_update( | ||
| 326 | struct inode *inode, | ||
| 327 | loff_t *ppos, | ||
| 328 | ssize_t bytes_written) | ||
| 329 | { | ||
| 330 | struct xfs_inode *ip = XFS_I(inode); | ||
| 331 | xfs_fsize_t isize = i_size_read(inode); | ||
| 332 | |||
| 333 | if (bytes_written > 0) | ||
| 334 | XFS_STATS_ADD(xs_write_bytes, bytes_written); | ||
| 335 | |||
| 336 | if (unlikely(bytes_written < 0 && bytes_written != -EFAULT && | ||
| 337 | *ppos > isize)) | ||
| 338 | *ppos = isize; | ||
| 339 | |||
| 340 | if (*ppos > ip->i_size) { | ||
| 341 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 342 | if (*ppos > ip->i_size) | ||
| 343 | ip->i_size = *ppos; | ||
| 344 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 324 | STATIC ssize_t | 348 | STATIC ssize_t |
| 325 | xfs_file_splice_write( | 349 | xfs_file_splice_write( |
| 326 | struct pipe_inode_info *pipe, | 350 | struct pipe_inode_info *pipe, |
| @@ -331,7 +355,7 @@ xfs_file_splice_write( | |||
| 331 | { | 355 | { |
| 332 | struct inode *inode = outfilp->f_mapping->host; | 356 | struct inode *inode = outfilp->f_mapping->host; |
| 333 | struct xfs_inode *ip = XFS_I(inode); | 357 | struct xfs_inode *ip = XFS_I(inode); |
| 334 | xfs_fsize_t isize, new_size; | 358 | xfs_fsize_t new_size; |
| 335 | int ioflags = 0; | 359 | int ioflags = 0; |
| 336 | ssize_t ret; | 360 | ssize_t ret; |
| 337 | 361 | ||
| @@ -355,19 +379,8 @@ xfs_file_splice_write( | |||
| 355 | trace_xfs_file_splice_write(ip, count, *ppos, ioflags); | 379 | trace_xfs_file_splice_write(ip, count, *ppos, ioflags); |
| 356 | 380 | ||
| 357 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); | 381 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); |
| 358 | if (ret > 0) | ||
| 359 | XFS_STATS_ADD(xs_write_bytes, ret); | ||
| 360 | |||
| 361 | isize = i_size_read(inode); | ||
| 362 | if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize)) | ||
| 363 | *ppos = isize; | ||
| 364 | 382 | ||
| 365 | if (*ppos > ip->i_size) { | 383 | xfs_aio_write_isize_update(inode, ppos, ret); |
| 366 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 367 | if (*ppos > ip->i_size) | ||
| 368 | ip->i_size = *ppos; | ||
| 369 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 370 | } | ||
| 371 | 384 | ||
| 372 | if (ip->i_new_size) { | 385 | if (ip->i_new_size) { |
| 373 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 386 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| @@ -576,7 +589,7 @@ xfs_file_aio_write( | |||
| 576 | struct xfs_mount *mp = ip->i_mount; | 589 | struct xfs_mount *mp = ip->i_mount; |
| 577 | ssize_t ret = 0; | 590 | ssize_t ret = 0; |
| 578 | int ioflags = 0; | 591 | int ioflags = 0; |
| 579 | xfs_fsize_t isize, new_size; | 592 | xfs_fsize_t new_size; |
| 580 | int iolock; | 593 | int iolock; |
| 581 | size_t ocount = 0, count; | 594 | size_t ocount = 0, count; |
| 582 | int need_i_mutex; | 595 | int need_i_mutex; |
| @@ -740,22 +753,11 @@ write_retry: | |||
| 740 | 753 | ||
| 741 | current->backing_dev_info = NULL; | 754 | current->backing_dev_info = NULL; |
| 742 | 755 | ||
| 743 | isize = i_size_read(inode); | 756 | xfs_aio_write_isize_update(inode, &iocb->ki_pos, ret); |
| 744 | if (unlikely(ret < 0 && ret != -EFAULT && iocb->ki_pos > isize)) | ||
| 745 | iocb->ki_pos = isize; | ||
| 746 | |||
| 747 | if (iocb->ki_pos > ip->i_size) { | ||
| 748 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 749 | if (iocb->ki_pos > ip->i_size) | ||
| 750 | ip->i_size = iocb->ki_pos; | ||
| 751 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 752 | } | ||
| 753 | 757 | ||
| 754 | if (ret <= 0) | 758 | if (ret <= 0) |
| 755 | goto out_unlock_internal; | 759 | goto out_unlock_internal; |
| 756 | 760 | ||
| 757 | XFS_STATS_ADD(xs_write_bytes, ret); | ||
| 758 | |||
| 759 | /* Handle various SYNC-type writes */ | 761 | /* Handle various SYNC-type writes */ |
| 760 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { | 762 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { |
| 761 | loff_t end = pos + ret - 1; | 763 | loff_t end = pos + ret - 1; |
