Skip to content

Commit

Permalink
xfs: fix locking for DAX writes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Dave Chinner committed Sep 19, 2016
1 parent a7d73fe commit 17879e8
Showing 1 changed file with 1 addition and 19 deletions.
20 changes: 1 addition & 19 deletions fs/xfs/xfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 17879e8

Please sign in to comment.