diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_file.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index c997aa2751b2..96799eb31c80 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -623,10 +623,7 @@ restart: | |||
623 | STATIC ssize_t | 623 | STATIC ssize_t |
624 | xfs_file_dio_aio_write( | 624 | xfs_file_dio_aio_write( |
625 | struct kiocb *iocb, | 625 | struct kiocb *iocb, |
626 | const struct iovec *iovp, | 626 | struct iov_iter *from) |
627 | unsigned long nr_segs, | ||
628 | loff_t pos, | ||
629 | size_t count) | ||
630 | { | 627 | { |
631 | struct file *file = iocb->ki_filp; | 628 | struct file *file = iocb->ki_filp; |
632 | struct address_space *mapping = file->f_mapping; | 629 | struct address_space *mapping = file->f_mapping; |
@@ -636,16 +633,15 @@ xfs_file_dio_aio_write( | |||
636 | ssize_t ret = 0; | 633 | ssize_t ret = 0; |
637 | int unaligned_io = 0; | 634 | int unaligned_io = 0; |
638 | int iolock; | 635 | int iolock; |
636 | size_t count = iov_iter_count(from); | ||
637 | loff_t pos = iocb->ki_pos; | ||
639 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? | 638 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? |
640 | mp->m_rtdev_targp : mp->m_ddev_targp; | 639 | mp->m_rtdev_targp : mp->m_ddev_targp; |
641 | struct iov_iter from; | ||
642 | 640 | ||
643 | /* DIO must be aligned to device logical sector size */ | 641 | /* DIO must be aligned to device logical sector size */ |
644 | if ((pos | count) & target->bt_logical_sectormask) | 642 | if ((pos | count) & target->bt_logical_sectormask) |
645 | return -XFS_ERROR(EINVAL); | 643 | return -XFS_ERROR(EINVAL); |
646 | 644 | ||
647 | iov_iter_init(&from, WRITE, iovp, nr_segs, count); | ||
648 | |||
649 | /* "unaligned" here means not aligned to a filesystem block */ | 645 | /* "unaligned" here means not aligned to a filesystem block */ |
650 | if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) | 646 | if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) |
651 | unaligned_io = 1; | 647 | unaligned_io = 1; |
@@ -677,7 +673,7 @@ xfs_file_dio_aio_write( | |||
677 | ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); | 673 | ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); |
678 | if (ret) | 674 | if (ret) |
679 | goto out; | 675 | goto out; |
680 | iov_iter_truncate(&from, count); | 676 | iov_iter_truncate(from, count); |
681 | 677 | ||
682 | if (mapping->nrpages) { | 678 | if (mapping->nrpages) { |
683 | ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, | 679 | ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, |
@@ -699,7 +695,7 @@ xfs_file_dio_aio_write( | |||
699 | } | 695 | } |
700 | 696 | ||
701 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); | 697 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); |
702 | ret = generic_file_direct_write(iocb, &from, pos); | 698 | ret = generic_file_direct_write(iocb, from, pos); |
703 | 699 | ||
704 | out: | 700 | out: |
705 | xfs_rw_iunlock(ip, iolock); | 701 | xfs_rw_iunlock(ip, iolock); |
@@ -712,10 +708,7 @@ out: | |||
712 | STATIC ssize_t | 708 | STATIC ssize_t |
713 | xfs_file_buffered_aio_write( | 709 | xfs_file_buffered_aio_write( |
714 | struct kiocb *iocb, | 710 | struct kiocb *iocb, |
715 | const struct iovec *iovp, | 711 | struct iov_iter *from) |
716 | unsigned long nr_segs, | ||
717 | loff_t pos, | ||
718 | size_t count) | ||
719 | { | 712 | { |
720 | struct file *file = iocb->ki_filp; | 713 | struct file *file = iocb->ki_filp; |
721 | struct address_space *mapping = file->f_mapping; | 714 | struct address_space *mapping = file->f_mapping; |
@@ -724,7 +717,8 @@ xfs_file_buffered_aio_write( | |||
724 | ssize_t ret; | 717 | ssize_t ret; |
725 | int enospc = 0; | 718 | int enospc = 0; |
726 | int iolock = XFS_IOLOCK_EXCL; | 719 | int iolock = XFS_IOLOCK_EXCL; |
727 | struct iov_iter from; | 720 | loff_t pos = iocb->ki_pos; |
721 | size_t count = iov_iter_count(from); | ||
728 | 722 | ||
729 | xfs_rw_ilock(ip, iolock); | 723 | xfs_rw_ilock(ip, iolock); |
730 | 724 | ||
@@ -732,13 +726,13 @@ xfs_file_buffered_aio_write( | |||
732 | if (ret) | 726 | if (ret) |
733 | goto out; | 727 | goto out; |
734 | 728 | ||
735 | iov_iter_init(&from, WRITE, iovp, nr_segs, count); | 729 | iov_iter_truncate(from, count); |
736 | /* We can write back this queue in page reclaim */ | 730 | /* We can write back this queue in page reclaim */ |
737 | current->backing_dev_info = mapping->backing_dev_info; | 731 | current->backing_dev_info = mapping->backing_dev_info; |
738 | 732 | ||
739 | write_retry: | 733 | write_retry: |
740 | trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0); | 734 | trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0); |
741 | ret = generic_perform_write(file, &from, pos); | 735 | ret = generic_perform_write(file, from, pos); |
742 | if (likely(ret >= 0)) | 736 | if (likely(ret >= 0)) |
743 | iocb->ki_pos = pos + ret; | 737 | iocb->ki_pos = pos + ret; |
744 | /* | 738 | /* |
@@ -771,6 +765,7 @@ xfs_file_aio_write( | |||
771 | struct xfs_inode *ip = XFS_I(inode); | 765 | struct xfs_inode *ip = XFS_I(inode); |
772 | ssize_t ret; | 766 | ssize_t ret; |
773 | size_t ocount = 0; | 767 | size_t ocount = 0; |
768 | struct iov_iter from; | ||
774 | 769 | ||
775 | XFS_STATS_INC(xs_write_calls); | 770 | XFS_STATS_INC(xs_write_calls); |
776 | 771 | ||
@@ -779,6 +774,7 @@ xfs_file_aio_write( | |||
779 | ocount = iov_length(iovp, nr_segs); | 774 | ocount = iov_length(iovp, nr_segs); |
780 | if (ocount == 0) | 775 | if (ocount == 0) |
781 | return 0; | 776 | return 0; |
777 | iov_iter_init(&from, WRITE, iovp, nr_segs, ocount); | ||
782 | 778 | ||
783 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 779 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
784 | ret = -EIO; | 780 | ret = -EIO; |
@@ -786,10 +782,9 @@ xfs_file_aio_write( | |||
786 | } | 782 | } |
787 | 783 | ||
788 | if (unlikely(file->f_flags & O_DIRECT)) | 784 | if (unlikely(file->f_flags & O_DIRECT)) |
789 | ret = xfs_file_dio_aio_write(iocb, iovp, nr_segs, pos, ocount); | 785 | ret = xfs_file_dio_aio_write(iocb, &from); |
790 | else | 786 | else |
791 | ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos, | 787 | ret = xfs_file_buffered_aio_write(iocb, &from); |
792 | ocount); | ||
793 | 788 | ||
794 | if (ret > 0) { | 789 | if (ret > 0) { |
795 | ssize_t err; | 790 | ssize_t err; |