On Mon, Aug 25, 2025 at 01:15:00PM +0200, Christoph Hellwig wrote: > Use the direct I/O alignment reporting from ->getattr instead of > reimplementing it. This exposes the relaxation of the memory > alignment in the XFS_IOC_DIOINFO info and ensure the information will > stay in sync. Note that randholes.c in xfstests has a bug where it > incorrectly fails when the required memory alignment is smaller than the > pointer size. Round up the reported value as there is a fair chance that > this code got copied into various applications. > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> > --- > > Changes since v1: > - update the comment > > fs/xfs/xfs_ioctl.c | 18 +++++++++--------- > 1 file changed, 9 insertions(+), 9 deletions(-) > > diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c > index e1051a530a50..ff0a8dc74948 100644 > --- a/fs/xfs/xfs_ioctl.c > +++ b/fs/xfs/xfs_ioctl.c > @@ -1209,21 +1209,21 @@ xfs_file_ioctl( > current->comm); > return -ENOTTY; > case XFS_IOC_DIOINFO: { > - struct xfs_buftarg *target = xfs_inode_buftarg(ip); > + struct kstat st; > struct dioattr da; > > - da.d_mem = target->bt_logical_sectorsize; > + error = vfs_getattr(&filp->f_path, &st, STATX_DIOALIGN, 0); > + if (error) > + return error; > > /* > - * See xfs_report_dioalign() for an explanation about why this > - * reports a value larger than the sector size for COW inodes. > + * Some userspace directly feeds the return value to > + * posix_memalign, which fails for values that are smaller than > + * the pointer size. Round up the value to not break userspace. Looks ok, don't care much if you say "userspace" or "userspace programs". Reviewed-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> > */ > - if (xfs_is_cow_inode(ip)) > - da.d_miniosz = xfs_inode_alloc_unitsize(ip); > - else > - da.d_miniosz = target->bt_logical_sectorsize; > + da.d_mem = roundup(st.dio_mem_align, sizeof(void *)); ...though one thing I /do/ wonder is whether this roundup() should be in the vfs statx code? Do people need to be able to initiate directio with buffers that are not aligned even to pointer size? --D > + da.d_miniosz = st.dio_offset_align; > da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); > - > if (copy_to_user(arg, &da, sizeof(da))) > return -EFAULT; > return 0; > -- > 2.47.2 > >