<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>devbypen</title>
      <link>https://www.devbypen.com</link>
      <description>this is a4 ide of devbypen</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://www.devbypen.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Mon, 27 Apr 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>All thing you need to know about ext4 filesystem</title>
          <pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate>
          <author>devbypen</author>
          <link>https://www.devbypen.com/blog/first-blog/</link>
          <guid>https://www.devbypen.com/blog/first-blog/</guid>
          <description xml:base="https://www.devbypen.com/blog/first-blog/">&lt;p&gt;As software engineers, we interact with files constantly. Understanding how
filesystems actually work under the hood is extremely useful for unlocking the
full potential and power of this awesome weapon.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;But why is Ext4 ?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Currently, Linux filesystem is used Ext4 as standard, and i work much with Linux. In many ways, Ext4 is a
deeper improvement over Ext3, than Ext3 was over Ext2. Morever, I mainly worked
with Linux so that is what I care about. Also, I recommend that we should know
about many filesystem in Window, MacOs, &lt;em&gt;etc...&lt;&#x2F;em&gt; to compare and analyze props and cons, understand
best implement in scenerio but this article place Ext4 first.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;So what problem with Ext2 and Ext3 ?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ext2: Data corrpution Nightmare&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Ext2  is short for Linux&#x27;s second extended filesystem&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ext2 is incredibly fast and lightweight,
but data is not &lt;strong&gt;durable&lt;&#x2F;strong&gt;, if a system lost power or crashed while writing data
to an ext2 disk, the filesystem was left in an inconsistent state. Upon rebooting,
the system had to run filesystem check &lt;code&gt;fsck&lt;&#x2F;code&gt; across the entire drive to find and
fix orphaned files or currupted blocks,as the result, we will lost unmounted data&lt;&#x2F;p&gt;
&lt;p&gt;That lead to new problem that as hard drives grew rapidly to gigabytes, this &lt;code&gt;fsck&lt;&#x2F;code&gt;
process maybe taking hours.&lt;&#x2F;p&gt;
&lt;p&gt;=&amp;gt; So &lt;strong&gt;Ext3&lt;&#x2F;strong&gt; fix this problem, just adding &lt;strong&gt;journaling&lt;&#x2F;strong&gt; feature into &lt;strong&gt;Ext2&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Basiclly, the journal kept a log of what the filesystem was about to do. If the
power failed, the system just looked at the journal upon reboot, finished the
imcomplete tasks and skipped the hours-long &lt;code&gt;fsck&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ext2 is incredibly fast, lightweight, how Linux archive that in practice ?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;Ext2&lt;&#x2F;strong&gt; file system id divided into &lt;em&gt;block groups&lt;&#x2F;em&gt;, but how many block
groups will be created ?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[ Ext2 file system ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+------------+---------------+---------------+-------+---------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Boot Block | Block Group 0 | Block Group 1 |  ...  | Block Group N |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+------------+---------------+---------------+-------+---------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; (~ 1KB)        |               |                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                v               v                       v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             +-------------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             |            Each Block Group&amp;#39;s Architecture            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             +------------+------------+--------+--------+-----+-----+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             | Superblock | Group      | Block  | Inode  |Inode|Data |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             |   (Copy)   | Descriptor | Bitmap | Bitmap |Table|Blks |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             +------------+------------+--------+--------+-----+-----+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To know quantity of &lt;code&gt;block groups&lt;&#x2F;code&gt;, we should know total &lt;code&gt;block_count&lt;&#x2F;code&gt; and
&lt;code&gt;block_per_group&lt;&#x2F;code&gt;, as the result &lt;code&gt;block_groups = block_count &#x2F; block_per_group&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Firstly, we need to know &lt;code&gt;block_count&lt;&#x2F;code&gt;, which means we need to know there are &lt;em&gt;xxxx&lt;&#x2F;em&gt;
blocks this disk. With default, size of one block &lt;em&gt;(the lowest level of file
computer deal with)&lt;&#x2F;em&gt; is 4096 Bytes, to caculate &lt;code&gt;block count&lt;&#x2F;code&gt;, we do simple math
with total disk space divide 4096 Bytes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e.g: At the partition &#x2F;dev&#x2F;sdb3, we have 1,000,000 Bytes disk space, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;by default (if you don&amp;#39;t change the setting), one block is 4096 Bytes &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;=&amp;gt; block_count = 1,000,000 &#x2F; 4096 = 244 blocks (+ 566 Bytes) &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But How is the +566 Bytes part in the example part is handle?&lt;&#x2F;p&gt;
&lt;p&gt;In theory, &lt;strong&gt;Block&lt;&#x2F;strong&gt; is the smallest division in file system, so file system
will skip that part and pretend it is no exist, but it rarely happend in reality
because &lt;code&gt;LBS - Logical Block Size&lt;&#x2F;code&gt; and &lt;code&gt;Partition Alignment&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Physical disk divide their data into Block called Sector (LBS). Which is 4096
Bytes, so the size of all partition is multiple of Sector size&lt;&#x2F;p&gt;
&lt;p&gt;Mordern tool like &lt;code&gt;fdisk&lt;&#x2F;code&gt; and &lt;code&gt;gparted&lt;&#x2F;code&gt; create partition, usually have &lt;code&gt;1 MiB Alignment&lt;&#x2F;code&gt; rule. Which means the start and the end of a partion always rounded
to multiple of 1 Megabyte (1,048,576 bytes). Because 1 MiB &#x2F; 4096 Bytes = 256 (blocks)&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, we need to deal with &lt;code&gt;block_per_group&lt;&#x2F;code&gt;, which means we need to know
there are &lt;em&gt;xxxx&lt;&#x2F;em&gt; blocks in one group. With default, this number is &lt;strong&gt;32768&lt;&#x2F;strong&gt; blocks,
to understand better, we should look at &lt;code&gt;block_bitmap&lt;&#x2F;code&gt;, which means a special block,
handle available information about other block in one &lt;code&gt;block_group&lt;&#x2F;code&gt;. Size of 1 block
is 4096 Bytes, each bytes have 8 bits, so total is 4096 * 8 = 32768 (bits). It means
there are 32768 bits in 1 block (with default setting), and in the special block: &lt;code&gt;block_bitmap&lt;&#x2F;code&gt;,
each bit show information about block (0 is unused, 1 is used).&lt;&#x2F;p&gt;
&lt;p&gt;After we know all of these thing, we can answer how many Block Groups in disk.
We can simple check use &lt;code&gt;tune2fs&lt;&#x2F;code&gt; in Linux&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;remember replace &#x2F;dev&#x2F;sdb3 with your path&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;sudo tune2fs -l &#x2F;dev&#x2F;sdb3 | grep -iE &quot;block size|blocks per group|block count&quot;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;information.webp&quot; &#x2F;&gt;
&lt;p&gt;Now, we look into each block group architecture, which is Superblock (copy version),
group description, block bitmap (we introduce earlier), inode bitmap, inode table,
data Blks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;SuperBlock&lt;&#x2F;strong&gt; is like guilde map for kernal to know what is the type of file system,
how many block in that pertition, size of a block, state of partition, for any reason
if you lose data of super block, the kernel can not mount your partition, and flag
that pertion with raw data, which means your data will still there but kernel
can not read because it don&#x27;t know how to read. In the scenerio, you need
&lt;strong&gt;Data Recovery Tools&lt;&#x2F;strong&gt; to raw carve each byte in disk to recover data.&lt;&#x2F;p&gt;
&lt;p&gt;At the early version of ext2, the copy of superblock appear at every block groups
because it is very important, but as size of disk increase, each partition can have
many block groups, and all of that have a copy of super block is waste resource.
With that problem, new feature called &lt;code&gt;sparse_super&lt;&#x2F;code&gt; is added to ext2, when this
feature turn on (default always turn on), super block will be saved in Block 0,
and backup in Block 1, and all block that is power of 3, 5 or 7. That save a lot
of space and still make sure safety.&lt;&#x2F;p&gt;
&lt;p&gt;To understand better about &lt;strong&gt;SuperBlock&lt;&#x2F;strong&gt; we go through its architecture. The
&lt;strong&gt;SuperBlock&lt;&#x2F;strong&gt; is always located at byte offset 1024 from beginning of the file,
block device or partition formated with Ext2.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Offset (bytes) | Size (bytes) | Description                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 0              | 4            | s_inodes_count                              |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 4              | 4            | s_blocks_count                              |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 8              | 4            | s_r_blocks_count                            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 12             | 4            | s_free_blocks_count                         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 16             | 4            | s_free_inodes_count                         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 20             | 4            | s_first_data_block                          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 24             | 4            | s_log_block_size                            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 28             | 4            | s_log_frag_size                             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 32             | 4            | s_blocks_per_group                          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 36             | 4            | s_frags_per_group                           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 40             | 4            | s_inodes_per_group                          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 44             | 4            | s_mtime                                     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 48             | 4            | s_wtime                                     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 52             | 2            | s_mnt_count                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 54             | 2            | s_max_mnt_count                             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 56             | 2            | s_magic                                     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 58             | 2            | s_state                                     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 60             | 2            | s_errors                                    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 62             | 2            | s_minor_rev_level                           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 64             | 4            | s_lastcheck                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 68             | 4            | s_checkinterval                             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 72             | 4            | s_creator_os                                |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 76             | 4            | s_rev_level                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 80             | 2            | s_def_resuid                                |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 82             | 2            | s_def_resgid                                |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|                     -- EXT2_DYNAMIC_REV Specific --                         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 84             | 4            | s_first_ino                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 88             | 2            | s_inode_size                                |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 90             | 2            | s_block_group_nr                            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 92             | 4            | s_feature_compat                            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 96             | 4            | s_feature_incompat                          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 100            | 4            | s_feature_ro_compat                         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 104            | 16           | s_uuid                                      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 120            | 16           | s_volume_name                               |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 136            | 64           | s_last_mounted                              |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 200            | 4            | s_algo_bitmap                               |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|                           -- Performance Hints --                           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 204            | 1            | s_prealloc_blocks                           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 205            | 1            | s_prealloc_dir_blocks                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 206            | 2            | (alignment)                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|                          -- Journaling Support --                           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 208            | 16           | s_journal_uuid                              |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 224            | 4            | s_journal_inum                              |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 228            | 4            | s_journal_dev                               |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 232            | 4            | s_last_orphan                               |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|                      -- Directory Indexing Support --                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 236            | 4 x 4        | s_hash_seed                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 252            | 1            | s_def_hash_version                          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 253            | 3            | padding - reserved for future expansion     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|                             -- Other options --                             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 256            | 4            | s_default_mount_options                     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 260            | 4            | s_first_meta_bg                             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 264            | 760          | Unused - reserved for future revisions      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----------------+--------------+---------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, we will look into &lt;strong&gt;group description&lt;&#x2F;strong&gt;, this is layout of it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OFFSET   SIZE         KERNEL VARIABLE          MEANING (MAIN FUNCTION)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 0 byte |  4 Bytes   | bg_block_bitmap        |  The block address of the Block Bitmap.         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 4 byte |  4 Bytes   | bg_inode_bitmap        |  The block address of the Inode Bitmap.         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 8 byte |  4 Bytes   | bg_inode_table         |  Starting block address of the Inode Table.     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 12 byte|  2 Bytes   | bg_free_blocks_count   | Number of free blocks currently in this group.  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 14 byte|  2 Bytes   | bg_free_inodes_count   | Number of free Inodes currently in this group.  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 16 byte|  2 Bytes   | bg_used_dirs_count     | Number of directories allocated in this group.  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 18 byte|  14 Bytes  | (Reserved &#x2F; Padding)   | Reserved bytes for future use.                  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--------+------------+------------------------+-------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;if the &lt;strong&gt;Super Block&lt;&#x2F;strong&gt; is general informations about block groups, then
&lt;strong&gt;group description&lt;&#x2F;strong&gt; is detail informations about 1 block, it contain informations
about block address of Block Bitmap, Inode Bitmap, Inode Table, or Number free
blocks, Inodes and number of directories.&lt;&#x2F;p&gt;
&lt;p&gt;Move on to &lt;strong&gt;Block bitmap&lt;&#x2F;strong&gt; (which we mentioned earlier), this is normally located at the first block, or
second block if a superblock backup is present. Its location can be determined
by reading the &quot;bg_block_bitmap&quot; in &lt;strong&gt;group description&lt;&#x2F;strong&gt;. Each bit is repersent
the current state of a block in that block group. Where 1 means used and 0 is free.&lt;&#x2F;p&gt;
&lt;p&gt;Similiar, &lt;strong&gt;Inode bitmap&lt;&#x2F;strong&gt; is used to represent current state of &lt;strong&gt;Inode&lt;&#x2F;strong&gt; in the
&lt;strong&gt;Inode table&lt;&#x2F;strong&gt;. In the original version of ext2 (revision 0), when &lt;strong&gt;Inode table&lt;&#x2F;strong&gt;
is crated, 11 first Inodes will be marked with used for system.&lt;&#x2F;p&gt;
&lt;p&gt;But what is &lt;strong&gt;Inode&lt;&#x2F;strong&gt; and &lt;strong&gt;Inode table&lt;&#x2F;strong&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Inode&lt;&#x2F;strong&gt; (Index Node) is where metadata of file is saved, which seperate with
data blocks (content of file). A file can be directory, a socket, a buffer,
character or block device, symbolic link or regular file. This is structure of &lt;strong&gt;Inode&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OFFSET     SIZE          FIELD NAME               MEANING (MAIN FUNCTION)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (Bytes)    (Bytes)       (In Kernel)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 0       |   2 Bytes    | i_mode                 | File type (regular, directory...) &amp;amp; Permissions.   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 2       |   2 Bytes    | i_uid                  | User ID of the file owner.                         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 4       |   4 Bytes    | i_size                 | Size of the file in bytes.                         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 8       |   4 Bytes    | i_atime                | Last access time (Access Time).                    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 12      |   4 Bytes    | i_ctime                | Inode change time (Change Time).                   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 16      |   4 Bytes    | i_mtime                | File content modification time (Modification Time).|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 20      |   4 Bytes    | i_dtime                | Time of file deletion (Deletion Time).             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 24      |   2 Bytes    | i_gid                  | Group ID of the file owner.                        |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 26      |   2 Bytes    | i_links_count          | Number of hard links pointing to this Inode.       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 28      |   4 Bytes    | i_blocks               | Total blocks (usually 512B sectors) allocated.     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 32      |   4 Bytes    | i_flags                | Special status flags of the file.                  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 36      |   4 Bytes    | i_osd1                 | Reserved for Operating System (OS Dependent 1).    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 40      |  60 Bytes    | i_block [15 x 4]       | CORE: Array of 15 pointers (4B each) pointing to   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|         |              |                        | the actual Data Blocks containing the file data.   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 100     |   4 Bytes    | i_generation           | File generation&#x2F;version (mainly for Network FS).   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 104     |   4 Bytes    | i_file_acl             | File ACL (Access Control List).                    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 108     |   4 Bytes    | i_dir_acl              | Dir ACL (For regular files, this is i_size_high    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|         |              |                        | to support file sizes &amp;gt; 4GB).                      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 112     |   4 Bytes    | i_faddr                | Fragment address (Rarely used&#x2F;Obsolete).           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 116     |  12 Bytes    | i_osd2                 | Reserved for Operating System (OS Dependent 2).    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                       [ TOTAL OF 128 BYTES ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The important we need to notice that &lt;code&gt;i_block&lt;&#x2F;code&gt; field have limit size of pointers
so to extend this, we need cascade hierrachy. There are 4 type of &lt;strong&gt;block_pointer&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Direct Block&lt;&#x2F;li&gt;
&lt;li&gt;Indirect Block&lt;&#x2F;li&gt;
&lt;li&gt;Double Indirect Block&lt;&#x2F;li&gt;
&lt;li&gt;Triple Indirect Block.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Regurlar, Each Inode have 12 direct pointers, 1 single indirect, 1 double indirect,
1 triple indirect. I can give you some number to help you know power of this archituecture.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Block_size = 4KB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 pointer = 4 Bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;=&amp;gt; 1 block cointains 1024 pointers (4096&#x2F;4)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Direct: 12 * 4KB = 48KB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Single Direct: 1024 * 4KB ~ 4MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Double Indirect: 1024 * 1024 * 4KB ~ 4GB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Triple Indirect: 1024 * 1024 * 1024 * 4KB ~ 4TB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With this, small file will have access time very fast, but big file will take
longer time but still available (trade off between Performance and Scalability)&lt;&#x2F;p&gt;
&lt;p&gt;So, the &lt;strong&gt;Inode Table&lt;&#x2F;strong&gt; is simply array of &lt;strong&gt;Inode&lt;&#x2F;strong&gt;, there is one &lt;strong&gt;Inode Table&lt;&#x2F;strong&gt;
per &lt;strong&gt;Block Group&lt;&#x2F;strong&gt; and it can be located by reading &lt;code&gt;bg_inode_table&lt;&#x2F;code&gt; in its
group description.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Wait... Why a &lt;strong&gt;directory, a socket, a buffer, character or block device, symbolic link&lt;&#x2F;strong&gt;
also called file?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is the most theory in Linux &quot;Everything is file&quot;. But those
are special file, and in filesystem, we care much more on &lt;strong&gt;directory&lt;&#x2F;strong&gt; and
&lt;strong&gt;symbolic link&lt;&#x2F;strong&gt; because &lt;strong&gt;socket&lt;&#x2F;strong&gt;, &lt;strong&gt;buffer&lt;&#x2F;strong&gt;, &lt;strong&gt;character or block device&lt;&#x2F;strong&gt;,
have no data on &lt;code&gt;Data_block&lt;&#x2F;code&gt;, the way handle it relate much more with kernel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Directory&lt;&#x2F;strong&gt; is like a contact books, when you want to call Devbypen, you search
his name and call the number. It&#x27;s &lt;code&gt;data_block&lt;&#x2F;code&gt; is informations of contact books.
In revision 0, directories could only be stored in a linked list. Revision 1
and later introduced indexed directory, which is backward compatible with linked
list directory.&lt;&#x2F;p&gt;
&lt;p&gt;This is linked list directories structure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OFFSET     SIZE          FIELD NAME               MEANING (MAIN FUNCTION)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 0       |   4 Bytes    | inode                  | Inode number of the file or subdirectory.          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 4       |   2 Bytes    | rec_len                | Directory entry length (must be a multiple of 4).  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 6       |   1 Byte     | name_len               | Length of the file name (maximum 255 characters).  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 7       |   1 Byte     | file_type              | File type indicator (e.g., 1=File, 2=Directory).   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 8       | 0-255 Bytes  | name                   | The actual file name characters.                   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+----------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using the standard linked list directory format can become very slow once the number
of file starts growing with O(N) when search file. To improve perfomance, a hashed
index was used with O(log N). This is its structure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OFFSET     SIZE          FIELD NAME               DESCRIPTION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (Bytes)    (Bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;=======================================================================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -- Linked Directory Entry: &amp;quot;.&amp;quot; (Current Directory) --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+-----------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 0       |   4 Bytes    | inode                  | Inode number of this directory.   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 4       |   2 Bytes    | rec_len                | Record length (12 bytes).         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 6       |   1 Byte     | name_len               | Length of the name (1).           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 7       |   1 Byte     | file_type              | File type (EXT2_FT_DIR = 2).      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 8       |   1 Byte     | name                   | The name string: &amp;quot;.&amp;quot;              |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 9       |   3 Bytes    | (padding)              | Padding to align to 4 bytes.      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+-----------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -- Linked Directory Entry: &amp;quot;..&amp;quot; (Parent Directory) --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+-----------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 12      |   4 Bytes    | inode                  | Inode number of parent directory. |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 16      |   2 Bytes    | rec_len                | Spans to the end of the block     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|         |              |                        | (e.g., 4084 for a 4KB blocksize). |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 18      |   1 Byte     | name_len               | Length of the name (2).           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 19      |   1 Byte     | file_type              | File type (EXT2_FT_DIR = 2).      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 20      |   2 Bytes    | name                   | The name string: &amp;quot;..&amp;quot;             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 22      |   2 Bytes    | (padding)              | Padding to align to 4 bytes.      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+-----------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -- Indexed Directory Root Information Structure (dx_root) --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+-----------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 24      |   4 Bytes    | reserved               | Reserved space (must be zero).    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 28      |   1 Byte     | hash_version           | Hash algorithm used (e.g. Half MD5) |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 29      |   1 Byte     | info_length            | Length of this info structure (8).|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 30      |   1 Byte     | indirect_levels        | Depth of the HTree (0 or 1).      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 31      |   1 Byte     | reserved               | Unused flags &#x2F; Reserved.          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---------+--------------+------------------------+-----------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We need to look at Parent Directory (..) 16 (2 Bytes) &lt;code&gt;rec_len&lt;&#x2F;code&gt;. To archive compatible with linked list,
Hashed Index Tree spans this value to 4084 (4084 + 12 (inode) = 4096) full Block
size, tricked old system that Others field do not exist, then treat them like normal.&lt;&#x2F;p&gt;
&lt;p&gt;Now move on &lt;strong&gt;symbolic link&lt;&#x2F;strong&gt; (also symlink or softlink) is a special file that
contains a reference to another file or directory in a form of an absolute or
relative path. For symlink have fewer 60 bytes, the data save at &lt;code&gt;i_block&lt;&#x2F;code&gt; field
inode itself. And this lead to extreme fast when we don&#x27;t need extra block data
to save link.&lt;&#x2F;p&gt;
&lt;p&gt;Ext2 is a beatiful design of filesystem which still the core of ext3&#x2F;ext4, next
we look into ext3 filesystem.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ext3 = Ext2 + Journaling&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;As we know, when you save a file in Ext2 file system, the kernel need to do many
things with disk in different postition:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Write Data Block (content of file)&lt;&#x2F;li&gt;
&lt;li&gt;Write Inode (metadata)&lt;&#x2F;li&gt;
&lt;li&gt;Write Block Bitmap and Inode Bitmap (marked unused or used)&lt;&#x2F;li&gt;
&lt;li&gt;Write Directory Entry (Add file to direcory)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For any reason, we can&#x27;t go through 4 step above, ext2&#x27;s structure will destroy,
and become inconsistency.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine you come to giant library, and you gave back the librian the Harry Potter
book. Without Journaling, the librian will go to the book shelf, put it in
position 5, and write to the book management app that book in postion 5. But
what happen when something occur when librian have not writen informtion to book
management. The result is book still there but invisible for everybody because
no one know in that position have a Harry Potter book (because they have to search
book management app first then librian will take that book for them).&lt;&#x2F;p&gt;
&lt;p&gt;In this situation, we can define that Kernel is librian, book management app is
metatdata (SuperBlock, Inode, Inode Table), and the book shelf is directory, book
is block data. The problem is worse when it come to computer because when some thing
bad happen (librian not write to book management app), the system need to check
all book shelf, and correct one by one. This can resolve by Journaling but we have
trade off.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;flag &lt;code&gt;data=journal&lt;&#x2F;code&gt;, copy all data, metadata, everything need to do to journaling.
In the example, it is like librian photo entire book, write to book management app,
marked with signature. Then she will put real book to shelf. But it lead to slowest
performance because we do exact 2 time with 1 request (journal + real request)&lt;&#x2F;li&gt;
&lt;li&gt;flag &lt;code&gt;data=ordered&lt;&#x2F;code&gt;, it will skip photo book part, instead the librian will
put book into shelf, then write to book management app (sound similar without
jouranling feature right?), but if something happen, the journaling have no thing
report about that situation, so the file is real invisible with kernel, and
everything still look good. With this, performance is better because we skip copy
part.&lt;&#x2F;li&gt;
&lt;li&gt;flag &lt;code&gt;data=writeback&lt;&#x2F;code&gt;, instead of put book into shelf immediately, the librian
stack in the table, then sign the book management app that already put on the shelf,
then when she have 2-3 book to carry to that shelf, or available, she will do it.
This lead to crash and security problem, if someone put water into book, the
book will destroy or smth bad happen, or when book is not put into shelf, someone
open the book management app, and see Harry Potter book, he want it, and take it,
but what he receive is John Wick&#x27;s book (which have a gun inside, and some assasin
coin!), because the system not update the old file. That lead to dangerous thing
but have fastest performance&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;img src=&quot;&#x2F;johnwick.jpg&quot; &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;That journaling part is interesting, but what problem that lead to Ext4&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The limitation of ext3 is disk and parition size. In Ext3 structure, it design
for 32bits interger, which mean highest number it can represent is 2^32 - 1,
each block size ~ 4KB =&amp;gt; We can format disk ~ 16TB, but 2TB for a file (15 pointer
structure &lt;code&gt;i_block&lt;&#x2F;code&gt;). Time go by, the size expand quickly, Ext3 nolonger adapt
demand, so Ext4 appear with 3 main feature:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Extents&lt;&#x2F;li&gt;
&lt;li&gt;Delay Allocation&lt;&#x2F;li&gt;
&lt;li&gt;Uninitialized Block&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Extents&lt;&#x2F;strong&gt; replace array 15 pointer &lt;code&gt;i_block&lt;&#x2F;code&gt;, instead of list every block,
extent simple save &lt;code&gt;start_block&lt;&#x2F;code&gt; and &lt;code&gt;data_length&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[ 60 Bytes (i_block) inside the ext4 Inode ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Offset  Size         Structure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+------------+-------------------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 0     |  12 Bytes  | EXTENT HEADER (Tree management header)                      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |            | - eh_magic  : Extent signature&#x2F;magic number (0xF30A)        |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |            | - eh_entries: Number of valid entries currently in this node|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |            | - eh_depth  : Depth of the tree (0 = Leaf node pointing     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |            |               directly to Data)                             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+------------+-------------------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 12    |  12 Bytes  | EXTENT ENTRY #1 (Extent Record #1)                          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |            | - ee_block  : Starting logical block (Example: 0)           |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |            | - ee_len    : Length of the Extent (Example: 25,600 blocks) |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |            | - ee_start  : Starting physical block on disk (48-bit)      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+------------+-------------------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 24    |  12 Bytes  | EXTENT ENTRY #2 (Only used if the file is fragmented)       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+------------+-------------------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 36    |  12 Bytes  | EXTENT ENTRY #3 (Only used if the file is fragmented)       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+------------+-------------------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 48    |  12 Bytes  | EXTENT ENTRY #4 (Only used if the file is fragmented)       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+------------+-------------------------------------------------------------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;               [ TOTAL: 12 + (12 x 4) = EXACTLY 60 BYTES ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Delayed Allocation&lt;&#x2F;strong&gt; reduce the fragment, when a system write a big file,
at ext3, system call &lt;code&gt;write()&lt;&#x2F;code&gt;  rapidly, ext3 immediately give kernel avaiable
file =&amp;gt; 1 big file can be fragment all the system. When come to Ext4, when system
call &lt;code&gt;write()&lt;&#x2F;code&gt;, ext4 refuse to give block address, it copy data to Ram (Page cache)
and update the logical Block, then when data is large enough (batching) or Kernel run out of Ram,
it will flush to disk, Ext4 find range of blocks fit data, so data is continious.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Uninitalized Block&lt;&#x2F;strong&gt; With ext3, when need to check 16TB disk with &lt;code&gt;e2fsck&lt;&#x2F;code&gt; (restart
after currupt) will take 2-10 hours to go through all inode to check. Ext4 simple
add to Group Description 2 field &lt;code&gt;EXT4_BG_INODE_UNINIT&lt;&#x2F;code&gt; and &lt;code&gt;EXT4_BG_BLOCK_UNINIT&lt;&#x2F;code&gt;
mark what block group don&#x27;t have any inode, so don&#x27;t need to group through that
block group&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Conclusion&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The evolution from Ext2 to Ext4 perfectly illustrates how Linux engineers
continually solve complex bottlenecks in storage technology, aslo show the art of
software. At the end of the day, knowing how the computer actually saves a file
under the hood helps us write smarter, better software.&lt;&#x2F;p&gt;
&lt;p&gt;Reference:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;giis.co.in&#x2F;ext2.pdf&quot;&gt;The Second Extended File System Internal Layout&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.usenix.org&#x2F;legacy&#x2F;publications&#x2F;library&#x2F;proceedings&#x2F;usenix02&#x2F;tech&#x2F;freenix&#x2F;full_papers&#x2F;tso&#x2F;tso.pdf&quot;&gt;Planned Extensions to the Linux Ext2&#x2F;Ext3 Filesystem&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kernel.org&#x2F;doc&#x2F;html&#x2F;latest&#x2F;filesystems&#x2F;ext2.html&quot;&gt;The Second Extended Filesystem&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kernel.org&#x2F;doc&#x2F;ols&#x2F;2007&#x2F;ols2007v2-pages-21-34.pdf&quot;&gt;The new ext4 filesystem: current status and future plans&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Disclaimer: There is some low-level informations i have not writen about
ext2&#x2F;3&#x2F;4 in this blog, this is only abstract thing to get feet wet. Feel free to
seek more deeper information or question me.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
