aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-09-18 21:24:50 -0400
committerDave Chinner <david@fromorbit.com>2016-09-18 21:24:50 -0400
commit17879e8f865f4ed8b6f9041a2687ad40f13ae460 (patch)
tree4d543b880fb8d762b4a57a4988a2099c1115428b
parenta7d73fe6c538fdba42635c0b8e73382fcd4bd667 (diff)
xfs: fix locking for DAX writes
So far DAX writes inherited the locking from direct I/O writes, but the direct I/O model of using shared locks for writes is actually wrong for DAX. For direct I/O we're out of any standards and don't have to provide the Posix required exclusion between writers, but for DAX which gets transparently enable on applications without any knowledge of it we can't simply drop the requirement. Even worse this only happens for aligned writes and thus doesn't show up for many typical use cases. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/xfs_file.c20
1 files changed, 1 insertions, 19 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index e612a0233710..62649ccdbb4d 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -714,24 +714,11 @@ xfs_file_dax_write(
714 struct address_space *mapping = iocb->ki_filp->f_mapping; 714 struct address_space *mapping = iocb->ki_filp->f_mapping;
715 struct inode *inode = mapping->host; 715 struct inode *inode = mapping->host;
716 struct xfs_inode *ip = XFS_I(inode); 716 struct xfs_inode *ip = XFS_I(inode);
717 struct xfs_mount *mp = ip->i_mount;
718 ssize_t ret = 0; 717 ssize_t ret = 0;
719 int unaligned_io = 0; 718 int iolock = XFS_IOLOCK_EXCL;
720 int iolock;
721 struct iov_iter data; 719 struct iov_iter data;
722 720
723 /* "unaligned" here means not aligned to a filesystem block */
724 if ((iocb->ki_pos & mp->m_blockmask) ||
725 ((iocb->ki_pos + iov_iter_count(from)) & mp->m_blockmask)) {
726 unaligned_io = 1;
727 iolock = XFS_IOLOCK_EXCL;
728 } else if (mapping->nrpages) {
729 iolock = XFS_IOLOCK_EXCL;
730 } else {
731 iolock = XFS_IOLOCK_SHARED;
732 }
733 xfs_rw_ilock(ip, iolock); 721 xfs_rw_ilock(ip, iolock);
734
735 ret = xfs_file_aio_write_checks(iocb, from, &iolock); 722 ret = xfs_file_aio_write_checks(iocb, from, &iolock);
736 if (ret) 723 if (ret)
737 goto out; 724 goto out;
@@ -758,11 +745,6 @@ xfs_file_dax_write(
758 WARN_ON_ONCE(ret); 745 WARN_ON_ONCE(ret);
759 } 746 }
760 747
761 if (iolock == XFS_IOLOCK_EXCL && !unaligned_io) {
762 xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);
763 iolock = XFS_IOLOCK_SHARED;
764 }
765
766 trace_xfs_file_dax_write(ip, iov_iter_count(from), iocb->ki_pos); 748 trace_xfs_file_dax_write(ip, iov_iter_count(from), iocb->ki_pos);
767 749
768 data = *from; 750 data = *from;