aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 5863dd8f448c..ef51eb43e137 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -684,9 +684,24 @@ xfs_file_aio_write_checks(
684 * xfs_file_dio_aio_write - handle direct IO writes 684 * xfs_file_dio_aio_write - handle direct IO writes
685 * 685 *
686 * Lock the inode appropriately to prepare for and issue a direct IO write. 686 * Lock the inode appropriately to prepare for and issue a direct IO write.
687 * By spearating it from the buffered write path we remove all the tricky to 687 * By separating it from the buffered write path we remove all the tricky to
688 * follow locking changes and looping. 688 * follow locking changes and looping.
689 * 689 *
690 * If there are cached pages or we're extending the file, we need IOLOCK_EXCL
691 * until we're sure the bytes at the new EOF have been zeroed and/or the cached
692 * pages are flushed out.
693 *
694 * In most cases the direct IO writes will be done holding IOLOCK_SHARED
695 * allowing them to be done in parallel with reads and other direct IO writes.
696 * However, if the IO is not aligned to filesystem blocks, the direct IO layer
697 * needs to do sub-block zeroing and that requires serialisation against other
698 * direct IOs to the same block. In this case we need to serialise the
699 * submission of the unaligned IOs so that we don't get racing block zeroing in
700 * the dio layer. To avoid the problem with aio, we also need to wait for
701 * outstanding IOs to complete so that unwritten extent conversion is completed
702 * before we try to map the overlapping block. This is currently implemented by
703 * hitting it with a big hammer (i.e. xfs_ioend_wait()).
704 *
690 * Returns with locks held indicated by @iolock and errors indicated by 705 * Returns with locks held indicated by @iolock and errors indicated by
691 * negative return values. 706 * negative return values.
692 */ 707 */
@@ -706,6 +721,7 @@ xfs_file_dio_aio_write(
706 struct xfs_mount *mp = ip->i_mount; 721 struct xfs_mount *mp = ip->i_mount;
707 ssize_t ret = 0; 722 ssize_t ret = 0;
708 size_t count = ocount; 723 size_t count = ocount;
724 int unaligned_io = 0;
709 struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? 725 struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ?
710 mp->m_rtdev_targp : mp->m_ddev_targp; 726 mp->m_rtdev_targp : mp->m_ddev_targp;
711 727
@@ -713,13 +729,10 @@ xfs_file_dio_aio_write(
713 if ((pos & target->bt_smask) || (count & target->bt_smask)) 729 if ((pos & target->bt_smask) || (count & target->bt_smask))
714 return -XFS_ERROR(EINVAL); 730 return -XFS_ERROR(EINVAL);
715 731
716 /* 732 if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask))
717 * For direct I/O, if there are cached pages or we're extending 733 unaligned_io = 1;
718 * the file, we need IOLOCK_EXCL until we're sure the bytes at 734
719 * the new EOF have been zeroed and/or the cached pages are 735 if (unaligned_io || mapping->nrpages || pos > ip->i_size)
720 * flushed out.
721 */
722 if (mapping->nrpages || pos > ip->i_size)
723 *iolock = XFS_IOLOCK_EXCL; 736 *iolock = XFS_IOLOCK_EXCL;
724 else 737 else
725 *iolock = XFS_IOLOCK_SHARED; 738 *iolock = XFS_IOLOCK_SHARED;
@@ -737,8 +750,13 @@ xfs_file_dio_aio_write(
737 return ret; 750 return ret;
738 } 751 }
739 752
740 if (*iolock == XFS_IOLOCK_EXCL) { 753 /*
741 /* demote the lock now the cached pages are gone */ 754 * If we are doing unaligned IO, wait for all other IO to drain,
755 * otherwise demote the lock if we had to flush cached pages
756 */
757 if (unaligned_io)
758 xfs_ioend_wait(ip);
759 else if (*iolock == XFS_IOLOCK_EXCL) {
742 xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL); 760 xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);
743 *iolock = XFS_IOLOCK_SHARED; 761 *iolock = XFS_IOLOCK_SHARED;
744 } 762 }