diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_aops.c | 17 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 119 | ||||
-rw-r--r-- | fs/xfs/xfs_trace.h | 1 |
3 files changed, 34 insertions, 103 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e32640eedea6..faaf716e2080 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -1486,9 +1486,8 @@ STATIC ssize_t | |||
1486 | xfs_vm_direct_IO( | 1486 | xfs_vm_direct_IO( |
1487 | int rw, | 1487 | int rw, |
1488 | struct kiocb *iocb, | 1488 | struct kiocb *iocb, |
1489 | const struct iovec *iov, | 1489 | struct iov_iter *iter, |
1490 | loff_t offset, | 1490 | loff_t offset) |
1491 | unsigned long nr_segs) | ||
1492 | { | 1491 | { |
1493 | struct inode *inode = iocb->ki_filp->f_mapping->host; | 1492 | struct inode *inode = iocb->ki_filp->f_mapping->host; |
1494 | struct block_device *bdev = xfs_find_bdev_for_inode(inode); | 1493 | struct block_device *bdev = xfs_find_bdev_for_inode(inode); |
@@ -1496,7 +1495,7 @@ xfs_vm_direct_IO( | |||
1496 | ssize_t ret; | 1495 | ssize_t ret; |
1497 | 1496 | ||
1498 | if (rw & WRITE) { | 1497 | if (rw & WRITE) { |
1499 | size_t size = iov_length(iov, nr_segs); | 1498 | size_t size = iov_iter_count(iter); |
1500 | 1499 | ||
1501 | /* | 1500 | /* |
1502 | * We cannot preallocate a size update transaction here as we | 1501 | * We cannot preallocate a size update transaction here as we |
@@ -1508,17 +1507,15 @@ xfs_vm_direct_IO( | |||
1508 | if (offset + size > XFS_I(inode)->i_d.di_size) | 1507 | if (offset + size > XFS_I(inode)->i_d.di_size) |
1509 | ioend->io_isdirect = 1; | 1508 | ioend->io_isdirect = 1; |
1510 | 1509 | ||
1511 | ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, | 1510 | ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iter, |
1512 | offset, nr_segs, | 1511 | offset, xfs_get_blocks_direct, |
1513 | xfs_get_blocks_direct, | ||
1514 | xfs_end_io_direct_write, NULL, | 1512 | xfs_end_io_direct_write, NULL, |
1515 | DIO_ASYNC_EXTEND); | 1513 | DIO_ASYNC_EXTEND); |
1516 | if (ret != -EIOCBQUEUED && iocb->private) | 1514 | if (ret != -EIOCBQUEUED && iocb->private) |
1517 | goto out_destroy_ioend; | 1515 | goto out_destroy_ioend; |
1518 | } else { | 1516 | } else { |
1519 | ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, | 1517 | ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iter, |
1520 | offset, nr_segs, | 1518 | offset, xfs_get_blocks_direct, |
1521 | xfs_get_blocks_direct, | ||
1522 | NULL, NULL, 0); | 1519 | NULL, NULL, 0); |
1523 | } | 1520 | } |
1524 | 1521 | ||
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 1b8160dc04d1..1f66779d7a46 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -229,34 +229,27 @@ xfs_file_fsync( | |||
229 | } | 229 | } |
230 | 230 | ||
231 | STATIC ssize_t | 231 | STATIC ssize_t |
232 | xfs_file_aio_read( | 232 | xfs_file_read_iter( |
233 | struct kiocb *iocb, | 233 | struct kiocb *iocb, |
234 | const struct iovec *iovp, | 234 | struct iov_iter *to) |
235 | unsigned long nr_segs, | ||
236 | loff_t pos) | ||
237 | { | 235 | { |
238 | struct file *file = iocb->ki_filp; | 236 | struct file *file = iocb->ki_filp; |
239 | struct inode *inode = file->f_mapping->host; | 237 | struct inode *inode = file->f_mapping->host; |
240 | struct xfs_inode *ip = XFS_I(inode); | 238 | struct xfs_inode *ip = XFS_I(inode); |
241 | struct xfs_mount *mp = ip->i_mount; | 239 | struct xfs_mount *mp = ip->i_mount; |
242 | size_t size = 0; | 240 | size_t size = iov_iter_count(to); |
243 | ssize_t ret = 0; | 241 | ssize_t ret = 0; |
244 | int ioflags = 0; | 242 | int ioflags = 0; |
245 | xfs_fsize_t n; | 243 | xfs_fsize_t n; |
244 | loff_t pos = iocb->ki_pos; | ||
246 | 245 | ||
247 | XFS_STATS_INC(xs_read_calls); | 246 | XFS_STATS_INC(xs_read_calls); |
248 | 247 | ||
249 | BUG_ON(iocb->ki_pos != pos); | ||
250 | |||
251 | if (unlikely(file->f_flags & O_DIRECT)) | 248 | if (unlikely(file->f_flags & O_DIRECT)) |
252 | ioflags |= IO_ISDIRECT; | 249 | ioflags |= IO_ISDIRECT; |
253 | if (file->f_mode & FMODE_NOCMTIME) | 250 | if (file->f_mode & FMODE_NOCMTIME) |
254 | ioflags |= IO_INVIS; | 251 | ioflags |= IO_INVIS; |
255 | 252 | ||
256 | ret = generic_segment_checks(iovp, &nr_segs, &size, VERIFY_WRITE); | ||
257 | if (ret < 0) | ||
258 | return ret; | ||
259 | |||
260 | if (unlikely(ioflags & IO_ISDIRECT)) { | 253 | if (unlikely(ioflags & IO_ISDIRECT)) { |
261 | xfs_buftarg_t *target = | 254 | xfs_buftarg_t *target = |
262 | XFS_IS_REALTIME_INODE(ip) ? | 255 | XFS_IS_REALTIME_INODE(ip) ? |
@@ -309,7 +302,7 @@ xfs_file_aio_read( | |||
309 | 302 | ||
310 | trace_xfs_file_read(ip, size, pos, ioflags); | 303 | trace_xfs_file_read(ip, size, pos, ioflags); |
311 | 304 | ||
312 | ret = generic_file_aio_read(iocb, iovp, nr_segs, pos); | 305 | ret = generic_file_read_iter(iocb, to); |
313 | if (ret > 0) | 306 | if (ret > 0) |
314 | XFS_STATS_ADD(xs_read_bytes, ret); | 307 | XFS_STATS_ADD(xs_read_bytes, ret); |
315 | 308 | ||
@@ -350,47 +343,6 @@ xfs_file_splice_read( | |||
350 | } | 343 | } |
351 | 344 | ||
352 | /* | 345 | /* |
353 | * xfs_file_splice_write() does not use xfs_rw_ilock() because | ||
354 | * generic_file_splice_write() takes the i_mutex itself. This, in theory, | ||
355 | * couuld cause lock inversions between the aio_write path and the splice path | ||
356 | * if someone is doing concurrent splice(2) based writes and write(2) based | ||
357 | * writes to the same inode. The only real way to fix this is to re-implement | ||
358 | * the generic code here with correct locking orders. | ||
359 | */ | ||
360 | STATIC ssize_t | ||
361 | xfs_file_splice_write( | ||
362 | struct pipe_inode_info *pipe, | ||
363 | struct file *outfilp, | ||
364 | loff_t *ppos, | ||
365 | size_t count, | ||
366 | unsigned int flags) | ||
367 | { | ||
368 | struct inode *inode = outfilp->f_mapping->host; | ||
369 | struct xfs_inode *ip = XFS_I(inode); | ||
370 | int ioflags = 0; | ||
371 | ssize_t ret; | ||
372 | |||
373 | XFS_STATS_INC(xs_write_calls); | ||
374 | |||
375 | if (outfilp->f_mode & FMODE_NOCMTIME) | ||
376 | ioflags |= IO_INVIS; | ||
377 | |||
378 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | ||
379 | return -EIO; | ||
380 | |||
381 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
382 | |||
383 | trace_xfs_file_splice_write(ip, count, *ppos, ioflags); | ||
384 | |||
385 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); | ||
386 | if (ret > 0) | ||
387 | XFS_STATS_ADD(xs_write_bytes, ret); | ||
388 | |||
389 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * This routine is called to handle zeroing any space in the last block of the | 346 | * This routine is called to handle zeroing any space in the last block of the |
395 | * file that is beyond the EOF. We do this since the size is being increased | 347 | * file that is beyond the EOF. We do this since the size is being increased |
396 | * without writing anything to that block and we don't want to read the | 348 | * without writing anything to that block and we don't want to read the |
@@ -625,10 +577,7 @@ restart: | |||
625 | STATIC ssize_t | 577 | STATIC ssize_t |
626 | xfs_file_dio_aio_write( | 578 | xfs_file_dio_aio_write( |
627 | struct kiocb *iocb, | 579 | struct kiocb *iocb, |
628 | const struct iovec *iovp, | 580 | struct iov_iter *from) |
629 | unsigned long nr_segs, | ||
630 | loff_t pos, | ||
631 | size_t ocount) | ||
632 | { | 581 | { |
633 | struct file *file = iocb->ki_filp; | 582 | struct file *file = iocb->ki_filp; |
634 | struct address_space *mapping = file->f_mapping; | 583 | struct address_space *mapping = file->f_mapping; |
@@ -636,9 +585,10 @@ xfs_file_dio_aio_write( | |||
636 | struct xfs_inode *ip = XFS_I(inode); | 585 | struct xfs_inode *ip = XFS_I(inode); |
637 | struct xfs_mount *mp = ip->i_mount; | 586 | struct xfs_mount *mp = ip->i_mount; |
638 | ssize_t ret = 0; | 587 | ssize_t ret = 0; |
639 | size_t count = ocount; | ||
640 | int unaligned_io = 0; | 588 | int unaligned_io = 0; |
641 | int iolock; | 589 | int iolock; |
590 | size_t count = iov_iter_count(from); | ||
591 | loff_t pos = iocb->ki_pos; | ||
642 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? | 592 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? |
643 | mp->m_rtdev_targp : mp->m_ddev_targp; | 593 | mp->m_rtdev_targp : mp->m_ddev_targp; |
644 | 594 | ||
@@ -677,6 +627,7 @@ xfs_file_dio_aio_write( | |||
677 | ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); | 627 | ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); |
678 | if (ret) | 628 | if (ret) |
679 | goto out; | 629 | goto out; |
630 | iov_iter_truncate(from, count); | ||
680 | 631 | ||
681 | if (mapping->nrpages) { | 632 | if (mapping->nrpages) { |
682 | ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, | 633 | ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, |
@@ -698,8 +649,7 @@ xfs_file_dio_aio_write( | |||
698 | } | 649 | } |
699 | 650 | ||
700 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); | 651 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); |
701 | ret = generic_file_direct_write(iocb, iovp, | 652 | ret = generic_file_direct_write(iocb, from, pos); |
702 | &nr_segs, pos, count, ocount); | ||
703 | 653 | ||
704 | out: | 654 | out: |
705 | xfs_rw_iunlock(ip, iolock); | 655 | xfs_rw_iunlock(ip, iolock); |
@@ -712,10 +662,7 @@ out: | |||
712 | STATIC ssize_t | 662 | STATIC ssize_t |
713 | xfs_file_buffered_aio_write( | 663 | xfs_file_buffered_aio_write( |
714 | struct kiocb *iocb, | 664 | struct kiocb *iocb, |
715 | const struct iovec *iovp, | 665 | struct iov_iter *from) |
716 | unsigned long nr_segs, | ||
717 | loff_t pos, | ||
718 | size_t count) | ||
719 | { | 666 | { |
720 | struct file *file = iocb->ki_filp; | 667 | struct file *file = iocb->ki_filp; |
721 | struct address_space *mapping = file->f_mapping; | 668 | struct address_space *mapping = file->f_mapping; |
@@ -724,7 +671,8 @@ xfs_file_buffered_aio_write( | |||
724 | ssize_t ret; | 671 | ssize_t ret; |
725 | int enospc = 0; | 672 | int enospc = 0; |
726 | int iolock = XFS_IOLOCK_EXCL; | 673 | int iolock = XFS_IOLOCK_EXCL; |
727 | struct iov_iter from; | 674 | loff_t pos = iocb->ki_pos; |
675 | size_t count = iov_iter_count(from); | ||
728 | 676 | ||
729 | xfs_rw_ilock(ip, iolock); | 677 | xfs_rw_ilock(ip, iolock); |
730 | 678 | ||
@@ -732,13 +680,13 @@ xfs_file_buffered_aio_write( | |||
732 | if (ret) | 680 | if (ret) |
733 | goto out; | 681 | goto out; |
734 | 682 | ||
735 | iov_iter_init(&from, iovp, nr_segs, count, 0); | 683 | iov_iter_truncate(from, count); |
736 | /* We can write back this queue in page reclaim */ | 684 | /* We can write back this queue in page reclaim */ |
737 | current->backing_dev_info = mapping->backing_dev_info; | 685 | current->backing_dev_info = mapping->backing_dev_info; |
738 | 686 | ||
739 | write_retry: | 687 | write_retry: |
740 | trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0); | 688 | trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0); |
741 | ret = generic_perform_write(file, &from, pos); | 689 | ret = generic_perform_write(file, from, pos); |
742 | if (likely(ret >= 0)) | 690 | if (likely(ret >= 0)) |
743 | iocb->ki_pos = pos + ret; | 691 | iocb->ki_pos = pos + ret; |
744 | /* | 692 | /* |
@@ -759,40 +707,29 @@ out: | |||
759 | } | 707 | } |
760 | 708 | ||
761 | STATIC ssize_t | 709 | STATIC ssize_t |
762 | xfs_file_aio_write( | 710 | xfs_file_write_iter( |
763 | struct kiocb *iocb, | 711 | struct kiocb *iocb, |
764 | const struct iovec *iovp, | 712 | struct iov_iter *from) |
765 | unsigned long nr_segs, | ||
766 | loff_t pos) | ||
767 | { | 713 | { |
768 | struct file *file = iocb->ki_filp; | 714 | struct file *file = iocb->ki_filp; |
769 | struct address_space *mapping = file->f_mapping; | 715 | struct address_space *mapping = file->f_mapping; |
770 | struct inode *inode = mapping->host; | 716 | struct inode *inode = mapping->host; |
771 | struct xfs_inode *ip = XFS_I(inode); | 717 | struct xfs_inode *ip = XFS_I(inode); |
772 | ssize_t ret; | 718 | ssize_t ret; |
773 | size_t ocount = 0; | 719 | size_t ocount = iov_iter_count(from); |
774 | 720 | ||
775 | XFS_STATS_INC(xs_write_calls); | 721 | XFS_STATS_INC(xs_write_calls); |
776 | 722 | ||
777 | BUG_ON(iocb->ki_pos != pos); | ||
778 | |||
779 | ret = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ); | ||
780 | if (ret) | ||
781 | return ret; | ||
782 | |||
783 | if (ocount == 0) | 723 | if (ocount == 0) |
784 | return 0; | 724 | return 0; |
785 | 725 | ||
786 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 726 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
787 | ret = -EIO; | 727 | return -EIO; |
788 | goto out; | ||
789 | } | ||
790 | 728 | ||
791 | if (unlikely(file->f_flags & O_DIRECT)) | 729 | if (unlikely(file->f_flags & O_DIRECT)) |
792 | ret = xfs_file_dio_aio_write(iocb, iovp, nr_segs, pos, ocount); | 730 | ret = xfs_file_dio_aio_write(iocb, from); |
793 | else | 731 | else |
794 | ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos, | 732 | ret = xfs_file_buffered_aio_write(iocb, from); |
795 | ocount); | ||
796 | 733 | ||
797 | if (ret > 0) { | 734 | if (ret > 0) { |
798 | ssize_t err; | 735 | ssize_t err; |
@@ -804,8 +741,6 @@ xfs_file_aio_write( | |||
804 | if (err < 0) | 741 | if (err < 0) |
805 | ret = err; | 742 | ret = err; |
806 | } | 743 | } |
807 | |||
808 | out: | ||
809 | return ret; | 744 | return ret; |
810 | } | 745 | } |
811 | 746 | ||
@@ -1461,12 +1396,12 @@ xfs_file_llseek( | |||
1461 | 1396 | ||
1462 | const struct file_operations xfs_file_operations = { | 1397 | const struct file_operations xfs_file_operations = { |
1463 | .llseek = xfs_file_llseek, | 1398 | .llseek = xfs_file_llseek, |
1464 | .read = do_sync_read, | 1399 | .read = new_sync_read, |
1465 | .write = do_sync_write, | 1400 | .write = new_sync_write, |
1466 | .aio_read = xfs_file_aio_read, | 1401 | .read_iter = xfs_file_read_iter, |
1467 | .aio_write = xfs_file_aio_write, | 1402 | .write_iter = xfs_file_write_iter, |
1468 | .splice_read = xfs_file_splice_read, | 1403 | .splice_read = xfs_file_splice_read, |
1469 | .splice_write = xfs_file_splice_write, | 1404 | .splice_write = iter_file_splice_write, |
1470 | .unlocked_ioctl = xfs_file_ioctl, | 1405 | .unlocked_ioctl = xfs_file_ioctl, |
1471 | #ifdef CONFIG_COMPAT | 1406 | #ifdef CONFIG_COMPAT |
1472 | .compat_ioctl = xfs_file_compat_ioctl, | 1407 | .compat_ioctl = xfs_file_compat_ioctl, |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 6910458915cf..152f82782630 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -1118,7 +1118,6 @@ DEFINE_RW_EVENT(xfs_file_read); | |||
1118 | DEFINE_RW_EVENT(xfs_file_buffered_write); | 1118 | DEFINE_RW_EVENT(xfs_file_buffered_write); |
1119 | DEFINE_RW_EVENT(xfs_file_direct_write); | 1119 | DEFINE_RW_EVENT(xfs_file_direct_write); |
1120 | DEFINE_RW_EVENT(xfs_file_splice_read); | 1120 | DEFINE_RW_EVENT(xfs_file_splice_read); |
1121 | DEFINE_RW_EVENT(xfs_file_splice_write); | ||
1122 | 1121 | ||
1123 | DECLARE_EVENT_CLASS(xfs_page_class, | 1122 | DECLARE_EVENT_CLASS(xfs_page_class, |
1124 | TP_PROTO(struct inode *inode, struct page *page, unsigned long off, | 1123 | TP_PROTO(struct inode *inode, struct page *page, unsigned long off, |