diff options
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r-- | fs/xfs/xfs_file.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 44856c3b9617..1f12ad0a8585 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -279,7 +279,7 @@ xfs_file_read_iter( | |||
279 | 279 | ||
280 | XFS_STATS_INC(xs_read_calls); | 280 | XFS_STATS_INC(xs_read_calls); |
281 | 281 | ||
282 | if (unlikely(file->f_flags & O_DIRECT)) | 282 | if (unlikely(iocb->ki_flags & IOCB_DIRECT)) |
283 | ioflags |= XFS_IO_ISDIRECT; | 283 | ioflags |= XFS_IO_ISDIRECT; |
284 | if (file->f_mode & FMODE_NOCMTIME) | 284 | if (file->f_mode & FMODE_NOCMTIME) |
285 | ioflags |= XFS_IO_INVIS; | 285 | ioflags |= XFS_IO_INVIS; |
@@ -544,18 +544,19 @@ xfs_zero_eof( | |||
544 | */ | 544 | */ |
545 | STATIC ssize_t | 545 | STATIC ssize_t |
546 | xfs_file_aio_write_checks( | 546 | xfs_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 | ssize_t error = 0; |
555 | size_t count = iov_iter_count(from); | ||
555 | 556 | ||
556 | restart: | 557 | restart: |
557 | error = generic_write_checks(file, pos, count, S_ISBLK(inode->i_mode)); | 558 | error = generic_write_checks(iocb, from); |
558 | if (error) | 559 | if (error <= 0) |
559 | return error; | 560 | return error; |
560 | 561 | ||
561 | error = xfs_break_layouts(inode, iolock); | 562 | error = xfs_break_layouts(inode, iolock); |
@@ -569,16 +570,17 @@ 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) { |
576 | xfs_rw_iunlock(ip, *iolock); | 577 | xfs_rw_iunlock(ip, *iolock); |
577 | *iolock = XFS_IOLOCK_EXCL; | 578 | *iolock = XFS_IOLOCK_EXCL; |
578 | xfs_rw_ilock(ip, *iolock); | 579 | xfs_rw_ilock(ip, *iolock); |
580 | iov_iter_reexpand(from, count); | ||
579 | goto restart; | 581 | goto restart; |
580 | } | 582 | } |
581 | error = xfs_zero_eof(ip, *pos, i_size_read(inode), &zero); | 583 | error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero); |
582 | if (error) | 584 | if (error) |
583 | return error; | 585 | return error; |
584 | } | 586 | } |
@@ -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 | ||
750 | write_retry: | 750 | write_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 |
@@ -803,7 +804,7 @@ xfs_file_write_iter( | |||
803 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 804 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
804 | return -EIO; | 805 | return -EIO; |
805 | 806 | ||
806 | if (unlikely(file->f_flags & O_DIRECT)) | 807 | if (unlikely(iocb->ki_flags & IOCB_DIRECT)) |
807 | ret = xfs_file_dio_aio_write(iocb, from); | 808 | ret = xfs_file_dio_aio_write(iocb, from); |
808 | else | 809 | else |
809 | ret = xfs_file_buffered_aio_write(iocb, from); | 810 | ret = xfs_file_buffered_aio_write(iocb, from); |