Skip to content

Commit 68456d0

Browse files
johnpgarrycmaiolino
authored andcommitted
xfs: disallow atomic writes on DAX
Atomic writes are not currently supported for DAX, but two problems exist: - we may go down DAX write path for IOCB_ATOMIC, which does not handle IOCB_ATOMIC properly - we report non-zero atomic write limits in statx (for DAX inodes) We may want atomic writes support on DAX in future, but just disallow for now. For this, ensure when IOCB_ATOMIC is set that we check the write size versus the atomic write min and max before branching off to the DAX write path. This is not strictly required for DAX, as we should not get this far in the write path as FMODE_CAN_ATOMIC_WRITE should not be set. In addition, due to reflink being supported for DAX, we automatically get CoW-based atomic writes support being advertised. Remedy this by disallowing atomic writes for a DAX inode for both sw and hw modes. Reported-by: Darrick J. Wong <[email protected]> Fixes: 9dffc58 ("xfs: update atomic write limits") Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: John Garry <[email protected]> Signed-off-by: Carlos Maiolino <[email protected]>
1 parent e7fb9b7 commit 68456d0

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

fs/xfs/xfs_file.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,9 +1101,6 @@ xfs_file_write_iter(
11011101
if (xfs_is_shutdown(ip->i_mount))
11021102
return -EIO;
11031103

1104-
if (IS_DAX(inode))
1105-
return xfs_file_dax_write(iocb, from);
1106-
11071104
if (iocb->ki_flags & IOCB_ATOMIC) {
11081105
if (ocount < xfs_get_atomic_write_min(ip))
11091106
return -EINVAL;
@@ -1116,6 +1113,9 @@ xfs_file_write_iter(
11161113
return ret;
11171114
}
11181115

1116+
if (IS_DAX(inode))
1117+
return xfs_file_dax_write(iocb, from);
1118+
11191119
if (iocb->ki_flags & IOCB_DIRECT) {
11201120
/*
11211121
* Allow a directio write to fall back to a buffered

fs/xfs/xfs_inode.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,20 @@ static inline bool xfs_inode_has_bigrtalloc(const struct xfs_inode *ip)
358358

359359
static inline bool xfs_inode_can_hw_atomic_write(const struct xfs_inode *ip)
360360
{
361+
if (IS_DAX(VFS_IC(ip)))
362+
return false;
363+
361364
return xfs_inode_buftarg(ip)->bt_awu_max > 0;
362365
}
363366

367+
static inline bool xfs_inode_can_sw_atomic_write(const struct xfs_inode *ip)
368+
{
369+
if (IS_DAX(VFS_IC(ip)))
370+
return false;
371+
372+
return xfs_can_sw_atomic_write(ip->i_mount);
373+
}
374+
364375
/*
365376
* In-core inode flags.
366377
*/

fs/xfs/xfs_iops.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,8 @@ xfs_get_atomic_write_min(
616616
* write of exactly one single fsblock if the bdev will make that
617617
* guarantee for us.
618618
*/
619-
if (xfs_inode_can_hw_atomic_write(ip) || xfs_can_sw_atomic_write(mp))
619+
if (xfs_inode_can_hw_atomic_write(ip) ||
620+
xfs_inode_can_sw_atomic_write(ip))
620621
return mp->m_sb.sb_blocksize;
621622

622623
return 0;
@@ -633,7 +634,7 @@ xfs_get_atomic_write_max(
633634
* write of exactly one single fsblock if the bdev will make that
634635
* guarantee for us.
635636
*/
636-
if (!xfs_can_sw_atomic_write(mp)) {
637+
if (!xfs_inode_can_sw_atomic_write(ip)) {
637638
if (xfs_inode_can_hw_atomic_write(ip))
638639
return mp->m_sb.sb_blocksize;
639640
return 0;

0 commit comments

Comments
 (0)