]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
mkfs: don't zero old superblocks if file was truncated
authorBrian Foster <bfoster@redhat.com>
Tue, 7 Apr 2015 00:04:11 +0000 (10:04 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 7 Apr 2015 00:04:11 +0000 (10:04 +1000)
If the force overwrite option is passed to mkfs, we attempt to zero old
superblock metadata on the mkfs target. We attempt to read the primary
superblock to identify the secondary superblocks.

If the mkfs target is a regular file, it is truncated on open and the
secondary superblock zeroing operation returns a spurious and incorrect
error message due to a 0-byte read:

$ mkfs.xfs -f -d file=1,name=xfs.fs,size=32m
...
existing superblock read failed: Inappropriate ioctl for device

Fix the error reporting in zero_old_xfs_structures() to only print an
error string if the pread() call returns an error. Warn the user if the
read doesn't match the sector size. Finally, detect the case where we
know we've already truncated a regular file and skip the sb zeroing.

Reported-by: Alexander Tsvetkov <alexander.tsvetkov@oracle.com>
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
mkfs/xfs_mkfs.c

index 484e7a858431f3dd10d7558c2ddc72fd6857164e..5084d7555f8cf959572830172e35677b8ec2f6b4 100644 (file)
@@ -817,6 +817,13 @@ zero_old_xfs_structures(
        __uint32_t              bsize;
        int                     i;
        xfs_off_t               off;
+       int                     tmp;
+
+       /*
+        * We open regular files with O_TRUNC|O_CREAT. Nothing to do here...
+        */
+       if (xi->disfile && xi->dcreat)
+               return;
 
        /*
         * read in existing filesystem superblock, use its geometry
@@ -830,11 +837,16 @@ zero_old_xfs_structures(
        }
        memset(buf, 0, new_sb->sb_sectsize);
 
-       if (pread(xi->dfd, buf, new_sb->sb_sectsize, 0) != new_sb->sb_sectsize) {
+       tmp = pread(xi->dfd, buf, new_sb->sb_sectsize, 0);
+       if (tmp < 0) {
                fprintf(stderr, _("existing superblock read failed: %s\n"),
                        strerror(errno));
-               free(buf);
-               return;
+               goto done;
+       }
+       if (tmp != new_sb->sb_sectsize) {
+               fprintf(stderr,
+       _("warning: could not read existing superblock, skip zeroing\n"));
+               goto done;
        }
        libxfs_sb_from_disk(&sb, buf);