Skip to content

Commit 6432c6e

Browse files
johnpgarryDarrick J. Wong
authored andcommitted
xfs: Support atomic write for statx
Support providing info on atomic write unit min and max for an inode. For simplicity, currently we limit the min at the FS block size. As for max, we limit also at FS block size, as there is no current method to guarantee extent alignment or granularity for regular files. Reviewed-by: "Darrick J. Wong" <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: John Garry <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 9e0933c commit 6432c6e

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

fs/xfs/xfs_buf.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,6 +2115,13 @@ xfs_alloc_buftarg(
21152115
btp->bt_daxdev = fs_dax_get_by_bdev(btp->bt_bdev, &btp->bt_dax_part_off,
21162116
mp, ops);
21172117

2118+
if (bdev_can_atomic_write(btp->bt_bdev)) {
2119+
btp->bt_bdev_awu_min = bdev_atomic_write_unit_min_bytes(
2120+
btp->bt_bdev);
2121+
btp->bt_bdev_awu_max = bdev_atomic_write_unit_max_bytes(
2122+
btp->bt_bdev);
2123+
}
2124+
21182125
/*
21192126
* When allocating the buftargs we have not yet read the super block and
21202127
* thus don't know the file system sector size yet.

fs/xfs/xfs_buf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ struct xfs_buftarg {
124124
struct percpu_counter bt_io_count;
125125
struct ratelimit_state bt_ioerror_rl;
126126

127+
/* Atomic write unit values */
128+
unsigned int bt_bdev_awu_min;
129+
unsigned int bt_bdev_awu_max;
130+
127131
/* built-in cache, if we're not using the perag one */
128132
struct xfs_buf_cache bt_cache[];
129133
};

fs/xfs/xfs_inode.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,21 @@ static inline bool xfs_inode_has_bigrtalloc(struct xfs_inode *ip)
327327
(XFS_IS_REALTIME_INODE(ip) ? \
328328
(ip)->i_mount->m_rtdev_targp : (ip)->i_mount->m_ddev_targp)
329329

330+
static inline bool
331+
xfs_inode_can_atomicwrite(
332+
struct xfs_inode *ip)
333+
{
334+
struct xfs_mount *mp = ip->i_mount;
335+
struct xfs_buftarg *target = xfs_inode_buftarg(ip);
336+
337+
if (mp->m_sb.sb_blocksize < target->bt_bdev_awu_min)
338+
return false;
339+
if (mp->m_sb.sb_blocksize > target->bt_bdev_awu_max)
340+
return false;
341+
342+
return true;
343+
}
344+
330345
/*
331346
* In-core inode flags.
332347
*/

fs/xfs/xfs_iops.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,20 @@ xfs_stat_blksize(
570570
return max_t(uint32_t, PAGE_SIZE, mp->m_sb.sb_blocksize);
571571
}
572572

573+
static void
574+
xfs_get_atomic_write_attr(
575+
struct xfs_inode *ip,
576+
unsigned int *unit_min,
577+
unsigned int *unit_max)
578+
{
579+
if (!xfs_inode_can_atomicwrite(ip)) {
580+
*unit_min = *unit_max = 0;
581+
return;
582+
}
583+
584+
*unit_min = *unit_max = ip->i_mount->m_sb.sb_blocksize;
585+
}
586+
573587
STATIC int
574588
xfs_vn_getattr(
575589
struct mnt_idmap *idmap,
@@ -643,6 +657,14 @@ xfs_vn_getattr(
643657
stat->dio_mem_align = bdev_dma_alignment(bdev) + 1;
644658
stat->dio_offset_align = bdev_logical_block_size(bdev);
645659
}
660+
if (request_mask & STATX_WRITE_ATOMIC) {
661+
unsigned int unit_min, unit_max;
662+
663+
xfs_get_atomic_write_attr(ip, &unit_min,
664+
&unit_max);
665+
generic_fill_statx_atomic_writes(stat,
666+
unit_min, unit_max);
667+
}
646668
fallthrough;
647669
default:
648670
stat->blksize = xfs_stat_blksize(ip);

0 commit comments

Comments
 (0)