[PATCH] xfs_mkfs: wipe old signatures from the device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We should wipe off all the signatures from the device prior the file
system creation. It is because because some file systems (btrfs) may
still have their signatures on the device which can be confusing for
userspace possibly resulting in the unmountable file system.

This patch adds a function which uses libblkid library to wipe all the
signatures from the device.

If user disables libblkid library or does not have it installed this new
feature will not be used. This case can be implemented separately.

Signed-off-by: Lukas Czerner <lczerner@xxxxxxxxxx>
---
 mkfs/xfs_mkfs.c |  134 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 97 insertions(+), 37 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index d636549..a889620 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -286,18 +286,73 @@ calc_stripe_factors(
 }
 
 #ifdef ENABLE_BLKID
+static int
+wipe_signatures(
+	char		*device,
+	int		dryrun)
+{
+	blkid_probe	pr = NULL;
+	int		ret = 0;
+	int		fd;
+
+	pr = blkid_new_probe_from_filename(device);
+	if (!pr)
+		goto out;
+
+	fd = open(device, O_RDWR|O_CLOEXEC);
+	if (fd < 0) {
+		ret = -1;
+		goto out;
+	}
+	ret = blkid_probe_set_device(pr, fd, 0, 0);
+	if (ret)
+		goto out;
+
+	/* No need to check return values we know that 'pr' is initialized */
+	blkid_probe_enable_partitions(pr, 1);
+	blkid_probe_enable_superblocks(pr, 1);
+	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
+	blkid_probe_set_superblocks_flags(pr,
+					BLKID_SUBLKS_MAGIC | BLKID_SUBLKS_TYPE);
+
+	while (1) {
+		ret = blkid_do_probe(pr);
+		if (ret != 0)
+			break;
+
+		/* Wipe off the signature */
+		ret = blkid_do_wipe(pr, dryrun);
+		if (ret)
+			break;
+	}
+	close(fd);
+
+out:
+	if (pr)
+		blkid_free_probe(pr);
+	if (ret < 0)
+		fprintf(stderr,
+			_("%s: Cannot wipe off existing signatures\n"), progname);
+	return (ret < 0 ? ret : 0);
+}
+
 /*
  * Check for existing filesystem or partition table on device.
  * Returns:
  *	 1 for existing fs or partition
  *	 0 for nothing found
  *	-1 for internal error
+ * If wipe is set, we'll attempt to wipe of all the signatures from
+ * the device. In this case we never return 1 (existing fs or partition).
  */
 static int
 check_overwrite(
-	char		*device)
+	char		*device,
+	int		wipe,
+	int		dryrun)
 {
 	const char	*type;
+	const char	*name;
 	blkid_probe	pr = NULL;
 	int		ret;
 	int		fd;
@@ -325,40 +380,43 @@ check_overwrite(
 	if (!pr)
 		goto out;
 
-	ret = blkid_probe_enable_partitions(pr, 1);
-	if (ret < 0)
-		goto out;
+	/* No need to check return values we know that 'pr' is initialized */
+	blkid_probe_enable_partitions(pr, 1);
+	blkid_probe_enable_superblocks(pr, 1);
+	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
+	blkid_probe_set_superblocks_flags(pr,
+					BLKID_SUBLKS_MAGIC | BLKID_SUBLKS_TYPE);
 
-	ret = blkid_do_fullprobe(pr);
-	if (ret < 0)
-		goto out;
+	ret = 0;
+	while (1) {
+		int retval = 0;
 
-	/*
-	 * Blkid returns 1 for nothing found and 0 when it finds a signature,
-	 * but we want the exact opposite, so reverse the return value here.
-	 *
-	 * In addition print some useful diagnostics about what actually is
-	 * on the device.
-	 */
-	if (ret) {
-		ret = 0;
-		goto out;
-	}
+		retval = blkid_do_probe(pr);
+		if (retval != 0) {
+			ret = retval;
+			break;
+		}
 
-	if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
-		fprintf(stderr,
-			_("%s: %s appears to contain an existing "
-			"filesystem (%s).\n"), progname, device, type);
-	} else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
-		fprintf(stderr,
-			_("%s: %s appears to contain a partition "
-			"table (%s).\n"), progname, device, type);
-	} else {
-		fprintf(stderr,
-			_("%s: %s appears to contain something weird "
-			"according to blkid\n"), progname, device);
+		if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) == 0)
+			name = "filesystem";
+
+		else if (blkid_probe_lookup_value(pr, "PTTYPE",
+						    &type, NULL) == 0)
+			name = "partition table";
+		else
+			continue;
+
+		if (wipe)
+			fprintf(stderr, _("%s: Wiping off %s signature.\n"),
+				progname, type);
+		else {
+			fprintf(stderr,
+				_("%s: %s appears to contain an existing "
+				"%s (%s).\n"), progname, device, name, type);
+			ret = 1;
+			continue;
+		}
 	}
-	ret = 1;
 
 out:
 	if (pr)
@@ -367,6 +425,8 @@ out:
 		fprintf(stderr,
 			_("%s: probe of %s failed, cannot detect "
 			  "existing filesystem.\n"), progname, device);
+	if (ret == 1 && wipe)
+		ret = wipe_signatures(device, dryrun);
 	return ret;
 }
 
@@ -464,7 +524,8 @@ static void get_topology(
 #else /* ENABLE_BLKID */
 static int
 check_overwrite(
-	char		*device)
+	char		*device,
+	int		wipe)
 {
 	char		*type;
 
@@ -1939,16 +2000,15 @@ _("block size %d cannot be smaller than logical sector size %d\n"),
 	xi.rtsize &= sector_mask;
 	xi.logBBsize &= (__uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT);
 
-	if (!force_overwrite) {
-		if (check_overwrite(dfile) ||
-		    check_overwrite(logfile) ||
-		    check_overwrite(xi.rtname)) {
+	if (check_overwrite(dfile, force_overwrite, Nflag) ||
+	    check_overwrite(logfile, force_overwrite, Nflag) ||
+	    check_overwrite(xi.rtname, force_overwrite, Nflag))
+		if (force_overwrite) {
 			fprintf(stderr,
 			_("%s: Use the -f option to force overwrite.\n"),
 				progname);
 			exit(1);
 		}
-	}
 
 	if (discard) {
 		discard_blocks(xi.ddev, xi.dsize);
-- 
1.7.7.6

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs


[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux