Ext2 is the most common filesystem for not journaling partitions (partitions that don't change much) like the boot partition. Ext3/4 are journaling and are used usually for the rest partitions.
All block groups in the filesystem have the same size and are stored sequentially. This allows the kernel to easily derive the location of a block group in a disk from its integer index.
Every block group contains the following pieces of information:
A copy of the filesystem’s superblock
A copy of the block group descriptors
A data block bitmap which is used to identify the free blocks inside the group
An inode bitmap, which is used to identify the free inodes inside the group
inode table: it consists of a series of consecutive blocks, each of which contains a predefined Figure 1 Ext2 inode number of inodes. All inodes have the same size: 128 bytes. A 1,024 byte block contains 8 inodes, while a 4,096-byte block contains 32 inodes. Note that in Ext2, there is no need to store on disk a mapping between an inode number and the corresponding block number because the latter value can be derived from the block group number and the relative position inside the inode table. For example, suppose that each block group contains 4,096 inodes and that we want to know the address on disk of inode 13,021. In this case, the inode belongs to the third block group and its disk address is stored in the 733rd entry of the corresponding inode table. As you can see, the inode number is just a key used by the Ext2 routines to retrieve the proper inode descriptor on disk quickly
data blocks, containing files. Any block which does not contain any meaningful information, it is said to be free.
Features affect where the data is located, how the data is stored in inodes and some of them might supply additional metadata for analysis, therefore features are important in Ext.
Ext has optional features that your OS may or may not support, there are 3 possibilities:
Compatible Read Only: It can be mounted but not for writing
If there are incompatible features you won't be able to mount the filesystem as the OS won't know how the access the data.
Any utility that reads the superblock will be able to indicate the features of a Ext filesystem, but you could also use
file -sL /dev/sd*
The superblock is the first 1024 bytes from the start, it's repeated in the first block of each group and contains:
Blocks per block group
Reserved blocks before the first block group
Inodes per block group
Last write time
Last mount time
Path where the file system was last mounted
Filesystem status (clean?)
It's possible to obtain this information from an Ext filesystem file using:
fsstat -o <offsetstart> /pat/to/filesystem-file.ext#You can get the <offsetstart> with the "p" command inside fdisk
The inodes contain the list of blocks that contains the actual data of a file. If the file is big, and inode may contain pointers to other inodes that points to the blocks/more inodes containing the file data.
In Ext2 and Ext3 inodes are of size 128B, Ext4 currently uses 156B but allocates 256B on disk to allow a future expansion.
File mode and type
Lower 16 bits of owner ID
Lower 32 bits of file size
Access time in seconds since epoch
Change time in seconds since epoch
Modify time in seconds since epoch
Delete time in seconds since epoch
Lower 16 bits of group ID
Hard link count
Lower 32 bits of block count
Linux: I version
15 pointes to data block
File version for NFS
File ACL low
Lower 32 bits of extended attributes (ACL, etc)
File size hi
Upper 32 bits of file size (ext4 only)
An obsoleted fragment address
Second operating system dependent union
Upper 16 bits of block count
File ACL hi
Upper 16 bits of extended attributes (ACL, etc.)
Upper 16 bits of owner ID
Upper 16 bits of group ID
Lower 16 bits of inode checksum
"Modify" is the timestamp of the last time the file's content has been mofified. This is often called "mtime". "Change" is the timestamp of the last time the file's inode has been changed, like by changing permissions, ownership, file name, number of hard links. It's often called "ctime".
Inode structure extended (Ext4):
How many bytes beyond standard 128 are used
Upper 16 bits of inode checksum
Change time extra bits
Modify time extra bits
Access time extra bits
File create time (seconds since epoch)
File create time extra bits
Upper 32 bits of version
Reserved space for future expansions
No such inode, numberings starts at 1
Defective block list
Reserved group descriptors (for resizing filesystem)
Exclude inode (for snapshots)
First non-reserved inode (often lost + found)
Knowing the inode number you can easily find it's index:
Block group where an inode belongs: (Inode number - 1) / (Inodes per group)
Index inside it's group: (Inode number - 1) mod(Inodes/groups)
Offset into inode table: Inode number * (Inode size)
The "-1" is because the inode 0 is undefined (not used)
ls -ali /bin | sort -n #Get all inode numbers and sort by themstat /bin/ls #Get the inode information of a fileistat -o <start offset> /path/to/image.ext 657103 #Get information of that inode inside the given ext fileicat -o <start offset> /path/to/image.ext 657103 #Cat the file
Directory/Block Bit 13
Char Device/Block Bit 14
Sticky Bit (without it, anyone with Write & exec perms on a directory can delete and rename files)
The bold bits (12, 13, 14, 15) indicate the type of file the file is (a directory, socket...) only one of the options in bold may exit.
0x00 Unknown 0x01 Regular
0x03 Char device
0x04 Block device
0x07 Sym link
Name string (up to 255 characters)
In order to increase the performance, Root hash Directory blocks may be used.
Can be stored in
Extra space between inodes (256 - inode size, usually = 100)
A data block pointed to by file_acl in inode
Can be used to store anything as a users attribute if name starts with "user".
Data can ne hidden this way.
Extended Attributes Entries
Length of attribute name
0x0 = no prefix
0x1 = user. Prefix
0x2 = system.posix_acl_access
0x3 = system.posix_acl_default
0x4 = trusted.
0x6 = security.
0x7 = system.
0x8 = system.richacl
Offset from first inode entry or start of block
Disk block where value stored or zero for this block
Length of value
Hash for attribs in block or zero if in inode
Attribute name w/o trailing NULL
setfattr -n 'user.secret' -v 'This is a secret' file.txt #Save a secret using extended attributesgetfattr file.txt #Get extended attribute names of a filegetdattr -n 'user.secret' file.txt #Get extended attribute called "user.secret"
In order to see the contents of the file system you can use the free tool: https://www.disk-editor.org/index.html
Or you can mount it in your linux using