xfs: fix locking for DAX writes
authorChristoph Hellwig <hch@lst.de>
Mon, 19 Sep 2016 01:24:50 +0000 (11:24 +1000)
committerDave Chinner <david@fromorbit.com>
Mon, 19 Sep 2016 01:24:50 +0000 (11:24 +1000)
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>
fs/xfs/xfs_file.c

index e612a0233710850f34eae93540b098c3ae7cda8c..62649ccdbb4dfc619dd6002719e08d3594e8e98e 100644 (file)
@@ -714,24 +714,11 @@ xfs_file_dax_write(
        struct address_space    *mapping = iocb->ki_filp->f_mapping;
        struct inode            *inode = mapping->host;
        struct xfs_inode        *ip = XFS_I(inode);
-       struct xfs_mount        *mp = ip->i_mount;
        ssize_t                 ret = 0;
-       int                     unaligned_io = 0;
-       int                     iolock;
+       int                     iolock = XFS_IOLOCK_EXCL;
        struct iov_iter         data;
 
-       /* "unaligned" here means not aligned to a filesystem block */
-       if ((iocb->ki_pos & mp->m_blockmask) ||
-           ((iocb->ki_pos + iov_iter_count(from)) & mp->m_blockmask)) {
-               unaligned_io = 1;
-               iolock = XFS_IOLOCK_EXCL;
-       } else if (mapping->nrpages) {
-               iolock = XFS_IOLOCK_EXCL;
-       } else {
-               iolock = XFS_IOLOCK_SHARED;
-       }
        xfs_rw_ilock(ip, iolock);
-
        ret = xfs_file_aio_write_checks(iocb, from, &iolock);
        if (ret)
                goto out;
@@ -758,11 +745,6 @@ xfs_file_dax_write(
                WARN_ON_ONCE(ret);
        }
 
-       if (iolock == XFS_IOLOCK_EXCL && !unaligned_io) {
-               xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);
-               iolock = XFS_IOLOCK_SHARED;
-       }
-
        trace_xfs_file_dax_write(ip, iov_iter_count(from), iocb->ki_pos);
 
        data = *from;