-
Bug
-
Resolution: Won't Do
-
Undefined
-
None
-
rhel-7.9.z
-
None
-
None
-
None
-
rhel-sst-filesystems
-
ssg_filesystems_storage_and_HA
-
None
-
False
-
-
None
-
Red Hat Enterprise Linux
-
None
-
None
-
None
-
-
s390x
-
None
What were you trying to do that didn't work?
While trying to create a filesystem on a file, located on an ext4 filesystem, with a required alignment of 4 KiB, mkfs.xfs fails to read/write due to performing O_DIRECT IO using a 512-byte aligned buffer.
Please provide the package NVR for which bug is seen:
xfsprogs 4.5.0-22.el7.s390x
How reproducible:
always on customer's s390x system; unclear on other systems
Steps to reproduce
on device requiring 4 KiB alignment:
- create ext4 filesystem
- mount ext4 filesystem (mount /dev/... /mnt)
- try to create xfs filesystem on a file on the ext4 filesystem
if the ext4 filesystem is itself a file on a filesystem, the 4 KiB alignment requirement may be forced when calling losetup:
- losetup -b 4096 --find --show foo.ext4
/dev/loop4
however, it's unclear how to cause the memalign() to align to just 512 bytes; it tends to also be aligned to 4 KiB (at least on x86_64)
Expected results
mkfs.xfs creates filesystem
Actual results
existing superblock re__memalign_hookad failed: Invalid argument
mkfs.xfs: pwrite64 failed: Invalid argument
the problem is in platform_findsizes() when creating the filesystem on a file:
if ((st.st_mode & S_IFMT) == S_IFREG) { struct dioattr da; *sz = (long long)(st.st_size >> 9); if (ioctl(fd, XFS_IOC_DIOINFO, &da) < 0) { /* * fall back to BBSIZE; mkfs might fail if there's a * size mismatch between the image & the host fs... */ *bsz = BBSIZE; } else *bsz = da.d_miniosz; if (*bsz > max_block_alignment) max_block_alignment = *bsz; return; }
the ioctl fails on any non-xfs filesystem, so bsz is set to BBSIZE, which is 512 bytes. In this case, the required alignment is 4096, so 512 bytes isn't sufficient. Strace confirms that the buffer address is only aligned to 512 bytes:
1570 14:08:46.808737 pread64(16</var/lib/leapp/scratch/diskimages/root_>, 0x8ee49a00, 512, 0) = -1 EINVAL (Invalid argument) <0.000002>
$ printf %x\\n $((0x8ee49a00 & 4095)) a00 $ printf %x\\n $((0x8ee49a00 & 511)) 0 $ printf %x\\n $((0x8ee49a00 & 1023)) 200
in this case, the /var device is dm-3:
$ cat sos_commands/block/blockdev_--report RO RA SSZ BSZ StartSec Size Device rw 1024 4096 4096 0 23796449280 /dev/dasda ... rw 8192 4096 4096 0 10712252416 /dev/dm-3