Inode Structure in EXT4 filesystem

Inode:-

An inode is a data structure on a filesystem on Linux and other Unix-like operating systems that store all the information about a file except its name and its actual data.

A filesystem is the hierarchy of directories that is used to organize files on a computer.

When a file is created, both the file names and their corresponding inode numbers are stored as entries in the directory that appears to the user to contain the files. That is the directory associates file names with inodes.

An inode number, which is an integer that is unique within the filesystem.

The operating system obtains a file’s inode number and information in the inode through the use of the system call named stat.

Inode Layout:-

 

 

inode

 

Ext4:-

Partition:

  • Reserved boot block,
  • Collection of equally sized block groups

An ext4 file system is split into a series of block groups. To reduce performance difficulties due to fragmentation, the block allocator tries very hard to keep each file’s blocks within the same group.

Ext4

The default block size of 4KiB, each group will contain 32,768 blocks, for a length of 128MiB. The number of block groups is the size of the device divided by the size of a block group.

i.e The number of block groups = (the size of the device / the size of a block group)

Group 0 Layout:

Group 0 Padding ext4 Super Block Group Descriptors Reserved GDT Blocks Data Block Bitmap inode Bitmap inode Table Data Blocks
1024 bytes 1 block many blocks many blocks 1 block 1 block many blocks many more blocks
  • For the special case of block group 0, the first 1024 bytes are unused, to allow for the installation of x86 boot sectors and other oddities.
  • The ext4 driver primarily works with the “SuperBlock” and the “Group Descriptors” that are found in block group 0.
  • Redundant copies of the superblock and group descriptors are written to some of the block groups across the disk in case the beginning of the disk gets trashed. Redundant copies of the superblock and group descriptors are kept only in the groups whose group number is either 0 or a power of 3, 5, or 7.
  • When the filesystem is freshly formatted, mkfs will allocate “Reserve GDT Block” space after the block group descriptors and before the start of the block bitmaps to allow for future expansion of the filesystem.
  • If the group does not have a redundant copy, the block group begins with the data block bitmap.

Super Block:

  • The superblock records various information about the enclosing filesystem, such as block counts, inode counts, supported features, maintenance information and more.

Group Descriptor:

  • The group descriptor records the location of both bitmaps and the inode table
  • Counter for free blocks and inodes in this group
  • Number of directories in the group

Block Bitmap:

  • Since each bitmap is limited to a single block, this means that the maximum Number of blocks per group is 8 times the size of a block.

Max. No of Blocks Per Group = (8 * size of a Block)

Inode Bitmap:

  • The “Inode Bitmap” works in a similar way as the “Block Bitmap“, the difference being in each bit representing an inode in the “Inode Table” rather than a block.

Example:

Group 0: (Blocks 0-16383) [ITABLE_ZEROED]

Checksum 0x64bf, unused inodes 5364

Primary superblock at 0, Group descriptors at 1-975

Reserved GDT blocks at 976-1487

Block bitmap at 1488 (+1488), Inode bitmap at 1504 (+1504)

Inode table at 1520-2191 (+1520)

4102 free blocks, 5364 free inodes, 2 directories, 5364 unused inodes

Free blocks: 12282-16383

Free inodes: 13-5376

Group 1: (Blocks 16384-32767) [INODE_UNINIT, ITABLE_ZEROED]

Checksum 0xb040, unused inodes 5376

Backup superblock at 16384, Group descriptors at 16385-17359

Reserved GDT blocks at 17360-17871

Block bitmap at 1489 (+4294952401), Inode bitmap at 1505 (+4294952417)

Inode table at 2192-2863 (+4294953104)

560 free blocks, 5376 free inodes, 0 directories, 5376 unused inodes

Free blocks: 17872-18431

Free inodes: 5377-10752

Group 2: (Blocks 32768-49151) [INODE_UNINIT, ITABLE_ZEROED]

Checksum 0x597f, unused inodes 5376

Block bitmap at 1490 (+4294936018), Inode bitmap at 1506 (+4294936034)

Inode table at 2864-3535 (+4294937392)

0 free blocks, 5376 free inodes, 0 directories, 5376 unused inodes

Free blocks:

Free inodes: 10753-16128

Group 3: (Blocks 49152-65535) [INODE_UNINIT, ITABLE_ZEROED]

Checksum 0x54a1, unused inodes 5376

Backup superblock at 49152, Group descriptors at 49153-50127

Reserved GDT blocks at 50128-50639

Block bitmap at 1491 (+4294919635), Inode bitmap at 1507 (+4294919651)

Inode table at 3536-4207 (+4294921680)

