Skip to content

Commit 0ea88ed

Browse files
johnpgarryDarrick J. Wong
authored andcommitted
xfs: refine atomic write size check in xfs_file_write_iter()
Currently the size of atomic write allowed is fixed at the blocksize. To start to lift this restriction, partly refactor xfs_report_atomic_write() to into helpers - xfs_get_atomic_write_{min, max}() - and use those helpers to find the per-inode atomic write limits and check according to that. Also add xfs_get_atomic_write_max_opt() to return the optimal limit, and just return 0 since large atomics aren't supported yet. Reviewed-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]> Signed-off-by: John Garry <[email protected]>
1 parent 514df14 commit 0ea88ed

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

fs/xfs/xfs_file.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,14 +1032,12 @@ xfs_file_write_iter(
10321032
return xfs_file_dax_write(iocb, from);
10331033

10341034
if (iocb->ki_flags & IOCB_ATOMIC) {
1035-
/*
1036-
* Currently only atomic writing of a single FS block is
1037-
* supported. It would be possible to atomic write smaller than
1038-
* a FS block, but there is no requirement to support this.
1039-
* Note that iomap also does not support this yet.
1040-
*/
1041-
if (ocount != ip->i_mount->m_sb.sb_blocksize)
1035+
if (ocount < xfs_get_atomic_write_min(ip))
10421036
return -EINVAL;
1037+
1038+
if (ocount > xfs_get_atomic_write_max(ip))
1039+
return -EINVAL;
1040+
10431041
ret = generic_atomic_write_valid(iocb, from);
10441042
if (ret)
10451043
return ret;

fs/xfs/xfs_iops.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -601,16 +601,42 @@ xfs_report_dioalign(
601601
stat->dio_offset_align = stat->dio_read_offset_align;
602602
}
603603

604+
unsigned int
605+
xfs_get_atomic_write_min(
606+
struct xfs_inode *ip)
607+
{
608+
if (!xfs_inode_can_hw_atomic_write(ip))
609+
return 0;
610+
611+
return ip->i_mount->m_sb.sb_blocksize;
612+
}
613+
614+
unsigned int
615+
xfs_get_atomic_write_max(
616+
struct xfs_inode *ip)
617+
{
618+
if (!xfs_inode_can_hw_atomic_write(ip))
619+
return 0;
620+
621+
return ip->i_mount->m_sb.sb_blocksize;
622+
}
623+
624+
unsigned int
625+
xfs_get_atomic_write_max_opt(
626+
struct xfs_inode *ip)
627+
{
628+
return 0;
629+
}
630+
604631
static void
605632
xfs_report_atomic_write(
606633
struct xfs_inode *ip,
607634
struct kstat *stat)
608635
{
609-
unsigned int unit_min = 0, unit_max = 0;
610-
611-
if (xfs_inode_can_hw_atomic_write(ip))
612-
unit_min = unit_max = ip->i_mount->m_sb.sb_blocksize;
613-
generic_fill_statx_atomic_writes(stat, unit_min, unit_max, 0);
636+
generic_fill_statx_atomic_writes(stat,
637+
xfs_get_atomic_write_min(ip),
638+
xfs_get_atomic_write_max(ip),
639+
xfs_get_atomic_write_max_opt(ip));
614640
}
615641

616642
STATIC int

fs/xfs/xfs_iops.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,8 @@ int xfs_inode_init_security(struct inode *inode, struct inode *dir,
1919
extern void xfs_setup_inode(struct xfs_inode *ip);
2020
extern void xfs_setup_iops(struct xfs_inode *ip);
2121
extern void xfs_diflags_to_iflags(struct xfs_inode *ip, bool init);
22+
unsigned int xfs_get_atomic_write_min(struct xfs_inode *ip);
23+
unsigned int xfs_get_atomic_write_max(struct xfs_inode *ip);
24+
unsigned int xfs_get_atomic_write_max_opt(struct xfs_inode *ip);
2225

2326
#endif /* __XFS_IOPS_H__ */

0 commit comments

Comments
 (0)