aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r--fs/xfs/xfs_file.c45
1 files changed, 11 insertions, 34 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index f675f3d9d7b3..86d5dc260464 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -327,7 +327,7 @@ xfs_file_aio_read(
327 mp->m_rtdev_targp : mp->m_ddev_targp; 327 mp->m_rtdev_targp : mp->m_ddev_targp;
328 if ((iocb->ki_pos & target->bt_smask) || 328 if ((iocb->ki_pos & target->bt_smask) ||
329 (size & target->bt_smask)) { 329 (size & target->bt_smask)) {
330 if (iocb->ki_pos == ip->i_size) 330 if (iocb->ki_pos == i_size_read(inode))
331 return 0; 331 return 0;
332 return -XFS_ERROR(EINVAL); 332 return -XFS_ERROR(EINVAL);
333 } 333 }
@@ -412,30 +412,6 @@ xfs_file_splice_read(
412 return ret; 412 return ret;
413} 413}
414 414
415STATIC void
416xfs_aio_write_isize_update(
417 struct inode *inode,
418 loff_t *ppos,
419 ssize_t bytes_written)
420{
421 struct xfs_inode *ip = XFS_I(inode);
422 xfs_fsize_t isize = i_size_read(inode);
423
424 if (bytes_written > 0)
425 XFS_STATS_ADD(xs_write_bytes, bytes_written);
426
427 if (unlikely(bytes_written < 0 && bytes_written != -EFAULT &&
428 *ppos > isize))
429 *ppos = isize;
430
431 if (*ppos > ip->i_size) {
432 xfs_rw_ilock(ip, XFS_ILOCK_EXCL);
433 if (*ppos > ip->i_size)
434 ip->i_size = *ppos;
435 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL);
436 }
437}
438
439/* 415/*
440 * If this was a direct or synchronous I/O that failed (such as ENOSPC) then 416 * If this was a direct or synchronous I/O that failed (such as ENOSPC) then
441 * part of the I/O may have been written to disk before the error occurred. In 417 * part of the I/O may have been written to disk before the error occurred. In
@@ -451,8 +427,8 @@ xfs_aio_write_newsize_update(
451 xfs_rw_ilock(ip, XFS_ILOCK_EXCL); 427 xfs_rw_ilock(ip, XFS_ILOCK_EXCL);
452 if (new_size == ip->i_new_size) 428 if (new_size == ip->i_new_size)
453 ip->i_new_size = 0; 429 ip->i_new_size = 0;
454 if (ip->i_d.di_size > ip->i_size) 430 if (ip->i_d.di_size > i_size_read(VFS_I(ip)))
455 ip->i_d.di_size = ip->i_size; 431 ip->i_d.di_size = i_size_read(VFS_I(ip));
456 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL); 432 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL);
457 } 433 }
458} 434}
@@ -492,15 +468,16 @@ xfs_file_splice_write(
492 new_size = *ppos + count; 468 new_size = *ppos + count;
493 469
494 xfs_ilock(ip, XFS_ILOCK_EXCL); 470 xfs_ilock(ip, XFS_ILOCK_EXCL);
495 if (new_size > ip->i_size) 471 if (new_size > i_size_read(inode))
496 ip->i_new_size = new_size; 472 ip->i_new_size = new_size;
497 xfs_iunlock(ip, XFS_ILOCK_EXCL); 473 xfs_iunlock(ip, XFS_ILOCK_EXCL);
498 474
499 trace_xfs_file_splice_write(ip, count, *ppos, ioflags); 475 trace_xfs_file_splice_write(ip, count, *ppos, ioflags);
500 476
501 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); 477 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
478 if (ret > 0)
479 XFS_STATS_ADD(xs_write_bytes, ret);
502 480
503 xfs_aio_write_isize_update(inode, ppos, ret);
504 xfs_aio_write_newsize_update(ip, new_size); 481 xfs_aio_write_newsize_update(ip, new_size);
505 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 482 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
506 return ret; 483 return ret;
@@ -728,14 +705,14 @@ restart:
728 * values are still valid. 705 * values are still valid.
729 */ 706 */
730 if ((ip->i_new_size && *pos > ip->i_new_size) || 707 if ((ip->i_new_size && *pos > ip->i_new_size) ||
731 (!ip->i_new_size && *pos > ip->i_size)) { 708 (!ip->i_new_size && *pos > i_size_read(inode))) {
732 if (*iolock == XFS_IOLOCK_SHARED) { 709 if (*iolock == XFS_IOLOCK_SHARED) {
733 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock); 710 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock);
734 *iolock = XFS_IOLOCK_EXCL; 711 *iolock = XFS_IOLOCK_EXCL;
735 xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock); 712 xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock);
736 goto restart; 713 goto restart;
737 } 714 }
738 error = -xfs_zero_eof(ip, *pos, ip->i_size); 715 error = -xfs_zero_eof(ip, *pos, i_size_read(inode));
739 } 716 }
740 717
741 /* 718 /*
@@ -744,7 +721,7 @@ restart:
744 * ip->i_new_size if this IO ends beyond any other in-flight writes. 721 * ip->i_new_size if this IO ends beyond any other in-flight writes.
745 */ 722 */
746 new_size = *pos + *count; 723 new_size = *pos + *count;
747 if (new_size > ip->i_size) { 724 if (new_size > i_size_read(inode)) {
748 if (new_size > ip->i_new_size) 725 if (new_size > ip->i_new_size)
749 ip->i_new_size = new_size; 726 ip->i_new_size = new_size;
750 *new_sizep = new_size; 727 *new_sizep = new_size;
@@ -957,11 +934,11 @@ xfs_file_aio_write(
957 ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos, 934 ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos,
958 ocount, &new_size, &iolock); 935 ocount, &new_size, &iolock);
959 936
960 xfs_aio_write_isize_update(inode, &iocb->ki_pos, ret);
961
962 if (ret <= 0) 937 if (ret <= 0)
963 goto out_unlock; 938 goto out_unlock;
964 939
940 XFS_STATS_ADD(xs_write_bytes, ret);
941
965 /* Handle various SYNC-type writes */ 942 /* Handle various SYNC-type writes */
966 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 943 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
967 loff_t end = pos + ret - 1; 944 loff_t end = pos + ret - 1;