560 free blocks, 5376 free inodes, 0 directories, 5376 unused inodes

Free blocks: 50640-51199

Free inodes: 16129-21504

Maximum File Size:

Sample calculation of maximum file size

  • Assume that there are 12 direct pointers to data blocks, 1 indirect pointer, 1 double indirect pointer, and 1 triple indirect pointer
  • Assume that the size of the data blocks is 2048 bytes = 2kB, i.e., BlockSize = 2kB
  • Assume that the block numbers are represented as 4-byte unsigned integers, i.e., BlockNumberSize = 4B
  • Maximum number of bytes addressed by 12 direct pointers is

= Number of direct pointers * Blocksize

= 12 * 2kB

= 24kB

  • Maximum number of bytes addressed by single indirect pointer is

= NumberOfEntries * BlockSize

= (Blocksize / BlockNumberSize) * BlockSize

= (2kB / 4B) * 2kB

= 512 * 2kB

= 1024kB·

  • Maximum number of bytes addressed by double indirect pointer is                                                                 = NumberOfEntries^2 * BlockSize

= 512^2 * 2kB

= 524288kB·

  • Maximum number of bytes addressed by triple indirect pointer is

= NumberOfEntries^3 * BlockSize

= 512^3 * 2kB

= 268435456kB·

  • Maximum file size is

= 268435456kB + 524288kB + 1024kB + 24kB

= 268960792kB

So if you use a block size as 2kB, the maximum file size is around 256 GB.

File System Maximums:-

inode size

Some useful Commands:

1. To find the block and inode size of file system at /dev/sda5:

# tune2fs -l /dev/sda5

2. Print the index number of the file

# ls -i /etc/passwd

3. Print file info on inode table

# stat /etc/passwd

4. To find more information about Group of blocks

# dumpe2fs /dev/sda5

Calculation of inode count:

  • Find Total Block Size for your partition:

[root@localhost ~]# cat /proc/partitions | grep sdb1 | awk ‘{print $3}’

2043938816

  • Block count                                          = <Total Block Size> / <Size of Block (KB)>
  • Max No. Blocks per Block Group     = 8 * <Size of Block (bytes)>
  • Size of block group                              = <No. Blocks per Block Group> * <Size of Block (KB)>
  • No. of Block Groups                            = <Block Count> / <No. Blocks per Block Group>
  • Group Descriptor Blocks                   = No. of Block Groups / 64

Consider Super Block is 1 Block

Block Bitmap is 1 Block

Inode Bitmap is 1 Block

Reserved GDT Block is 512 Blocks

  • Free Blocks per Block Group            = <No. Blocks per Block Group> – (1+1+1+512+< Group Descriptor Blocks>)
  • Inode count per Block                        = <Size of Block (byte)> / 256
  • Inode count per group                       = (< Free Blocks per Block Group> / 9) * 8
  • Total Inode count                               = <Inode Count Per Group> * < No. of Block Groups>

Sample calculation to find inode count for particular partition:

  • Find Total Block Size for your partition:

[root@localhost ~]# cat /proc/partitions | grep sdb1 | awk ‘{print $3}’

2043938816

  • Assume that Block size is 2kB
  • Block count                                         = 2043938816 / 2
    = 1021969408
  • Max No. Blocks per Block Group  = 8 * 2048
    = 16384
  • Size of Block group                            = 16384 * 2
    = 32768
  • No. of Block Groups                          = 1021969408 / 16384
    = 62376

Find inode per Group:

  • Assume the sparse_super feature flag is not set, redundant copies are kept in all groups.
  • So consider that Super Block is 1 block
  • Assume that Block Bitmap is 1 block
  • Assume that Inode Bitmap is 1 block
  • Assume that Reserved GDT Block is 512 blocks
  • Group Descriptor                         = No. of groups / 64

= 62376 / 64

= 974 blocks

  • Free Blocks per Block Group      = 16,384 – (1 + 1 + 1 + 512 + 974)

= 16,384 – 1489

= 14895 blocks

  • Inode count per Block                 = 2048 / 256
    = 8
  • Inode count per Group               = ( 14895 / 9 ) * 8
    = 13240
  • Inode table per Group                = 13240 / 8
    = 1655 blocks
  • Free data blocks                          = 14895 – 1655
    = 13240 blocks
  • The ratio of inode:data              = 13240:13240

Note: The ratio is not same all the cases. But it should be nearest one.

  • Total Inode count                        = Inode per Group * No. of Group

= 13240 * 62376

= 825858240

Finally, we can use inode count as 825858240 for 2043938816 block size partition.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s