Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-17657

mkfs.xfs fails if creating filesystem on file on non-xfs filesystem, with required alignment larger than 512 bytes

    • Icon: Bug Bug
    • Resolution: Won't Do
    • Icon: Undefined Undefined
    • None
    • rhel-7.9.z
    • xfsprogs
    • None
    • None
    • None
    • sst_filesystems
    • ssg_filesystems_storage_and_HA
    • None
    • False
    • Hide

      None

      Show
      None
    • 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:

      1. create ext4 filesystem
      2. mount ext4 filesystem (mount /dev/... /mnt)
      3. 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:

      1. 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

            bodonnel Bill O'Donnell
            rhn-support-fsorenso Frank Sorenson
            Bill O'Donnell Bill O'Donnell
            Murphy Zhou Murphy Zhou
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: