diff options
| author | Christoph Hellwig <hch@lst.de> | 2025-08-25 13:15:00 +0200 |
|---|---|---|
| committer | Carlos Maiolino <cem@kernel.org> | 2025-08-28 14:20:03 +0200 |
| commit | 851c4c96db001f51bdad1432aa54549c7fe2c63e (patch) | |
| tree | d8541886a2ebfbd3dac827019da96594ea17fee4 | |
| parent | 0239bd9fa445a21def88f7e76fe6e0414b2a4da0 (diff) | |
| download | linux-851c4c96db001f51bdad1432aa54549c7fe2c63e.tar.gz linux-851c4c96db001f51bdad1432aa54549c7fe2c63e.zip | |
xfs: implement XFS_IOC_DIOINFO in terms of vfs_getattr
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@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
| -rw-r--r-- | fs/xfs/xfs_ioctl.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 10a3a5160f4e..a6bb7ee7a27a 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1203,21 +1203,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. */ - 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 *)); + 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; |
