Skip to contentSkip to conversation

teach libblkid about ext4(dev)

PATCH In review Eric Sandeen 2 participants 3 messages Jan 22, 2008 – Jan 27, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 teach libblkid about ext4(dev)

Returns ext4dev for now; will need to change to ext4 at the appropriate time I guess.

---

Index: e2fsprogs-1.40.4/lib/blkid/probe.c

===================================================================

lib/blkid/probe.c +33 -0
@@ -148,6 +148,38 @@ static void get_ext2_info(blkid_dev dev,
 	set_uuid(dev, es->s_uuid, 0);
 }
 
+static int probe_ext4(struct blkid_probe *probe,
+		      struct blkid_magic *id __BLKID_ATTR((unused)),
+		      unsigned char *buf)
+{
+	struct ext2_super_block *es;
+	es = (struct ext2_super_block *)buf;
+
+	/* Distinguish between jbd and ext2/3/4 fs */
+	if (blkid_le32(es->s_feature_incompat) &
+	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
+		return -BLKID_ERR_PARAM;
+
+	/* Distinguish between ext3/4 and ext2 */
+	if (!(blkid_le32(es->s_feature_compat) &
+	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
+		return -BLKID_ERR_PARAM;
+
+	/* Distinguish between ext4 and ext3 */
+	if (!(blkid_le32(es->s_feature_ro_compat) &
+	      EXT4_FEATURES_RO_COMPAT) &&
+	    !(blkid_le32(es->s_feature_incompat) &
+	      EXT4_FEATURES_INCOMPAT))
+		return -BLKID_ERR_PARAM;
+
+	get_ext2_info(probe->dev, buf);
+
+	if ((es->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+	    !uuid_is_null(es->s_journal_uuid))
+		set_uuid(probe->dev, es->s_journal_uuid, "EXT_JOURNAL");
+
+	return 0;
+}
 static int probe_ext3(struct blkid_probe *probe, 
 		      struct blkid_magic *id __BLKID_ATTR((unused)), 
 		      unsigned char *buf)
@@ -833,6 +865,7 @@ static struct blkid_magic type_array[] =
   { "oracleasm", 0,	32,  8, "ORCLDISK",		probe_oracleasm },
   { "ntfs",	 0,	 3,  8, "NTFS    ",		probe_ntfs },
   { "jbd",	 1,   0x38,  2, "\123\357",		probe_jbd },
+  { "ext4dev",	 1,   0x38,  2, "\123\357",		probe_ext4 },
   { "ext3",	 1,   0x38,  2, "\123\357",		probe_ext3 },
   { "ext2",	 1,   0x38,  2, "\123\357",		probe_ext2 },
   { "reiserfs",	 8,   0x34,  8, "ReIsErFs",		probe_reiserfs },
lib/blkid/probe.h +20 -0
Index: e2fsprogs-1.40.4/lib/blkid/probe.h
===================================================================
@@ -88,6 +88,26 @@ struct ext2_super_block {
 #define EXT3_FEATURE_INCOMPAT_RECOVER		0x00000004
 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x00000008
 
+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE	0x0008
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM		0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK	0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE	0x0040
+
+#define EXT4_FEATURE_INCOMPAT_EXTENTS		0x0040 /* extents support */
+#define EXT4_FEATURE_INCOMPAT_64BIT		0x0080
+#define EXT4_FEATURE_INCOMPAT_MMP		0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
+
+#define EXT4_FEATURES_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_HUGE_FILE| \
+				 EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
+				 EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
+				 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
+
+#define EXT4_FEATURES_INCOMPAT	(EXT4_FEATURE_INCOMPAT_EXTENTS| \
+				 EXT4_FEATURE_INCOMPAT_64BIT| \
+				 EXT4_FEATURE_INCOMPAT_MMP| \
+				 EXT4_FEATURE_INCOMPAT_FLEX_BG)
+
 struct xfs_super_block {
 	unsigned char	xs_magic[4];
 	__u32		xs_blocksize;
#1 lore raw
Quoted 4 lines · Eric Sandeen

Returns ext4dev for now; will need to change to ext4 at the appropriate time I guess.

Hmm... see my test_fs patch. If we decide that this is a good way to go, then we can use the presence of that flag to cause blkid to return "ext4dev", and absence of that flag for blkid to return "ext4".

When we rename the kernel filesystem type from ext4dev to ext4, we also take out the requirement for EXT2_FLAGS_TEST_FILESYS, and simply tell people to remove that flag from their ext4 filesytems. Blkid will then do the right thing without requiring us to synchronize updating the kernel as well as e2fsprogs at the same time.

What do people think? I think it's a pretty elegant solution.

- Ted

#2 lore raw
In reply to Eric Sandeen
Quoted 2 lines · Eric Sandeen

Returns ext4dev for now; will need to change to ext4 at the appropriate time I guess.

This is what I ultimately ended up committing.

- Ted

commit 2921332fd88b843ffb828d9c18f05bfd171ace76

Author: Theodore Ts'o <[email protected]>
Date:   Sat Jan 26 22:25:50 2008 -0500

Teach the blkid library about ext4/ext4dev

lib/blkid/probe.c +86 -21
index 32d9f3f..f7bb491 100644
@@ -131,7 +131,8 @@ static void set_uuid(blkid_dev dev, uuid_t uuid, char *tag)
 	}
 }
 
-static void get_ext2_info(blkid_dev dev, unsigned char *buf)
+static void get_ext2_info(blkid_dev dev, struct blkid_magic *id,
+			  unsigned char *buf)
 {
 	struct ext2_super_block *es = (struct ext2_super_block *) buf;
 	const char *label = 0;
@@ -146,61 +147,123 @@ static void get_ext2_info(blkid_dev dev, unsigned char *buf)
 	blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name));
 
 	set_uuid(dev, es->s_uuid, 0);
+
+	if ((es->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+	    !uuid_is_null(es->s_journal_uuid))
+		set_uuid(dev, es->s_journal_uuid, "EXT_JOURNAL");
+
+	if (strcmp(id->bim_type, "ext2") &&
+	    ((blkid_le32(es->s_feature_incompat) &
+	      EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0))
+		blkid_set_tag(dev, "SEC_TYPE", "ext2", sizeof("ext2"));
 }
 
-static int probe_ext3(struct blkid_probe *probe, 
-		      struct blkid_magic *id __BLKID_ATTR((unused)), 
+static int probe_ext4dev(struct blkid_probe *probe,
+			 struct blkid_magic *id,
+			 unsigned char *buf)
+{
+	struct ext2_super_block *es;
+	es = (struct ext2_super_block *)buf;
+
+	/* Distinguish between ext4dev and other filesystems */
+	if ((blkid_le32(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) == 0)
+		return -BLKID_ERR_PARAM;
+
+	/* Distinguish from jbd */
+	if (blkid_le32(es->s_feature_incompat) &
+	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
+		return -BLKID_ERR_PARAM;
+
+	/* ext4dev requires a journal */
+	if (!(blkid_le32(es->s_feature_compat) &
+	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
+		return -BLKID_ERR_PARAM;
+
+    	get_ext2_info(probe->dev, id, buf);
+	return 0;
+}
+
+static int probe_ext4(struct blkid_probe *probe, struct blkid_magic *id,
 		      unsigned char *buf)
 {
 	struct ext2_super_block *es;
 	es = (struct ext2_super_block *)buf;
 
-	/* Distinguish between jbd and ext2/3 fs */
+	/* Distinguish from ext4dev */
+	if (blkid_le32(es->s_flags) & EXT2_FLAGS_TEST_FILESYS)
+		return -BLKID_ERR_PARAM;
+
+	/* Distinguish from jbd */
 	if (blkid_le32(es->s_feature_incompat) & 
 	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
 		return -BLKID_ERR_PARAM;
 
-	/* Distinguish between ext3 and ext2 */
+	/* ext4 requires journal */
 	if (!(blkid_le32(es->s_feature_compat) &
 	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
 		return -BLKID_ERR_PARAM;
 
-	get_ext2_info(probe->dev, buf);
+	/* Ext4 has at least one feature which ext3 doesn't understand */
+	if (!(blkid_le32(es->s_feature_ro_compat) &
+	      EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) &&
+	    !(blkid_le32(es->s_feature_incompat) &
+	      EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
+		return -BLKID_ERR_PARAM;
 
-	if ((es->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
-	    !uuid_is_null(es->s_journal_uuid))
-		set_uuid(probe->dev, es->s_journal_uuid, "EXT_JOURNAL");
+    	get_ext2_info(probe->dev, id, buf);
+	return 0;
+}
+
+static int probe_ext3(struct blkid_probe *probe, struct blkid_magic *id,
+		      unsigned char *buf)
+{
+	struct ext2_super_block *es;
+	es = (struct ext2_super_block *)buf;
+
+	/* Distinguish from ext4dev */
+	if (blkid_le32(es->s_flags) & EXT2_FLAGS_TEST_FILESYS)
+		return -BLKID_ERR_PARAM;
 
-	blkid_set_tag(probe->dev, "SEC_TYPE", "ext2", sizeof("ext2"));
+	/* ext3 requires journal */
+	if (!(blkid_le32(es->s_feature_compat) &
+	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
+		return -BLKID_ERR_PARAM;
 
+	/* Any features which ext3 doesn't understand */
+	if ((blkid_le32(es->s_feature_ro_compat) &
+	     EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) ||
+	    (blkid_le32(es->s_feature_incompat) &
+	     EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
+		return -BLKID_ERR_PARAM;
+
+    	get_ext2_info(probe->dev, id, buf);
 	return 0;
 }
 
-static int probe_ext2(struct blkid_probe *probe,
-		      struct blkid_magic *id __BLKID_ATTR((unused)), 
+static int probe_ext2(struct blkid_probe *probe, struct blkid_magic *id,
 		      unsigned char *buf)
 {
 	struct ext2_super_block *es;
 
 	es = (struct ext2_super_block *)buf;
 
-	/* Distinguish between jbd and ext2/3 fs */
-	if (blkid_le32(es->s_feature_incompat) & 
-	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
-		return -BLKID_ERR_PARAM;
-	
 	/* Distinguish between ext3 and ext2 */
 	if ((blkid_le32(es->s_feature_compat) &
 	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
 		return -BLKID_ERR_PARAM;
 
-	get_ext2_info(probe->dev, buf);
+	/* Any features which ext2 doesn't understand */
+	if ((blkid_le32(es->s_feature_ro_compat) &
+	     EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) ||
+	    (blkid_le32(es->s_feature_incompat) &
+	     EXT2_FEATURE_INCOMPAT_UNSUPPORTED))
+		return -BLKID_ERR_PARAM;
 
+	get_ext2_info(probe->dev, id, buf);
 	return 0;
 }
 
-static int probe_jbd(struct blkid_probe *probe,
-		     struct blkid_magic *id __BLKID_ATTR((unused)), 
+static int probe_jbd(struct blkid_probe *probe, struct blkid_magic *id,
 		     unsigned char *buf)
 {
 	struct ext2_super_block *es = (struct ext2_super_block *) buf;
@@ -209,7 +272,7 @@ static int probe_jbd(struct blkid_probe *probe,
 	      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
 		return -BLKID_ERR_PARAM;
 
-	get_ext2_info(probe->dev, buf);
+	get_ext2_info(probe->dev, id, buf);
 
 	return 0;
 }
@@ -833,6 +896,8 @@ static struct blkid_magic type_array[] = {
   { "oracleasm", 0,	32,  8, "ORCLDISK",		probe_oracleasm },
   { "ntfs",	 0,	 3,  8, "NTFS    ",		probe_ntfs },
   { "jbd",	 1,   0x38,  2, "\123\357",		probe_jbd },
+  { "ext4dev",	 1,   0x38,  2, "\123\357",		probe_ext4dev },
+  { "ext4",	 1,   0x38,  2, "\123\357",		probe_ext4 },
   { "ext3",	 1,   0x38,  2, "\123\357",		probe_ext3 },
   { "ext2",	 1,   0x38,  2, "\123\357",		probe_ext2 },
   { "reiserfs",	 8,   0x34,  8, "ReIsErFs",		probe_reiserfs },
lib/blkid/probe.h +54 -4

65 lines not on this page · raw message