aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r--fs/xfs/xfs_file.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index bbb9eb6811b2..086440e79b86 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -527,6 +527,15 @@ xfs_file_dio_aio_write(
527 if ((iocb->ki_pos & mp->m_blockmask) || 527 if ((iocb->ki_pos & mp->m_blockmask) ||
528 ((iocb->ki_pos + count) & mp->m_blockmask)) { 528 ((iocb->ki_pos + count) & mp->m_blockmask)) {
529 unaligned_io = 1; 529 unaligned_io = 1;
530
531 /*
532 * We can't properly handle unaligned direct I/O to reflink
533 * files yet, as we can't unshare a partial block.
534 */
535 if (xfs_is_reflink_inode(ip)) {
536 trace_xfs_reflink_bounce_dio_write(ip, iocb->ki_pos, count);
537 return -EREMCHG;
538 }
530 iolock = XFS_IOLOCK_EXCL; 539 iolock = XFS_IOLOCK_EXCL;
531 } else { 540 } else {
532 iolock = XFS_IOLOCK_SHARED; 541 iolock = XFS_IOLOCK_SHARED;
@@ -552,14 +561,6 @@ xfs_file_dio_aio_write(
552 } 561 }
553 562
554 trace_xfs_file_direct_write(ip, count, iocb->ki_pos); 563 trace_xfs_file_direct_write(ip, count, iocb->ki_pos);
555
556 /* If this is a block-aligned directio CoW, remap immediately. */
557 if (xfs_is_reflink_inode(ip) && !unaligned_io) {
558 ret = xfs_reflink_allocate_cow_range(ip, iocb->ki_pos, count);
559 if (ret)
560 goto out;
561 }
562
563 ret = iomap_dio_rw(iocb, from, &xfs_iomap_ops, xfs_dio_write_end_io); 564 ret = iomap_dio_rw(iocb, from, &xfs_iomap_ops, xfs_dio_write_end_io);
564out: 565out:
565 xfs_iunlock(ip, iolock); 566 xfs_iunlock(ip, iolock);
@@ -614,8 +615,10 @@ xfs_file_buffered_aio_write(
614 struct xfs_inode *ip = XFS_I(inode); 615 struct xfs_inode *ip = XFS_I(inode);
615 ssize_t ret; 616 ssize_t ret;
616 int enospc = 0; 617 int enospc = 0;
617 int iolock = XFS_IOLOCK_EXCL; 618 int iolock;
618 619
620write_retry:
621 iolock = XFS_IOLOCK_EXCL;
619 xfs_ilock(ip, iolock); 622 xfs_ilock(ip, iolock);
620 623
621 ret = xfs_file_aio_write_checks(iocb, from, &iolock); 624 ret = xfs_file_aio_write_checks(iocb, from, &iolock);
@@ -625,7 +628,6 @@ xfs_file_buffered_aio_write(
625 /* We can write back this queue in page reclaim */ 628 /* We can write back this queue in page reclaim */
626 current->backing_dev_info = inode_to_bdi(inode); 629 current->backing_dev_info = inode_to_bdi(inode);
627 630
628write_retry:
629 trace_xfs_file_buffered_write(ip, iov_iter_count(from), iocb->ki_pos); 631 trace_xfs_file_buffered_write(ip, iov_iter_count(from), iocb->ki_pos);
630 ret = iomap_file_buffered_write(iocb, from, &xfs_iomap_ops); 632 ret = iomap_file_buffered_write(iocb, from, &xfs_iomap_ops);
631 if (likely(ret >= 0)) 633 if (likely(ret >= 0))
@@ -641,18 +643,21 @@ write_retry:
641 * running at the same time. 643 * running at the same time.
642 */ 644 */
643 if (ret == -EDQUOT && !enospc) { 645 if (ret == -EDQUOT && !enospc) {
646 xfs_iunlock(ip, iolock);
644 enospc = xfs_inode_free_quota_eofblocks(ip); 647 enospc = xfs_inode_free_quota_eofblocks(ip);
645 if (enospc) 648 if (enospc)
646 goto write_retry; 649 goto write_retry;
647 enospc = xfs_inode_free_quota_cowblocks(ip); 650 enospc = xfs_inode_free_quota_cowblocks(ip);
648 if (enospc) 651 if (enospc)
649 goto write_retry; 652 goto write_retry;
653 iolock = 0;
650 } else if (ret == -ENOSPC && !enospc) { 654 } else if (ret == -ENOSPC && !enospc) {
651 struct xfs_eofblocks eofb = {0}; 655 struct xfs_eofblocks eofb = {0};
652 656
653 enospc = 1; 657 enospc = 1;
654 xfs_flush_inodes(ip->i_mount); 658 xfs_flush_inodes(ip->i_mount);
655 eofb.eof_scan_owner = ip->i_ino; /* for locking */ 659
660 xfs_iunlock(ip, iolock);
656 eofb.eof_flags = XFS_EOF_FLAGS_SYNC; 661 eofb.eof_flags = XFS_EOF_FLAGS_SYNC;
657 xfs_icache_free_eofblocks(ip->i_mount, &eofb); 662 xfs_icache_free_eofblocks(ip->i_mount, &eofb);
658 goto write_retry; 663 goto write_retry;
@@ -660,7 +665,8 @@ write_retry:
660 665
661 current->backing_dev_info = NULL; 666 current->backing_dev_info = NULL;
662out: 667out:
663 xfs_iunlock(ip, iolock); 668 if (iolock)
669 xfs_iunlock(ip, iolock);
664 return ret; 670 return ret;
665} 671}
666 672
@@ -908,9 +914,9 @@ xfs_dir_open(
908 */ 914 */
909 mode = xfs_ilock_data_map_shared(ip); 915 mode = xfs_ilock_data_map_shared(ip);
910 if (ip->i_d.di_nextents > 0) 916 if (ip->i_d.di_nextents > 0)
911 xfs_dir3_data_readahead(ip, 0, -1); 917 error = xfs_dir3_data_readahead(ip, 0, -1);
912 xfs_iunlock(ip, mode); 918 xfs_iunlock(ip, mode);
913 return 0; 919 return error;
914} 920}
915 921
916STATIC int 922STATIC int