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 /fs/xfs | |
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>
Diffstat (limited to 'fs/xfs')
-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; |