aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_aops.c17
-rw-r--r--fs/xfs/xfs_file.c119
-rw-r--r--fs/xfs/xfs_trace.h1
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
1486xfs_vm_direct_IO( 1486xfs_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
231STATIC ssize_t 231STATIC ssize_t
232xfs_file_aio_read( 232xfs_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 */
360STATIC ssize_t
361xfs_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:
625STATIC ssize_t 577STATIC ssize_t
626xfs_file_dio_aio_write( 578xfs_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
704out: 654out:
705 xfs_rw_iunlock(ip, iolock); 655 xfs_rw_iunlock(ip, iolock);
@@ -712,10 +662,7 @@ out:
712STATIC ssize_t 662STATIC ssize_t
713xfs_file_buffered_aio_write( 663xfs_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
739write_retry: 687write_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
761STATIC ssize_t 709STATIC ssize_t
762xfs_file_aio_write( 710xfs_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
808out:
809 return ret; 744 return ret;
810} 745}
811 746
@@ -1461,12 +1396,12 @@ xfs_file_llseek(
1461 1396
1462const struct file_operations xfs_file_operations = { 1397const 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);
1118DEFINE_RW_EVENT(xfs_file_buffered_write); 1118DEFINE_RW_EVENT(xfs_file_buffered_write);
1119DEFINE_RW_EVENT(xfs_file_direct_write); 1119DEFINE_RW_EVENT(xfs_file_direct_write);
1120DEFINE_RW_EVENT(xfs_file_splice_read); 1120DEFINE_RW_EVENT(xfs_file_splice_read);
1121DEFINE_RW_EVENT(xfs_file_splice_write);
1122 1121
1123DECLARE_EVENT_CLASS(xfs_page_class, 1122DECLARE_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,