After looking at the code for various utilities and the kernel code for some time, it does seem that what @Hauke suggested is true - whether a filesystem is
ext4 is purely defined by the options that are enabled.
From the Wikipedia page on
ext4 is backward compatible with ext3 and ext2, making it possible to mount ext3 and ext2 as ext4. This will slightly improve performance, because certain new features of ext4 can also be used with ext3 and ext2, such as the new block allocation algorithm.
ext3 is partially forward compatible with ext4. That is, ext4 can be mounted as ext3 (using "ext3" as the filesystem type when mounting). However, if the ext4 partition uses extents (a major new feature of ext4), then the ability to mount as ext3 is lost.
As most probably already know, there is similar compatibility between
After looking at the code which
blkid uses to distinguish different
ext filesystems, I was able to turn an
ext4 filesystem into something recognised as
ext3 (and from there to
ext2). You should be able to repeat this with:
truncate -s 100M testfs
mkfs.ext4 -O ^64bit,^extent,^flex_bg testfs <<<y
tune2fs -O ^huge_file,^dir_nlink,^extra_isize,^mmp testfs
tune2fs -O metadata_csum testfs
tune2fs -O ^metadata_csum testfs
./e2fsprogs/misc/tune2fs -O ^has_journal testfs
blkid output is:
testfs: UUID="78f4475b-060a-445c-a5d2-0f45688cc954" SEC_TYPE="ext2" TYPE="ext4"
testfs: UUID="78f4475b-060a-445c-a5d2-0f45688cc954" SEC_TYPE="ext2" TYPE="ext3"
And the final one:
testfs: UUID="78f4475b-060a-445c-a5d2-0f45688cc954" TYPE="ext2"
Note that I had to use a new version of
e2fsprogs than was available in my distro to get the
metadata_csum flag. The reason for setting, then clearing this was because I found no other way to affect the underlying
EXT4_FEATURE_RO_COMPAT_GDT_CSUM flag. The underlying flag for
EXT4_FEATURE_RO_COMPAT_GDT_CSUM are mutually exclusive. Setting
EXT4_FEATURE_RO_COMPAT_GDT_CSUM, but un-setting
metadata_csum does not re-enable the latter.
Lacking a deep knowledge of the filesystem internals, it seems either:
Journal checksumming is meant to be a defining feature of a filesystem created as
ext4 that you are really not supposed to disable and that fact that I have managed this is really a bug in
ext4 features were always designed to be disabled and disabling them does make the filesystem to all intents an purposes an
Either way a high level of compatibility between the filesystems is clearly a design goal, compare this to ReiserFS and Reiser4 where Reiser4 is a complete redesign. What really matters is whether the features present are supported by the driver that is used to mount the system. As the Wikipedia article notes the
ext4 driver can be used with
ext2 as well (in fact there is a kernel option to always use the
ext4 driver and ditch the others). Disabling features just means that the earlier drivers will have no problems with the filesystem and so there are no reasons to stop them from mounting the filesystem.
To distinguish between the different
ext filesystems in a C program,
libblkid seems to be the best thing to use. It is part of
util-linux and this is what the
mount command uses to try to determine the filesystem type. API documentation is here.
If you have to do your own implementation of the check, then testing the same flags as
libblkid seems to be the right way to go. Although notably the file linked has no mention of the
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM flag which appears to be tested in practice.
If you really wanted to go the whole hog, then looking at for journal checksums might be a surefire way of finding if a filesystem without these flags is (or perhaps was)
It is actually somewhat easier to go in the opposite direction and promote an
ext2 filesystem to
truncate -s 100M test
tune2fs -O has_journal test
tune2fs -O huge_file test
test: UUID="59dce6f5-96ed-4307-9b39-6da2ff73cb04" TYPE="ext2"
test: UUID="59dce6f5-96ed-4307-9b39-6da2ff73cb04" SEC_TYPE="ext2" TYPE="ext3"
test: UUID="59dce6f5-96ed-4307-9b39-6da2ff73cb04" SEC_TYPE="ext2" TYPE="ext4"
The fact that
ext4 features can so easily by enabled on a filesystem that started out as
ext2 is probably the best demonstration that the filesystem type really is defined by the features.