dcavalca / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone
05ad79
diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.c
05ad79
--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak	2015-06-24 12:58:20.790115492 +0200
05ad79
+++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c	2015-06-24 12:57:57.961286166 +0200
05ad79
@@ -49,6 +49,8 @@
05ad79
  *
05ad79
  * @UUID_SUB: subvolume uuid (e.g. btrfs)
05ad79
  *
05ad79
+ * @LOGUUID: external log UUID (e.g. xfs)
05ad79
+ *
05ad79
  * @UUID_RAW: raw UUID from FS superblock
05ad79
  *
05ad79
  * @EXT_JOURNAL: external journal UUID
05ad79
@@ -113,6 +115,7 @@ static const struct blkid_idinfo *idinfo
05ad79
 	&swsuspend_idinfo,
05ad79
 	&swap_idinfo,
05ad79
 	&xfs_idinfo,
05ad79
+	&xfs_log_idinfo,
05ad79
 	&ext4dev_idinfo,
05ad79
 	&ext4_idinfo,
05ad79
 	&ext3_idinfo,
05ad79
diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.h.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.h
05ad79
--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.h.kzak	2015-06-24 12:58:48.533908071 +0200
05ad79
+++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.h	2015-06-24 12:59:00.098821476 +0200
05ad79
@@ -29,6 +29,7 @@ extern const struct blkid_idinfo ext2_id
05ad79
 extern const struct blkid_idinfo jbd_idinfo;
05ad79
 extern const struct blkid_idinfo jfs_idinfo;
05ad79
 extern const struct blkid_idinfo xfs_idinfo;
05ad79
+extern const struct blkid_idinfo xfs_log_idinfo;
05ad79
 extern const struct blkid_idinfo gfs_idinfo;
05ad79
 extern const struct blkid_idinfo gfs2_idinfo;
05ad79
 extern const struct blkid_idinfo romfs_idinfo;
05ad79
diff -up util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak util-linux-2.23.2/libblkid/src/superblocks/xfs.c
05ad79
--- util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak	2015-06-24 12:39:34.300507071 +0200
05ad79
+++ util-linux-2.23.2/libblkid/src/superblocks/xfs.c	2015-06-24 12:39:45.389427015 +0200
05ad79
@@ -4,6 +4,7 @@
05ad79
  * Copyright (C) 2001 by Andreas Dilger
05ad79
  * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
05ad79
  * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
05ad79
+ * Copyright (C) 2013 Eric Sandeen <sandeen@redhat.com>
05ad79
  *
05ad79
  * This file may be redistributed under the terms of the
05ad79
  * GNU Lesser General Public License.
05ad79
@@ -187,3 +188,90 @@ const struct blkid_idinfo xfs_idinfo =
05ad79
 	}
05ad79
 };
05ad79
 
05ad79
+struct xlog_rec_header {
05ad79
+	uint32_t	h_magicno;
05ad79
+	uint32_t	h_dummy1[1];
05ad79
+	uint32_t	h_version;
05ad79
+	uint32_t	h_len;
05ad79
+	uint32_t	h_dummy2[71];
05ad79
+	uint32_t	h_fmt;
05ad79
+	unsigned char	h_uuid[16];
05ad79
+} __attribute__((packed));
05ad79
+
05ad79
+#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe
05ad79
+
05ad79
+/*
05ad79
+ * For very small filesystems, the minimum log size
05ad79
+ * can be smaller, but that seems vanishingly unlikely
05ad79
+ * when used with an external log (which is used for
05ad79
+ * performance reasons; tiny conflicts with that goal).
05ad79
+ */
05ad79
+#define XFS_MIN_LOG_BYTES	(10 * 1024 * 1024)
05ad79
+
05ad79
+#define XLOG_FMT_LINUX_LE	1
05ad79
+#define XLOG_FMT_LINUX_BE	2
05ad79
+#define XLOG_FMT_IRIX_BE	3
05ad79
+
05ad79
+#define XLOG_VERSION_1		1
05ad79
+#define XLOG_VERSION_2		2	/* Large IClogs, Log sunit */
05ad79
+#define XLOG_VERSION_OKBITS	(XLOG_VERSION_1 | XLOG_VERSION_2)
05ad79
+
05ad79
+static int xlog_valid_rec_header(struct xlog_rec_header *rhead)
05ad79
+{
05ad79
+	uint32_t hlen;
05ad79
+
05ad79
+	if (rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
05ad79
+		return 0;
05ad79
+
05ad79
+	if (!rhead->h_version ||
05ad79
+            (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS)))
05ad79
+		return 0;
05ad79
+
05ad79
+	/* LR body must have data or it wouldn't have been written */
05ad79
+	hlen = be32_to_cpu(rhead->h_len);
05ad79
+	if (hlen <= 0 || hlen > INT_MAX)
05ad79
+		return 0;
05ad79
+
05ad79
+	if (rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_LE) &&
05ad79
+	    rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_BE) &&
05ad79
+	    rhead->h_fmt != cpu_to_be32(XLOG_FMT_IRIX_BE))
05ad79
+		return 0;
05ad79
+
05ad79
+	return 1;
05ad79
+}
05ad79
+
05ad79
+/* xlog record header will be in some sector in the first 256k */
05ad79
+static int probe_xfs_log(blkid_probe pr, const struct blkid_idmag *mag)
05ad79
+{
05ad79
+	int i;
05ad79
+	struct xlog_rec_header *rhead;
05ad79
+	unsigned char *buf;
05ad79
+
05ad79
+	buf = blkid_probe_get_buffer(pr, 0, 256*1024);
05ad79
+	if (!buf)
05ad79
+		return errno ? -errno : 1;
05ad79
+
05ad79
+	if (memcmp(buf, "XFSB", 4) == 0)
05ad79
+		return 1;			/* this is regular XFS, ignore */
05ad79
+
05ad79
+	/* check the first 512 512-byte sectors */
05ad79
+	for (i = 0; i < 512; i++) {
05ad79
+		rhead = (struct xlog_rec_header *)&buf[i*512];
05ad79
+
05ad79
+		if (xlog_valid_rec_header(rhead)) {
05ad79
+			blkid_probe_set_uuid_as(pr, rhead->h_uuid, "LOGUUID");
05ad79
+			return 0;
05ad79
+		}
05ad79
+	}
05ad79
+
05ad79
+	return 1;
05ad79
+}
05ad79
+
05ad79
+const struct blkid_idinfo xfs_log_idinfo =
05ad79
+{
05ad79
+	.name		= "xfs_external_log",
05ad79
+	.usage		= BLKID_USAGE_OTHER,
05ad79
+	.probefunc	= probe_xfs_log,
05ad79
+	.magics		= BLKID_NONE_MAGIC,
05ad79
+	.minsz		= XFS_MIN_LOG_BYTES,
05ad79
+};