I need to detect a filesystem type from a C/C++ program using the filesystem superblock. However, I don't see much differences between superblocks for ext2 and ext4. The s_rev_level
field is the same (=1), the s_minor_rev_level
is the same (=0).
I could check some features from s_feature_compat
(and other feature fields) and try to locate features, which aren't supported by ext2. But – the person, formatting a partition, could disable some features on purpose. So, this method can detect the ext4, but it can't distinguish between the ext2 and the ext4 with disabled ext4-specific features.
So, how to do that?
Best Answer
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
ext2
/ext3
/ext4
is purely defined by the options that are enabled.From the Wikipedia page on
ext4
:As most probably already know, there is similar compatibility between
ext2
andext3
.After looking at the code which
blkid
uses to distinguish differentext
filesystems, I was able to turn anext4
filesystem into something recognised asext3
(and from there toext2
). You should be able to repeat this with:First
blkid
output is:Second is:
And the final one:
Note that I had to use a new version of
e2fsprogs
than was available in my distro to get themetadata_csum
flag. The reason for setting, then clearing this was because I found no other way to affect the underlyingEXT4_FEATURE_RO_COMPAT_GDT_CSUM
flag. The underlying flag formetadata_csum
(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
) andEXT4_FEATURE_RO_COMPAT_GDT_CSUM
are mutually exclusive. Settingmetadata_csum
disablesEXT4_FEATURE_RO_COMPAT_GDT_CSUM
, but un-settingmetadata_csum
does not re-enable the latter.Conclusions
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 ine2fsprogs
. Or,All
ext4
features were always designed to be disabled and disabling them does make the filesystem to all intents an purposes anext3
filesystem.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 withext3
andext2
as well (in fact there is a kernel option to always use theext4
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.Recommendations
To distinguish between the different
ext
filesystems in a C program,libblkid
seems to be the best thing to use. It is part ofutil-linux
and this is what themount
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 theEXT4_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)
ext4
.Update
It is actually somewhat easier to go in the opposite direction and promote an
ext2
filesystem toext4
:The three
blkid
ouputs:The fact that
ext3
/ext4
features can so easily by enabled on a filesystem that started out asext2
is probably the best demonstration that the filesystem type really is defined by the features.