aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_file.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 43c0e6686c47..ebde43e15dd9 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -544,17 +544,18 @@ xfs_zero_eof(
544 */ 544 */
545STATIC ssize_t 545STATIC ssize_t
546xfs_file_aio_write_checks( 546xfs_file_aio_write_checks(
547 struct file *file, 547 struct kiocb *iocb,
548 loff_t *pos, 548 struct iov_iter *from,
549 size_t *count,
550 int *iolock) 549 int *iolock)
551{ 550{
551 struct file *file = iocb->ki_filp;
552 struct inode *inode = file->f_mapping->host; 552 struct inode *inode = file->f_mapping->host;
553 struct xfs_inode *ip = XFS_I(inode); 553 struct xfs_inode *ip = XFS_I(inode);
554 int error = 0; 554 int error = 0;
555 size_t count = iov_iter_count(from);
555 556
556restart: 557restart:
557 error = generic_write_checks(file, pos, count); 558 error = generic_write_checks(file, &iocb->ki_pos, &count);
558 if (error) 559 if (error)
559 return error; 560 return error;
560 561
@@ -569,7 +570,7 @@ restart:
569 * iolock shared, we need to update it to exclusive which implies 570 * iolock shared, we need to update it to exclusive which implies
570 * having to redo all checks before. 571 * having to redo all checks before.
571 */ 572 */
572 if (*pos > i_size_read(inode)) { 573 if (iocb->ki_pos > i_size_read(inode)) {
573 bool zero = false; 574 bool zero = false;
574 575
575 if (*iolock == XFS_IOLOCK_SHARED) { 576 if (*iolock == XFS_IOLOCK_SHARED) {
@@ -578,10 +579,11 @@ restart:
578 xfs_rw_ilock(ip, *iolock); 579 xfs_rw_ilock(ip, *iolock);
579 goto restart; 580 goto restart;
580 } 581 }
581 error = xfs_zero_eof(ip, *pos, i_size_read(inode), &zero); 582 error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero);
582 if (error) 583 if (error)
583 return error; 584 return error;
584 } 585 }
586 iov_iter_truncate(from, count);
585 587
586 /* 588 /*
587 * Updating the timestamps will grab the ilock again from 589 * Updating the timestamps will grab the ilock again from
@@ -678,10 +680,11 @@ xfs_file_dio_aio_write(
678 xfs_rw_ilock(ip, iolock); 680 xfs_rw_ilock(ip, iolock);
679 } 681 }
680 682
681 ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); 683 ret = xfs_file_aio_write_checks(iocb, from, &iolock);
682 if (ret) 684 if (ret)
683 goto out; 685 goto out;
684 iov_iter_truncate(from, count); 686 count = iov_iter_count(from);
687 pos = iocb->ki_pos;
685 688
686 if (mapping->nrpages) { 689 if (mapping->nrpages) {
687 ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, 690 ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
@@ -734,24 +737,22 @@ xfs_file_buffered_aio_write(
734 ssize_t ret; 737 ssize_t ret;
735 int enospc = 0; 738 int enospc = 0;
736 int iolock = XFS_IOLOCK_EXCL; 739 int iolock = XFS_IOLOCK_EXCL;
737 loff_t pos = iocb->ki_pos;
738 size_t count = iov_iter_count(from);
739 740
740 xfs_rw_ilock(ip, iolock); 741 xfs_rw_ilock(ip, iolock);
741 742
742 ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); 743 ret = xfs_file_aio_write_checks(iocb, from, &iolock);
743 if (ret) 744 if (ret)
744 goto out; 745 goto out;
745 746
746 iov_iter_truncate(from, count);
747 /* We can write back this queue in page reclaim */ 747 /* We can write back this queue in page reclaim */
748 current->backing_dev_info = inode_to_bdi(inode); 748 current->backing_dev_info = inode_to_bdi(inode);
749 749
750write_retry: 750write_retry:
751 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0); 751 trace_xfs_file_buffered_write(ip, iov_iter_count(from),
752 ret = generic_perform_write(file, from, pos); 752 iocb->ki_pos, 0);
753 ret = generic_perform_write(file, from, iocb->ki_pos);
753 if (likely(ret >= 0)) 754 if (likely(ret >= 0))
754 iocb->ki_pos = pos + ret; 755 iocb->ki_pos += ret;
755 756
756 /* 757 /*
757 * If we hit a space limit, try to free up some lingering preallocated 758 * If we hit a space limit, try to free up some lingering preallocated