summaryrefslogtreecommitdiff
diff options
l---------build/ext2-doc/DC-ext2-doc1
-rw-r--r--build/ext2-doc/ext2-doc.html1318
-rw-r--r--build/ext2-doc/ext2-doc_color_en.pdfbin0 -> 317396 bytes
-rw-r--r--makefile37
4 files changed, 1319 insertions, 37 deletions
diff --git a/build/ext2-doc/DC-ext2-doc b/build/ext2-doc/DC-ext2-doc
new file mode 120000
index 0000000..f193e5d
--- /dev/null
+++ b/build/ext2-doc/DC-ext2-doc
@@ -0,0 +1 @@
+/dockerShare/DC-ext2-doc \ No newline at end of file
diff --git a/build/ext2-doc/ext2-doc.html b/build/ext2-doc/ext2-doc.html
new file mode 100644
index 0000000..bda8f96
--- /dev/null
+++ b/build/ext2-doc/ext2-doc.html
@@ -0,0 +1,1318 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The Second Extended File System</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1" /></head><body><div xml:lang="en" class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="Ext2.Internals"></a>The Second Extended File System</h1></div><div><h2 class="subtitle">Internal Layout</h2></div><div><div class="authorgroup"><div class="author"><h3 class="author"><span class="firstname">Dave</span> <span class="surname">Poirier</span></h3><div class="affiliation"><div class="address"><p><br />
+      <code class="email">&lt;<a class="email" href="mailto:[email protected]">[email protected]</a>&gt;</code><br />
+     </p></div></div></div></div></div><div><p class="copyright">Copyright © 2001-2019 Dave Poirier</p></div><div><div class="legalnotice"><a id="idm140660450229376"></a><p>
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, with no Front-Cover Texts, and with no
+ Back-Cover Texts. A copy of the license can be acquired electronically
+ from http://www.fsf.org/licenses/fdl.html or by writing to
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ </p></div></div></div><hr /></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="preface"><a href="#idm140660448989936">About this book</a></span></dt><dt><span class="chapter"><a href="#history">1. Historical Background</a></span></dt><dt><span class="chapter"><a href="#Definitions">2. Definitions</a></span></dt><dd><dl><dt><span class="sect1"><a href="#def-blocks">Blocks</a></span></dt><dt><span class="sect1"><a href="#def-block-groups">Block Groups</a></span></dt><dt><span class="sect1"><a href="#def-directories">Directories</a></span></dt><dt><span class="sect1"><a href="#def-inodes">Inodes</a></span></dt><dt><span class="sect1"><a href="#def-superblock">Superblocks</a></span></dt><dt><span class="sect1"><a href="#def-symbolic-links">Symbolic Links</a></span></dt></dl></dd><dt><span class="chapter"><a href="#disk-organisation">3. Disk Organization</a></span></dt><dd><dl><dt><span class="sect1"><a href="#superblock">Superblock</a></span></dt><dd><dl><dt><span class="sect2"><a href="#s-inodes-count">s_inodes_count</a></span></dt><dt><span class="sect2"><a href="#s-blocks-count">s_blocks_count</a></span></dt><dt><span class="sect2"><a href="#s-r-blocks-count">s_r_blocks_count</a></span></dt><dt><span class="sect2"><a href="#s-free-blocks-count">s_free_blocks_count</a></span></dt><dt><span class="sect2"><a href="#s-free-inodes-count">s_free_inodes_count</a></span></dt><dt><span class="sect2"><a href="#s-first-data-block">s_first_data_block</a></span></dt><dt><span class="sect2"><a href="#s-log-block-size">s_log_block_size</a></span></dt><dt><span class="sect2"><a href="#s-log-frag-size">s_log_frag_size</a></span></dt><dt><span class="sect2"><a href="#s-blocks-per-group">s_blocks_per_group</a></span></dt><dt><span class="sect2"><a href="#s-frags-per-group">s_frags_per_group</a></span></dt><dt><span class="sect2"><a href="#s-inodes-per-group">s_inodes_per_group</a></span></dt><dt><span class="sect2"><a href="#s-mtime">s_mtime</a></span></dt><dt><span class="sect2"><a href="#s-wtime">s_wtime</a></span></dt><dt><span class="sect2"><a href="#s-mnt-count">s_mnt_count</a></span></dt><dt><span class="sect2"><a href="#s-max-mnt-count">s_max_mnt_count</a></span></dt><dt><span class="sect2"><a href="#s-magic">s_magic</a></span></dt><dt><span class="sect2"><a href="#s-state">s_state</a></span></dt><dt><span class="sect2"><a href="#s-errors">s_errors</a></span></dt><dt><span class="sect2"><a href="#s-minor-rev-level">s_minor_rev_level</a></span></dt><dt><span class="sect2"><a href="#s-lastcheck">s_lastcheck</a></span></dt><dt><span class="sect2"><a href="#s-checkinterval">s_checkinterval</a></span></dt><dt><span class="sect2"><a href="#s-creator-os">s_creator_os</a></span></dt><dt><span class="sect2"><a href="#s-rev-level">s_rev_level</a></span></dt><dt><span class="sect2"><a href="#s-def-resuid">s_def_resuid</a></span></dt><dt><span class="sect2"><a href="#s-def-resgid">s_def_resgid</a></span></dt><dt><span class="sect2"><a href="#s-first-ino">s_first_ino</a></span></dt><dt><span class="sect2"><a href="#s-inode-size">s_inode_size</a></span></dt><dt><span class="sect2"><a href="#s-block-group-nr">s_block_group_nr</a></span></dt><dt><span class="sect2"><a href="#s-feature-compat">s_feature_compat</a></span></dt><dt><span class="sect2"><a href="#s-feature-incompat">s_feature_incompat</a></span></dt><dt><span class="sect2"><a href="#s-feature-ro-compat">s_feature_ro_compat</a></span></dt><dt><span class="sect2"><a href="#s-uuid">s_uuid</a></span></dt><dt><span class="sect2"><a href="#s-volume-name">s_volume_name</a></span></dt><dt><span class="sect2"><a href="#s-last-mounted">s_last_mounted</a></span></dt><dt><span class="sect2"><a href="#s-algo-bitmap">s_algo_bitmap</a></span></dt><dt><span class="sect2"><a href="#s-prealloc-blocks">s_prealloc_blocks</a></span></dt><dt><span class="sect2"><a href="#s-prealloc-dir-blocks">s_prealloc_dir_blocks</a></span></dt><dt><span class="sect2"><a href="#s-journal-uuid">s_journal_uuid</a></span></dt><dt><span class="sect2"><a href="#s-journal-inum">s_journal_inum</a></span></dt><dt><span class="sect2"><a href="#s-journal-dev">s_journal_dev</a></span></dt><dt><span class="sect2"><a href="#s-last-orphan">s_last_orphan</a></span></dt><dt><span class="sect2"><a href="#s-hash-seed">s_hash_seed</a></span></dt><dt><span class="sect2"><a href="#s-def-hash-version">s_def_hash_version</a></span></dt><dt><span class="sect2"><a href="#s-default-mount-options">s_default_mount_options</a></span></dt><dt><span class="sect2"><a href="#s-first-meta-bg">s_first_meta_bg</a></span></dt></dl></dd><dt><span class="sect1"><a href="#block-group-descriptor-table">Block Group Descriptor Table</a></span></dt><dd><dl><dt><span class="sect2"><a href="#bg-block-bitmap">bg_block_bitmap</a></span></dt><dt><span class="sect2"><a href="#bg-inode-bitmap">bg_inode_bitmap</a></span></dt><dt><span class="sect2"><a href="#bg-inode-table">bg_inode_table</a></span></dt><dt><span class="sect2"><a href="#bg-free-blocks-count">bg_free_blocks_count</a></span></dt><dt><span class="sect2"><a href="#bg-free-inodes-count">bg_free_inodes_count</a></span></dt><dt><span class="sect2"><a href="#bg-used-dirs-count">bg_used_dirs_count</a></span></dt><dt><span class="sect2"><a href="#bg-pad">bg_pad</a></span></dt><dt><span class="sect2"><a href="#bg-reserved">bg_reserved</a></span></dt></dl></dd><dt><span class="sect1"><a href="#block-bitmap">Block Bitmap</a></span></dt><dt><span class="sect1"><a href="#inode-bitmap">Inode Bitmap</a></span></dt><dt><span class="sect1"><a href="#inode-table">Inode Table</a></span></dt><dd><dl><dt><span class="sect2"><a href="#i-mode">i_mode</a></span></dt><dt><span class="sect2"><a href="#i-uid">i_uid</a></span></dt><dt><span class="sect2"><a href="#i-size">i_size</a></span></dt><dt><span class="sect2"><a href="#i-atime">i_atime</a></span></dt><dt><span class="sect2"><a href="#i-ctime">i_ctime</a></span></dt><dt><span class="sect2"><a href="#i-mtime">i_mtime</a></span></dt><dt><span class="sect2"><a href="#i-dtime">i_dtime</a></span></dt><dt><span class="sect2"><a href="#i-gid">i_gid</a></span></dt><dt><span class="sect2"><a href="#i-links-count">i_links_count</a></span></dt><dt><span class="sect2"><a href="#i-blocks">i_blocks</a></span></dt><dt><span class="sect2"><a href="#i-flags">i_flags</a></span></dt><dt><span class="sect2"><a href="#i-osd1">i_osd1</a></span></dt><dt><span class="sect2"><a href="#i-block">i_block</a></span></dt><dt><span class="sect2"><a href="#i-generation">i_generation</a></span></dt><dt><span class="sect2"><a href="#i-file-acl">i_file_acl</a></span></dt><dt><span class="sect2"><a href="#i-dir-acl">i_dir_acl</a></span></dt><dt><span class="sect2"><a href="#i-faddr">i_faddr</a></span></dt><dt><span class="sect2"><a href="#i-osd2">Inode i_osd2 Structure</a></span></dt></dl></dd><dt><span class="sect1"><a href="#idm140660447281728">Locating an Inode</a></span></dt></dl></dd><dt><span class="chapter"><a href="#directory">4. Directory Structure</a></span></dt><dd><dl><dt><span class="sect1"><a href="#linked-directories">Linked List Directory</a></span></dt><dd><dl><dt><span class="sect2"><a href="#ifdir-inode">inode</a></span></dt><dt><span class="sect2"><a href="#ifdir-rec-len">rec_len</a></span></dt><dt><span class="sect2"><a href="#ifdir-name-len">name_len</a></span></dt><dt><span class="sect2"><a href="#ifdir-file-type">file_type</a></span></dt><dt><span class="sect2"><a href="#ifdir-name">name</a></span></dt><dt><span class="sect2"><a href="#dir-sample">Sample Directory</a></span></dt></dl></dd><dt><span class="sect1"><a href="#indexed-directory">Indexed Directory Format</a></span></dt><dd><dl><dt><span class="sect2"><a href="#dx-root">Indexed Directory Root</a></span></dt><dt><span class="sect2"><a href="#dx-entry">Indexed Directory Entry</a></span></dt><dt><span class="sect2"><a href="#contrib-lookup-algorithm">Lookup Algorithm</a></span></dt><dt><span class="sect2"><a href="#contrib-insert-algorithm">Insert Algorithm</a></span></dt><dt><span class="sect2"><a href="#contrib-splitting">Splitting</a></span></dt><dt><span class="sect2"><a href="#contrib-key-collisions">Key Collisions</a></span></dt><dt><span class="sect2"><a href="#contrib-hash-function">Hash Function</a></span></dt><dt><span class="sect2"><a href="#contrib-performance">Performance</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#idm140660446981504">5. File Attributes</a></span></dt><dd><dl><dt><span class="sect1"><a href="#idm140660446979776">Standard Attributes</a></span></dt><dd><dl><dt><span class="sect2"><a href="#idm140660446979264">SUID, SGID and -rwxrwxrwx</a></span></dt><dt><span class="sect2"><a href="#idm140660446977504">File Size</a></span></dt><dt><span class="sect2"><a href="#idm140660446975776">Owner and Group</a></span></dt></dl></dd><dt><span class="sect1"><a href="#contrib-extended-attributes">Extended Attributes</a></span></dt><dd><dl><dt><span class="sect2"><a href="#extended-attribute-layout">Extended Attribute Block Layout</a></span></dt><dt><span class="sect2"><a href="#attribute-block-header">Extended Attribute Block Header</a></span></dt><dt><span class="sect2"><a href="#idm140660446913440">Attribute Entry Header</a></span></dt></dl></dd><dt><span class="sect1"><a href="#behaviour-flags">Behaviour Control Flags</a></span></dt><dd><dl><dt><span class="sect2"><a href="#ext2-secrm-fl">EXT2_SECRM_FL - Secure Deletion</a></span></dt><dt><span class="sect2"><a href="#ext2-unrm-fl">EXT2_UNRM_FL - Record for Undelete</a></span></dt><dt><span class="sect2"><a href="#ext2-compr-fl">EXT2_COMPR_FL - Compressed File</a></span></dt><dt><span class="sect2"><a href="#ext2-sync-fl">EXT2_SYNC_FL - Synchronous Updates</a></span></dt><dt><span class="sect2"><a href="#ext2-immutable-fl">EXT2_IMMUTABLE_FL - Immutable File</a></span></dt><dt><span class="sect2"><a href="#ext2-append-fl">EXT2_APPEND_FL - Append Only</a></span></dt><dt><span class="sect2"><a href="#ext2-nodump-fl">EXT2_NODUMP_FL - Do No Dump/Delete</a></span></dt><dt><span class="sect2"><a href="#ext2-noatime-fl">EXT2_NOATIME_FL - Do Not Update .i_atime</a></span></dt><dt><span class="sect2"><a href="#ext2-dirty-fl">EXT2_DIRTY_FL - Dirty</a></span></dt><dt><span class="sect2"><a href="#ext2-comprblk-fl">EXT2_COMPRBLK_FL - Compressed Blocks</a></span></dt><dt><span class="sect2"><a href="#ext2-nocompr-fl">EXT2_NOCOMPR_FL - Access Raw Compressed Data</a></span></dt><dt><span class="sect2"><a href="#ext2-ecompr-fl">EXT2_ECOMPR_FL - Compression Error</a></span></dt><dt><span class="sect2"><a href="#ext2-btree-fl">EXT2_BTREE_FL - B-Tree Format Directory</a></span></dt><dt><span class="sect2"><a href="#ext2-index-fl">EXT2_INDEX_FL - Hash Indexed Directory</a></span></dt><dt><span class="sect2"><a href="#ext2-imagic-fl">EXT2_IMAGIC_FL - </a></span></dt><dt><span class="sect2"><a href="#ext3-journal-data-fl">EXT2_JOURNAL_DATA_FL - Journal File Data</a></span></dt><dt><span class="sect2"><a href="#ext2-reserved-fl">EXT2_RESERVED_FL - Reserved</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="#idm140660446838800">A. Credits</a></span></dt></dl></div><div class="list-of-figures"><p><strong>List of Figures</strong></p><dl><dt>4.1. <a href="#idm140660446987040">Performance of Indexed Directories</a></dt><dt>5.1. <a href="#idm140660446912928">ext2_xattr_header structure</a></dt></dl></div><div class="list-of-tables"><p><strong>List of Tables</strong></p><dl><dt>2.1. <a href="#block-size-impact">Impact of Block Sizes</a></dt><dt>3.1. <a href="#disk-layout-sample-floppy">Sample Floppy Disk Layout, 1KiB blocks</a></dt><dt>3.2. <a href="#disk-layout-sample-20mb">Sample 20mb Partition Layout</a></dt><dt>3.3. <a href="#superblock-structure">Superblock Structure</a></dt><dt>3.4. <a href="#s-state-values">Defined s_state Values</a></dt><dt>3.5. <a href="#ext2-errors">Defined s_errors Values</a></dt><dt>3.6. <a href="#s-creator-os-values">Defined s_creator_os Values</a></dt><dt>3.7. <a href="#s-rev-level-values">Defined s_rev_level Values</a></dt><dt>3.8. <a href="#s-feature-compat-values">Defined s_feature_compat Values</a></dt><dt>3.9. <a href="#s-feature-incompat-values">Defined s_feature_incompat Values</a></dt><dt>3.10. <a href="#s-feature-ro-compat-values">Defined s_feature_ro_compat Values</a></dt><dt>3.11. <a href="#s-algo-bitmap-values">Defined s_algo_bitmap Values</a></dt><dt>3.12. <a href="#block-group-descriptor-structure">Block Group Descriptor Structure</a></dt><dt>3.13. <a href="#inode-structure">Inode Structure</a></dt><dt>3.14. <a href="#reserved-inodes-values">Defined Reserved Inodes</a></dt><dt>3.15. <a href="#idm140660447480672">Defined i_mode Values</a></dt><dt>3.16. <a href="#defined-i-flags-values">Defined i_flags Values</a></dt><dt>3.17. <a href="#i-osd2-hurd-structure">Inode i_osd2 Structure: Hurd</a></dt><dt>3.18. <a href="#i-osd2-linux-structure">Inode i_osd2 Structure: Linux</a></dt><dt>3.19. <a href="#i-osd2-masix-structure">Inode i_osd2 Structure: Masix</a></dt><dt>3.20. <a href="#inode-computation-sample">Sample Inode Computations</a></dt><dt>4.1. <a href="#linked-directory-entry-structure">Linked Directory Entry Structure</a></dt><dt>4.2. <a href="#ifdir-file-type-values">Defined Inode File Type Values</a></dt><dt>4.3. <a href="#sample-linked-directory-data">Sample Linked Directory Data Layout, 4KiB blocks</a></dt><dt>4.4. <a href="#dx-root-structure">Indexed Directory Root Structure</a></dt><dt>4.5. <a href="#defined-dx-hash-version-values">Defined Indexed Directory Hash Versions</a></dt><dt>4.6. <a href="#dx-entry-structure">Indexed Directory Entry Structure (dx_entry)</a></dt><dt>4.7. <a href="#dx-entry-countlimit">Indexed Directory Entry Count and Limit Structure</a></dt><dt>5.1. <a href="#extended-attribute-block-layout">Extended Attribute Block Layout</a></dt><dt>5.2. <a href="#attribute-block-header-structure">ext2_xattr_header structure</a></dt><dt>5.3. <a href="#idm140660446894752">Behaviour Control Flags</a></dt></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a id="idm140660448989936"></a>About this book</h1></div></div></div><p>
+ The latest version of this document may be downloaded from
+ https://www.nongnu.org/ext2-doc/
+ </p><p>
+ This book is intended as an introduction and guide to the Second
+ Extended File System, also known as Ext2. The reader should have a
+ good understanding of the purpose of a file system as well as the
+ associated vocabulary (file, directory, partition, etc).
+ </p><p>
+ Implementing file system drivers is already a daunting task, unfortunately
+ except for tidbits of information here and there most of the documentation
+ for the Second Extended Filesystem is in source files.
+ </p><p>
+ Hopefully this document will fix this problem, may it be of help to as
+ many of you as possible.
+ </p><p>
+ <span class="emphasis"><em>Unless otherwise stated, all values are stored in little
+ endian byte order.</em></span>
+ </p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="history"></a>Chapter 1. Historical Background</h1></div></div></div><p>
+ Written by Remy Card, Theodore Ts'o and Stephen Tweedie as a major rewrite
+ of the Extended Filesystem, it was first released to the public on January
+ 1993 as part of the Linux kernel. One of its greatest achievement is the
+ ability to extend the file system functionalities while maintaining the
+ internal structures. This allowed an easier development of the Third
+ Extended Filesystem (ext3) and the Fourth Extended Filesystem (ext4).
+ </p><p>
+ There are implementations available in most operating system including but
+ not limited to NetBSD, FreeBSD, the GNU HURD, Microsoft Windows, IBM OS/2
+ and RISC OS.
+ </p><p>
+ Although newer file systems have been designed, such as Ext3 and Ext4, the
+ Second Extended Filesystem is still prefered on flash drives as it requires
+ fewer write operations (since it has no journal). The structures of Ext3
+ and Ext4 are based on Ext2 and add some additional options such as journaling,
+ journal checksums, extents, online defragmentation, delayed allocations and
+ larger directories to name but a few.
+ </p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="Definitions"></a>Chapter 2. Definitions</h1></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="#def-blocks">Blocks</a></span></dt><dt><span class="sect1"><a href="#def-block-groups">Block Groups</a></span></dt><dt><span class="sect1"><a href="#def-directories">Directories</a></span></dt><dt><span class="sect1"><a href="#def-inodes">Inodes</a></span></dt><dt><span class="sect1"><a href="#def-superblock">Superblocks</a></span></dt><dt><span class="sect1"><a href="#def-symbolic-links">Symbolic Links</a></span></dt></dl></div><p>
+ The Second Extended Filesystem uses blocks as the basic unit of storage,
+ inodes as the mean of keeping track of files and system objects, block groups
+ to logically split the disk into more manageable sections, directories to
+ provide a hierarchical organization of files, block and inode bitmaps to keep
+ track of allocated blocks and inodes, and superblocks to define
+ the parameters of the file system and its overall state.
+ </p><p>
+ Ext2 shares many properties with traditional Unix filesystems. It has space
+ in the specification for Access Control Lists (ACLs), fragments, undeletion
+ and compression. There is also a versioning mechanism to allow new
+ features (such as journalling) to be added in a maximally compatible
+ manner; such as in Ext3 and Ext4.
+ </p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="def-blocks"></a>Blocks</h2></div></div></div><p>
+ A partition, disk, file or block device formated with a Second Extended
+ Filesystem is divided into small groups of sectors called <span class="quote">“<span class="quote">blocks</span>”</span>. These blocks are then grouped into larger units called block groups.
+ </p><p>
+ The size of the blocks are usually determined when formatting the disk
+ and will have an impact on performance, maximum file size, and maximum
+ file system size. Block sizes commonly implemented include 1KiB,
+ 2KiB, 4KiB and 8KiB although provisions in the superblock allow for
+ block sizes as big as 1024 * (2^31)-1 (see
+ <a class="link" href="#s-log-block-size" title="s_log_block_size">s_log_block_size</a>).
+ </p><p>
+ Depending on the implementation, some architectures may impose limits on
+ which block sizes are supported. For example, a Linux 2.6
+ implementation on DEC Alpha uses blocks of 8KiB but the same
+ implementation on a Intel 386 processor will support a maximum block
+ size of 4KiB.
+ </p><div class="table"><a id="block-size-impact"></a><p class="title"><strong>Table 2.1. Impact of Block Sizes</strong></p><div class="table-contents"><table summary="Impact of Block Sizes" width="100%" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th align="left">Upper Limits</th><th align="left">1KiB</th><th align="left">2KiB</th><th align="left">4KiB</th><th align="left">8KiB</th></tr></thead><tbody><tr><td align="left">file system blocks</td><td align="left">2,147,483,647</td><td align="left">2,147,483,647</td><td align="left">2,147,483,647</td><td align="left">2,147,483,647</td></tr><tr><td align="left">blocks per block group</td><td align="left">8,192</td><td align="left">16,384</td><td align="left">32,768</td><td align="left">65,536</td></tr><tr><td align="left">inodes per block group</td><td align="left">8,192</td><td align="left">16,384</td><td align="left">32,768</td><td align="left">65,536</td></tr><tr><td align="left">bytes per block group</td><td align="left">8,388,608 (8MiB)</td><td align="left">33,554,432 (32MiB)</td><td align="left">134,217,728 (128MiB)</td><td align="left">536,870,912 (512MiB)</td></tr><tr><td align="left">file system size (real)</td><td align="left">4,398,046,509,056 (4TiB)</td><td align="left">8,796,093,018,112 (8TiB)</td><td align="left">17,592,186,036,224 (16TiB)</td><td align="left">35,184,372,080,640 (32TiB)</td></tr><tr><td align="left">file system size (Linux)</td><td align="left">2,199,023,254,528 (2TiB)
+ <a href="#ftn.idm140660453588896" class="footnote" id="idm140660453588896"><sup class="footnote">[a]</sup></a>
+ </td><td align="left">8,796,093,018,112 (8TiB)</td><td align="left">17,592,186,036,224 (16TiB)</td><td align="left">35,184,372,080,640 (32TiB)</td></tr><tr><td align="left">blocks per file</td><td align="left">16,843,020</td><td align="left">134,217,728</td><td align="left">1,074,791,436</td><td align="left">8,594,130,956</td></tr><tr><td align="left">file size (real)</td><td align="left">17,247,252,480 (16GiB)</td><td align="left">274,877,906,944 (256GiB)</td><td align="left">2,199,023,255,552 (2TiB)</td><td align="left">2,199,023,255,552 (2TiB)</td></tr><tr><td align="left">file size (Linux 2.6.28)</td><td align="left">17,247,252,480 (16GiB)</td><td align="left">274,877,906,944 (256GiB)</td><td align="left">2,199,023,255,552 (2TiB)</td><td align="left">2,199,023,255,552 (2TiB)</td></tr></tbody><tbody class="footnotes"><tr><td colspan="5"><div id="ftn.idm140660453588896" class="footnote"><p><a href="#idm140660453588896" class="para"><sup class="para">[a] </sup></a>
+ This limit comes from the maximum size of a block device in
+ Linux 2.4; it is unclear whether a Linux 2.6 kernel using a 1KiB block
+ size could properly format and mount a Ext2 partition larger than 2TiB.
+ </p></div></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Note: the 2TiB file size is limited by the i_blocks value in the inode which indicates the number of 512-bytes sector rather than the actual number of ext2 blocks allocated.
+ </p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="def-block-groups"></a>Block Groups</h2></div></div></div><div class="epigraph"><p>
+ This definition comes from the Linux Kernel Documentation.
+ </p></div><p>
+ Blocks are clustered into block groups in order to reduce fragmentation
+ and minimise the amount of head seeking when reading a large amount
+ of consecutive data. Information about each block group is kept in a
+ descriptor table stored in the block(s) immediately after the superblock.
+ Two blocks near the start of each group are reserved for the block usage
+ bitmap and the inode usage bitmap which show which blocks and inodes
+ are in use. Since each bitmap is limited to a single block, this means
+ that the maximum size of a block group is 8 times the size of a block.
+ </p><p>
+ The block(s) following the bitmaps in each block group are designated
+ as the inode table for that block group and the remainder are the data
+ blocks. The block allocation algorithm attempts to allocate data blocks
+ in the same block group as the inode which contains them.
+ </p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="def-directories"></a>Directories</h2></div></div></div><div class="epigraph"><p>
+ This definition comes from the Linux Kernel Documentation with some minor
+ alterations.
+ </p></div><p>
+ A directory is a filesystem object and has an inode just like a file.
+ It is a specially formatted file containing records which associate
+ each name with an inode number. Later revisions of the filesystem also
+ encode the type of the object (file, directory, symlink, device, fifo,
+ socket) to avoid the need to check the inode itself for this information
+ </p><p>
+ The inode allocation code should try to assign inodes which are in the same
+ block group as the directory in which they are first created.
+ </p><p>
+ The original Ext2 revision used singly-linked list to store
+ the filenames in the directory; newer revisions are able to use hashes
+ and binary trees.
+ </p><p>
+ Also note that as directory grows additional blocks are assigned to
+ store the additional file records. When filenames are removed, some
+ implementations do not free these additional blocks.
+ </p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="def-inodes"></a>Inodes</h2></div></div></div><div class="epigraph"><p>
+ This definition comes from the Linux Kernel Documentation with some minor
+ alterations.
+ </p></div><p>
+ The inode (index node) is a fundamental concept in the ext2 filesystem.
+ Each object in the filesystem is represented by an inode. The inode
+ structure contains pointers to the filesystem blocks which contain the
+ data held in the object and all of the metadata about an object except
+ its name. The metadata about an object includes the permissions, owner,
+ group, flags, size, number of blocks used, access time, change time,
+ modification time, deletion time, number of links, fragments, version
+ (for NFS) and extended attributes (EAs) and/or Access Control Lists (ACLs).
+ </p><p>
+ There are some reserved fields which are currently unused in the inode
+ structure and several which are overloaded. One field is reserved for the
+ directory ACL if the inode is a directory and alternately for the top 32
+ bits of the file size if the inode is a regular file (allowing file sizes
+ larger than 2GB). The translator field is unused under Linux, but is used
+ by the HURD to reference the inode of a program which will be used to
+ interpret this object. Most of the remaining reserved fields have been
+ used up for both Linux and the HURD for larger owner and group fields,
+ The HURD also has a larger mode field so it uses another of the remaining
+ fields to store the extra bits.
+ </p><p>
+ There are pointers to the first 12 blocks which contain the file's data
+ in the inode. There is a pointer to an indirect block (which contains
+ pointers to the next set of blocks), a pointer to a doubly-indirect
+ block (which contains pointers to indirect blocks) and a pointer to a
+ trebly-indirect block (which contains pointers to doubly-indirect blocks).
+ </p><p>
+ Some filesystem specific behaviour flags are also stored and allow for
+ specific filesystem behaviour on a per-file basis. There are flags for
+ secure deletion, undeletable, compression, synchronous updates,
+ immutability, append-only, dumpable, no-atime, indexed directories, and
+ data-journaling.
+ </p><p>
+ Many of the filesystem specific behaviour flags, like journaling, have been
+ implemented in newer filesystems like Ext3 and Ext4, while some other
+ are still under development.
+ </p><p>
+ All the inodes are stored in inode tables, with one inode table per block group.
+ </p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="def-superblock"></a>Superblocks</h2></div></div></div><div class="epigraph"><p>
+ This definition comes from the Linux Kernel Documentation with some minor
+ alterations.
+ </p></div><p>
+ The superblock contains all the information about the configuration of
+ the filesystem. The information in the superblock contains fields
+ such as the total number of inodes and blocks in the filesystem and how
+ many are free, how many inodes and blocks are in each block group, when
+ the filesystem was mounted (and if it was cleanly unmounted), when it
+ was modified, what version of the filesystem it is and which OS created
+ it.
+ </p><p>
+ The primary copy of the superblock is stored at an offset of 1024 bytes
+ from the start of the device, and it is essential to mounting the
+ filesystem. Since it is so important, backup copies of the superblock
+ are stored in block groups throughout the filesystem.
+ </p><p>
+ The first version of ext2 (revision 0) stores a copy at the start of
+ every block group, along with backups of the group descriptor block(s).
+ Because this can consume a considerable amount of space for large
+ filesystems, later revisions can optionally reduce the number of backup
+ copies by only putting backups in specific groups (this is the sparse
+ superblock feature). The groups chosen are 0, 1 and powers of 3, 5 and 7.
+ </p><p>
+ Revision 1 and higher of the filesystem also store extra fields, such as
+ a volume name, a unique identification number, the inode size, and space
+ for optional filesystem features to store configuration info.
+ </p><p>
+ All fields in the superblock (as in all other ext2 structures) are stored
+ on the disc in little endian format, so a filesystem is portable between
+ machines without having to know what machine it was created on.
+ </p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="def-symbolic-links"></a>Symbolic Links</h2></div></div></div><div class="epigraph"><p>
+ This definition comes from Wikipedia.org with some minor
+ alterations.
+ </p></div><p>
+ A symbolic link (also symlink or soft link) is a special type of file that
+ contains a reference to another file or directory in the form of an
+ absolute or relative path and that affects pathname resolution.
+ </p><p>
+ Symbolic links operate transparently for most operations: programs which
+ read or write to files named by a symbolic link will behave as if
+ operating directly on the target file. However, programs that need to
+ handle symbolic links specially (e.g., backup utilities) may identify
+ and manipulate them directly.
+ </p><p>
+ A symbolic link merely contains a text string that is interpreted and
+ followed by the operating system as a path to another file or directory.
+ It is a file on its own and can exist independently of its target. The
+ symbolic links do not affect an inode link count. If a symbolic link is
+ deleted, its target remains unaffected. If the target is moved, renamed
+ or deleted, any symbolic link that used to point to it continues to exist
+ but now points to a non-existing file. Symbolic links pointing to
+ non-existing files are sometimes called <span class="quote">“<span class="quote">orphaned</span>”</span> or
+ <span class="quote">“<span class="quote">dangling</span>”</span>.
+ </p><p>
+ Symbolic links are also filesystem objects with inodes. For all symlink
+ shorter than 60 bytes long, the data is stored within the inode itself; it
+ uses the fields which would normally be used to store the pointers to data
+ blocks. This is a worthwhile optimisation as it we avoid allocating a full
+ block for the symlink, and most symlinks are less than 60 characters long.
+ </p><p>
+ Symbolic links can also point to files or directories of other partitions
+ and file systems.
+ </p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="disk-organisation"></a>Chapter 3. Disk Organization</h1></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="#superblock">Superblock</a></span></dt><dd><dl><dt><span class="sect2"><a href="#s-inodes-count">s_inodes_count</a></span></dt><dt><span class="sect2"><a href="#s-blocks-count">s_blocks_count</a></span></dt><dt><span class="sect2"><a href="#s-r-blocks-count">s_r_blocks_count</a></span></dt><dt><span class="sect2"><a href="#s-free-blocks-count">s_free_blocks_count</a></span></dt><dt><span class="sect2"><a href="#s-free-inodes-count">s_free_inodes_count</a></span></dt><dt><span class="sect2"><a href="#s-first-data-block">s_first_data_block</a></span></dt><dt><span class="sect2"><a href="#s-log-block-size">s_log_block_size</a></span></dt><dt><span class="sect2"><a href="#s-log-frag-size">s_log_frag_size</a></span></dt><dt><span class="sect2"><a href="#s-blocks-per-group">s_blocks_per_group</a></span></dt><dt><span class="sect2"><a href="#s-frags-per-group">s_frags_per_group</a></span></dt><dt><span class="sect2"><a href="#s-inodes-per-group">s_inodes_per_group</a></span></dt><dt><span class="sect2"><a href="#s-mtime">s_mtime</a></span></dt><dt><span class="sect2"><a href="#s-wtime">s_wtime</a></span></dt><dt><span class="sect2"><a href="#s-mnt-count">s_mnt_count</a></span></dt><dt><span class="sect2"><a href="#s-max-mnt-count">s_max_mnt_count</a></span></dt><dt><span class="sect2"><a href="#s-magic">s_magic</a></span></dt><dt><span class="sect2"><a href="#s-state">s_state</a></span></dt><dt><span class="sect2"><a href="#s-errors">s_errors</a></span></dt><dt><span class="sect2"><a href="#s-minor-rev-level">s_minor_rev_level</a></span></dt><dt><span class="sect2"><a href="#s-lastcheck">s_lastcheck</a></span></dt><dt><span class="sect2"><a href="#s-checkinterval">s_checkinterval</a></span></dt><dt><span class="sect2"><a href="#s-creator-os">s_creator_os</a></span></dt><dt><span class="sect2"><a href="#s-rev-level">s_rev_level</a></span></dt><dt><span class="sect2"><a href="#s-def-resuid">s_def_resuid</a></span></dt><dt><span class="sect2"><a href="#s-def-resgid">s_def_resgid</a></span></dt><dt><span class="sect2"><a href="#s-first-ino">s_first_ino</a></span></dt><dt><span class="sect2"><a href="#s-inode-size">s_inode_size</a></span></dt><dt><span class="sect2"><a href="#s-block-group-nr">s_block_group_nr</a></span></dt><dt><span class="sect2"><a href="#s-feature-compat">s_feature_compat</a></span></dt><dt><span class="sect2"><a href="#s-feature-incompat">s_feature_incompat</a></span></dt><dt><span class="sect2"><a href="#s-feature-ro-compat">s_feature_ro_compat</a></span></dt><dt><span class="sect2"><a href="#s-uuid">s_uuid</a></span></dt><dt><span class="sect2"><a href="#s-volume-name">s_volume_name</a></span></dt><dt><span class="sect2"><a href="#s-last-mounted">s_last_mounted</a></span></dt><dt><span class="sect2"><a href="#s-algo-bitmap">s_algo_bitmap</a></span></dt><dt><span class="sect2"><a href="#s-prealloc-blocks">s_prealloc_blocks</a></span></dt><dt><span class="sect2"><a href="#s-prealloc-dir-blocks">s_prealloc_dir_blocks</a></span></dt><dt><span class="sect2"><a href="#s-journal-uuid">s_journal_uuid</a></span></dt><dt><span class="sect2"><a href="#s-journal-inum">s_journal_inum</a></span></dt><dt><span class="sect2"><a href="#s-journal-dev">s_journal_dev</a></span></dt><dt><span class="sect2"><a href="#s-last-orphan">s_last_orphan</a></span></dt><dt><span class="sect2"><a href="#s-hash-seed">s_hash_seed</a></span></dt><dt><span class="sect2"><a href="#s-def-hash-version">s_def_hash_version</a></span></dt><dt><span class="sect2"><a href="#s-default-mount-options">s_default_mount_options</a></span></dt><dt><span class="sect2"><a href="#s-first-meta-bg">s_first_meta_bg</a></span></dt></dl></dd><dt><span class="sect1"><a href="#block-group-descriptor-table">Block Group Descriptor Table</a></span></dt><dd><dl><dt><span class="sect2"><a href="#bg-block-bitmap">bg_block_bitmap</a></span></dt><dt><span class="sect2"><a href="#bg-inode-bitmap">bg_inode_bitmap</a></span></dt><dt><span class="sect2"><a href="#bg-inode-table">bg_inode_table</a></span></dt><dt><span class="sect2"><a href="#bg-free-blocks-count">bg_free_blocks_count</a></span></dt><dt><span class="sect2"><a href="#bg-free-inodes-count">bg_free_inodes_count</a></span></dt><dt><span class="sect2"><a href="#bg-used-dirs-count">bg_used_dirs_count</a></span></dt><dt><span class="sect2"><a href="#bg-pad">bg_pad</a></span></dt><dt><span class="sect2"><a href="#bg-reserved">bg_reserved</a></span></dt></dl></dd><dt><span class="sect1"><a href="#block-bitmap">Block Bitmap</a></span></dt><dt><span class="sect1"><a href="#inode-bitmap">Inode Bitmap</a></span></dt><dt><span class="sect1"><a href="#inode-table">Inode Table</a></span></dt><dd><dl><dt><span class="sect2"><a href="#i-mode">i_mode</a></span></dt><dt><span class="sect2"><a href="#i-uid">i_uid</a></span></dt><dt><span class="sect2"><a href="#i-size">i_size</a></span></dt><dt><span class="sect2"><a href="#i-atime">i_atime</a></span></dt><dt><span class="sect2"><a href="#i-ctime">i_ctime</a></span></dt><dt><span class="sect2"><a href="#i-mtime">i_mtime</a></span></dt><dt><span class="sect2"><a href="#i-dtime">i_dtime</a></span></dt><dt><span class="sect2"><a href="#i-gid">i_gid</a></span></dt><dt><span class="sect2"><a href="#i-links-count">i_links_count</a></span></dt><dt><span class="sect2"><a href="#i-blocks">i_blocks</a></span></dt><dt><span class="sect2"><a href="#i-flags">i_flags</a></span></dt><dt><span class="sect2"><a href="#i-osd1">i_osd1</a></span></dt><dt><span class="sect2"><a href="#i-block">i_block</a></span></dt><dt><span class="sect2"><a href="#i-generation">i_generation</a></span></dt><dt><span class="sect2"><a href="#i-file-acl">i_file_acl</a></span></dt><dt><span class="sect2"><a href="#i-dir-acl">i_dir_acl</a></span></dt><dt><span class="sect2"><a href="#i-faddr">i_faddr</a></span></dt><dt><span class="sect2"><a href="#i-osd2">Inode i_osd2 Structure</a></span></dt></dl></dd><dt><span class="sect1"><a href="#idm140660447281728">Locating an Inode</a></span></dt></dl></div><p>
+ An Ext2 file systems starts with a <a class="link" href="#superblock" title="Superblock">superblock</a>
+ located at byte offset 1024 from the start of the volume. This is block 1
+ for a 1KiB block formatted volume or within block 0 for larger block sizes. Note that the size of the superblock is constant regardless of the block size.
+ </p><p>
+ On the next block(s) following the superblock, is the
+ Block Group Descriptor Table; which provides an overview of how the volume
+ is split into block groups and where to find the inode bitmap, the block bitmap,
+ and the inode table for each block group.
+ </p><p>
+ In revision 0 of Ext2, each block group consists of a copy superblock, a copy of the
+ block group descriptor table, a block bitmap, an inode bitmap, an inode table,
+ and data blocks.
+ </p><p>
+ With the introduction of revision 1 and the sparse superblock feature in Ext2,
+ only specific block groups contain copies of the superblock and block group
+ descriptor table. All block groups still contain the block bitmap, inode
+ bitmap, inode table, and data blocks. The shadow copies of the superblock can
+ be located in block groups 0, 1 and powers of 3, 5 and 7.
+ </p><p>
+ The block bitmap and inode bitmap are limited to 1 block each per block group,
+ so the total blocks per block group is therefore limited. (More information in
+ the <a class="link" href="#block-size-impact" title="Table 2.1. Impact of Block Sizes">Block Size Impact</a> table).
+ </p><p>
+ Each data block may also be further divided into <span class="quote">“<span class="quote">fragments</span>”</span>. As of
+ Linux 2.6.28, support for fragment was still not implemented in the kernel;
+ it is therefore suggested to ensure the fragment size is equal to the
+ block size so as to maintain compatibility.
+ </p><div class="table"><a id="disk-layout-sample-floppy"></a><p class="title"><strong>Table 3.1. Sample Floppy Disk Layout, 1KiB blocks</strong></p><div class="table-contents"><table summary="Sample Floppy Disk Layout, 1KiB blocks" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Block Offset</th><th>Length</th><th>Description</th></tr></thead><tbody><tr><td>byte 0</td><td>512 bytes</td><td>boot record (if present)</td></tr><tr><td>byte 512</td><td>512 bytes</td><td>additional boot record data (if present)</td></tr><tr><td colspan="3" align="left">-- block group 0, blocks 1 to 1439 --</td></tr><tr><td>byte 1024</td><td>1024 bytes</td><td><a class="link" href="#superblock" title="Superblock">superblock</a></td></tr><tr><td>block 2</td><td>1 block</td><td><a class="link" href="#block-group-descriptor-table" title="Block Group Descriptor Table">block group descriptor table</a></td></tr><tr><td>block 3</td><td>1 block</td><td><a class="link" href="#block-bitmap" title="Block Bitmap">block bitmap</a></td></tr><tr><td>block 4</td><td>1 block</td><td><a class="link" href="#inode-bitmap" title="Inode Bitmap">inode bitmap</a></td></tr><tr><td>block 5</td><td>23 blocks</td><td><a class="link" href="#inode-table" title="Inode Table">inode table</a></td></tr><tr><td>block 28</td><td>1412 blocks</td><td>data blocks</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For the curious, block 0 always points to the first sector of the disk
+ or partition and will always contain the boot record if one is present.
+ </p><p>
+ The superblock is always located at byte offset 1024 from the start of
+ the disk or partition. In a 1KiB block-size formatted file system, this is
+ block 1, but it will always be block 0 (at 1024 bytes within block 0) in
+ larger block size file systems.
+ </p><p>
+ And here's the organisation of a 20MB ext2 file system, using 1KiB blocks:
+ </p><div class="table"><a id="disk-layout-sample-20mb"></a><p class="title"><strong>Table 3.2. Sample 20mb Partition Layout</strong></p><div class="table-contents"><table summary="Sample 20mb Partition Layout" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Block Offset</th><th>Length</th><th>Description</th></tr></thead><tbody><tr><td>byte 0</td><td>512 bytes</td><td>boot record (if present)</td></tr><tr><td>byte 512</td><td>512 bytes</td><td>additional boot record data (if present)</td></tr><tr><td colspan="3" align="left">-- block group 0, blocks 1 to 8192 --</td></tr><tr><td>byte 1024</td><td>1024 bytes</td><td><a class="link" href="#superblock" title="Superblock">superblock</a></td></tr><tr><td>block 2</td><td>1 block</td><td><a class="link" href="#block-group-descriptor-table" title="Block Group Descriptor Table">block group descriptor table</a></td></tr><tr><td>block 3</td><td>1 block</td><td><a class="link" href="#block-bitmap" title="Block Bitmap">block bitmap</a></td></tr><tr><td>block 4</td><td>1 block</td><td><a class="link" href="#inode-bitmap" title="Inode Bitmap">inode bitmap</a></td></tr><tr><td>block 5</td><td>214 blocks</td><td><a class="link" href="#inode-table" title="Inode Table">inode table</a></td></tr><tr><td>block 219</td><td>7974 blocks</td><td>data blocks</td></tr><tr><td colspan="3" align="left">-- block group 1, blocks 8193 to 16384 --</td></tr><tr><td>block 8193</td><td>1 block</td><td><a class="link" href="#superblock" title="Superblock">superblock</a> backup</td></tr><tr><td>block 8194</td><td>1 block</td><td><a class="link" href="#block-group-descriptor-table" title="Block Group Descriptor Table">block group descriptor table</a> backup</td></tr><tr><td>block 8195</td><td>1 block</td><td><a class="link" href="#block-bitmap" title="Block Bitmap">block bitmap</a></td></tr><tr><td>block 8196</td><td>1 block</td><td><a class="link" href="#inode-bitmap" title="Inode Bitmap">inode bitmap</a></td></tr><tr><td>block 8197</td><td>214 blocks</td><td><a class="link" href="#inode-table" title="Inode Table">inode table</a></td></tr><tr><td>block 8408</td><td>7974 blocks</td><td>data blocks</td></tr><tr><td colspan="3" align="left">-- block group 2, blocks 16385 to 24576 --</td></tr><tr><td>block 16385</td><td>1 block</td><td><a class="link" href="#block-bitmap" title="Block Bitmap">block bitmap</a></td></tr><tr><td>block 16386</td><td>1 block</td><td><a class="link" href="#inode-bitmap" title="Inode Bitmap">inode bitmap</a></td></tr><tr><td>block 16387</td><td>214 blocks</td><td><a class="link" href="#inode-table" title="Inode Table">inode table</a></td></tr><tr><td>block 16601</td><td>3879 blocks</td><td>data blocks</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The layout on disk is very predictable as long as you know a few basic
+ information; block size, blocks per group, inodes per group. This
+ information is all located in, or can be computed from, the
+ <span class="structname">superblock</span> structure.
+ </p><p>
+ Nevertheless, unless the image was crafted with controlled parameters,
+ the position of the various structures on disk (except the superblock)
+ should never be assumed. Always load the superblock first.
+ </p><p>
+ Notice how block 0 is not part of the block group 0 in 1KiB block
+ size file systems. The reason for this is block group 0 always starts
+ with the block containing the superblock. Hence, on 1KiB block systems,
+ block group 0 starts at block 1, but on larger block sizes it starts on
+ block 0. For more information, see the
+ <a class="link" href="#s-first-data-block" title="s_first_data_block">s_first_data_block</a> superblock
+ entry.
+ </p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="superblock"></a>Superblock</h2></div></div></div><p>
+ The <a class="link" href="#def-superblock" title="Superblocks">superblock</a> is always located at
+ byte offset 1024 from the beginning of the file, block device or
+ partition formatted with Ext2 and later variants (Ext3, Ext4).
+ </p><p>
+ Its structure is mostly constant from Ext2 to Ext3 and Ext4 with only
+ some minor changes.
+ </p><div class="table"><a id="superblock-structure"></a><p class="title"><strong>Table 3.3. Superblock Structure</strong></p><div class="table-contents"><table summary="Superblock Structure" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>4</td><td><a class="link" href="#s-inodes-count" title="s_inodes_count">s_inodes_count</a></td></tr><tr><td>4</td><td>4</td><td><a class="link" href="#s-blocks-count" title="s_blocks_count">s_blocks_count</a></td></tr><tr><td>8</td><td>4</td><td><a class="link" href="#s-r-blocks-count" title="s_r_blocks_count">s_r_blocks_count</a></td></tr><tr><td>12</td><td>4</td><td><a class="link" href="#s-free-blocks-count" title="s_free_blocks_count">s_free_blocks_count</a></td></tr><tr><td>16</td><td>4</td><td><a class="link" href="#s-free-inodes-count" title="s_free_inodes_count">s_free_inodes_count</a></td></tr><tr><td>20</td><td>4</td><td><a class="link" href="#s-first-data-block" title="s_first_data_block">s_first_data_block</a></td></tr><tr><td>24</td><td>4</td><td><a class="link" href="#s-log-block-size" title="s_log_block_size">s_log_block_size</a></td></tr><tr><td>28</td><td>4</td><td><a class="link" href="#s-log-frag-size" title="s_log_frag_size">s_log_frag_size</a></td></tr><tr><td>32</td><td>4</td><td><a class="link" href="#s-blocks-per-group" title="s_blocks_per_group">s_blocks_per_group</a></td></tr><tr><td>36</td><td>4</td><td><a class="link" href="#s-frags-per-group" title="s_frags_per_group">s_frags_per_group</a></td></tr><tr><td>40</td><td>4</td><td><a class="link" href="#s-inodes-per-group" title="s_inodes_per_group">s_inodes_per_group</a></td></tr><tr><td>44</td><td>4</td><td><a class="link" href="#s-mtime" title="s_mtime">s_mtime</a></td></tr><tr><td>48</td><td>4</td><td><a class="link" href="#s-wtime" title="s_wtime">s_wtime</a></td></tr><tr><td>52</td><td>2</td><td><a class="link" href="#s-mnt-count" title="s_mnt_count">s_mnt_count</a></td></tr><tr><td>54</td><td>2</td><td><a class="link" href="#s-max-mnt-count" title="s_max_mnt_count">s_max_mnt_count</a></td></tr><tr><td>56</td><td>2</td><td><a class="link" href="#s-magic" title="s_magic">s_magic</a></td></tr><tr><td>58</td><td>2</td><td><a class="link" href="#s-state" title="s_state">s_state</a></td></tr><tr><td>60</td><td>2</td><td><a class="link" href="#s-errors" title="s_errors">s_errors</a></td></tr><tr><td>62</td><td>2</td><td><a class="link" href="#s-minor-rev-level" title="s_minor_rev_level">s_minor_rev_level</a></td></tr><tr><td>64</td><td>4</td><td><a class="link" href="#s-lastcheck" title="s_lastcheck">s_lastcheck</a></td></tr><tr><td>68</td><td>4</td><td><a class="link" href="#s-checkinterval" title="s_checkinterval">s_checkinterval</a></td></tr><tr><td>72</td><td>4</td><td><a class="link" href="#s-creator-os" title="s_creator_os">s_creator_os</a></td></tr><tr><td>76</td><td>4</td><td><a class="link" href="#s-rev-level" title="s_rev_level">s_rev_level</a></td></tr><tr><td>80</td><td>2</td><td><a class="link" href="#s-def-resuid" title="s_def_resuid">s_def_resuid</a></td></tr><tr><td>82</td><td>2</td><td><a class="link" href="#s-def-resgid" title="s_def_resgid">s_def_resgid</a></td></tr><tr><td colspan="3" align="left">-- EXT2_DYNAMIC_REV Specific --</td></tr><tr><td>84</td><td>4</td><td><a class="link" href="#s-first-ino" title="s_first_ino">s_first_ino</a></td></tr><tr><td>88</td><td>2</td><td><a class="link" href="#s-inode-size" title="s_inode_size">s_inode_size</a></td></tr><tr><td>90</td><td>2</td><td><a class="link" href="#s-block-group-nr" title="s_block_group_nr">s_block_group_nr</a></td></tr><tr><td>92</td><td>4</td><td><a class="link" href="#s-feature-compat" title="s_feature_compat">s_feature_compat</a></td></tr><tr><td>96</td><td>4</td><td><a class="link" href="#s-feature-incompat" title="s_feature_incompat">s_feature_incompat</a></td></tr><tr><td>100</td><td>4</td><td><a class="link" href="#s-feature-ro-compat" title="s_feature_ro_compat">s_feature_ro_compat</a></td></tr><tr><td>104</td><td>16</td><td><a class="link" href="#s-uuid" title="s_uuid">s_uuid</a></td></tr><tr><td>120</td><td>16</td><td><a class="link" href="#s-volume-name" title="s_volume_name">s_volume_name</a></td></tr><tr><td>136</td><td>64</td><td><a class="link" href="#s-last-mounted" title="s_last_mounted">s_last_mounted</a></td></tr><tr><td>200</td><td>4</td><td><a class="link" href="#s-algo-bitmap" title="s_algo_bitmap">s_algo_bitmap</a></td></tr><tr><td colspan="3" align="left">-- Performance Hints --</td></tr><tr><td>204</td><td>1</td><td><a class="link" href="#s-prealloc-blocks" title="s_prealloc_blocks">s_prealloc_blocks</a></td></tr><tr><td>205</td><td>1</td><td><a class="link" href="#s-prealloc-dir-blocks" title="s_prealloc_dir_blocks">s_prealloc_dir_blocks</a></td></tr><tr><td>206</td><td>2</td><td>(alignment)</td></tr><tr><td colspan="3" align="left">-- Journaling Support --</td></tr><tr><td>208</td><td>16</td><td><a class="link" href="#s-journal-uuid" title="s_journal_uuid">s_journal_uuid</a></td></tr><tr><td>224</td><td>4</td><td><a class="link" href="#s-journal-inum" title="s_journal_inum">s_journal_inum</a></td></tr><tr><td>228</td><td>4</td><td><a class="link" href="#s-journal-dev" title="s_journal_dev">s_journal_dev</a></td></tr><tr><td>232</td><td>4</td><td><a class="link" href="#s-last-orphan" title="s_last_orphan">s_last_orphan</a></td></tr><tr><td colspan="3" align="left">-- Directory Indexing Support --</td></tr><tr><td>236</td><td>4 x 4</td><td><a class="link" href="#s-hash-seed" title="s_hash_seed">s_hash_seed</a></td></tr><tr><td>252</td><td>1</td><td><a class="link" href="#s-def-hash-version" title="s_def_hash_version">s_def_hash_version</a></td></tr><tr><td>253</td><td>3</td><td>padding - reserved for future expansion</td></tr><tr><td colspan="3" align="left">-- Other options --</td></tr><tr><td>256</td><td>4</td><td><a class="link" href="#s-default-mount-options" title="s_default_mount_options">s_default_mount_options</a></td></tr><tr><td>260</td><td>4</td><td><a class="link" href="#s-first-meta-bg" title="s_first_meta_bg">s_first_meta_bg</a></td></tr><tr><td>264</td><td>760</td><td>Unused - reserved for future revisions</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-inodes-count"></a>s_inodes_count</h3></div></div></div><p>
+ 32bit value indicating the total number of inodes, both used and free,
+ in the file system. This value must be lower or equal to
+ (s_inodes_per_group * number of block groups). It must be equal to the
+ sum of the inodes defined in each block group.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-blocks-count"></a>s_blocks_count</h3></div></div></div><p>
+ 32bit value indicating the total number of blocks in the system including
+ all used, free and reserved. This value must be lower or equal to
+ (s_blocks_per_group * number of block groups). It can be lower than
+ the previous calculation if the last block group has a smaller number of
+ blocks than s_blocks_per_group du to volume size. It must be equal to
+ the sum of the blocks defined in each block group.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-r-blocks-count"></a>s_r_blocks_count</h3></div></div></div><p>
+ 32bit value indicating the total number of blocks reserved for the
+ usage of the super user. This is most useful if for some reason a
+ user, maliciously or not, fill the file system to capacity; the super
+ user will have this specified amount of free blocks at his disposal so
+ he can edit and save configuration files.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-free-blocks-count"></a>s_free_blocks_count</h3></div></div></div><p>
+ 32bit value indicating the total number of free blocks, including the
+ number of reserved blocks (see
+ <a class="link" href="#s-r-blocks-count" title="s_r_blocks_count">s_r_blocks_count</a>). This is a sum
+ of all free blocks of all the block groups.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-free-inodes-count"></a>s_free_inodes_count</h3></div></div></div><p>
+ 32bit value indicating the total number of free inodes. This is a sum
+ of all free inodes of all the block groups.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-first-data-block"></a>s_first_data_block</h3></div></div></div><p>
+ 32bit value identifying the first data block, in other word the id of
+ the block containing the <span class="structname">superblock</span> structure.
+ </p><p>
+ Note that this value is always 0 for file systems with a block size
+ larger than 1KB, and always 1 for file systems with a block size of
+ 1KB. The <span class="structname">superblock</span> is <span class="emphasis"><em>always</em></span> starting at
+ the 1024th byte of the disk, which normally happens to be the first
+ byte of the 3rd sector.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-log-block-size"></a>s_log_block_size</h3></div></div></div><p>
+ The block size is computed using this 32bit value as the number of
+ bits to shift left the value 1024. This value may only be non-negative.
+ </p><pre class="programlisting">
+block size = 1024 &lt;&lt; s_log_block_size;
+ </pre><p>
+ Common block sizes include 1KiB, 2KiB, 4KiB and 8Kib. For information
+ about the impact of selecting a block size, see
+ <a class="link" href="#block-size-impact" title="Table 2.1. Impact of Block Sizes">Impact of Block Sizes</a>.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ In Linux, at least up to 2.6.28, the block size must be at least as
+ large as the sector size of the block device, and cannot be larger than
+ the supported memory page of the architecture.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-log-frag-size"></a>s_log_frag_size</h3></div></div></div><p>
+ The fragment size is computed using this 32bit value as the number of
+ bits to shift left the value 1024. Note that a negative value would
+ shift the bit right rather than left.
+ </p><pre class="programlisting">
+if( positive )
+ fragmnet size = 1024 &lt;&lt; s_log_frag_size;
+else
+ framgnet size = 1024 &gt;&gt; -s_log_frag_size;
+ </pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ As of Linux 2.6.28 no support exists for an Ext2
+ partition with fragment size smaller than the block size, as this feature
+ seems to not be available.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-blocks-per-group"></a>s_blocks_per_group</h3></div></div></div><p>
+ 32bit value indicating the total number of blocks per group. This
+ value in combination with
+ <a class="link" href="#s-first-data-block" title="s_first_data_block">s_first_data_block</a> can be used
+ to determine the block groups boundaries. Due to volume size boundaries,
+ the last block group might have a smaller number of blocks than what is
+ specified in this field.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-frags-per-group"></a>s_frags_per_group</h3></div></div></div><p>
+ 32bit value indicating the total number of fragments per group. It is
+ also used to determine the size of the <span class="structname">block bitmap</span> of
+ each block group.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-inodes-per-group"></a>s_inodes_per_group</h3></div></div></div><p>
+ 32bit value indicating the total number of inodes per group. This is
+ also used to determine the size of the <span class="structname">inode bitmap</span> of
+ each block group. Note that you cannot have more than
+ (block size in bytes * 8) inodes per group as the inode bitmap
+ must fit within a single block. This value must be a perfect multiple
+ of the number of inodes that can fit in a block
+ ((1024&lt;&lt;s_log_block_size)/s_inode_size).
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-mtime"></a>s_mtime</h3></div></div></div><p>
+ Unix time, as defined by POSIX, of the last time the file system was
+ mounted.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-wtime"></a>s_wtime</h3></div></div></div><p>
+ Unix time, as defined by POSIX, of the last write access to the file
+ system.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-mnt-count"></a>s_mnt_count</h3></div></div></div><p>
+ 16bit value indicating how many time the file system was mounted
+ since the last time it was fully verified.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-max-mnt-count"></a>s_max_mnt_count</h3></div></div></div><p>
+ 16bit value indicating the maximum number of times that the file
+ system may be mounted before a full check is performed.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-magic"></a>s_magic</h3></div></div></div><p>
+ 16bit value identifying the file system as Ext2. The value is
+ currently fixed to <code class="constant">EXT2_SUPER_MAGIC</code> of value 0xEF53.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-state"></a>s_state</h3></div></div></div><p>
+ 16bit value indicating the file system state. When the file system is
+ mounted, this state is set to <code class="constant">EXT2_ERROR_FS</code>. After the
+ file system was cleanly unmounted, this value is set to <code class="constant">EXT2_VALID_FS</code>.
+ </p><p>
+ When mounting the file system, if a valid of <code class="constant">EXT2_ERROR_FS</code> is
+ encountered it means the file system was not cleanly unmounted and most
+ likely contain errors that will need to be fixed. Typically under Linux
+ this means running fsck.
+ </p><div class="table"><a id="s-state-values"></a><p class="title"><strong>Table 3.4. Defined s_state Values</strong></p><div class="table-contents"><table summary="Defined s_state Values" width="100%" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">EXT2_VALID_FS</td><td align="left">1</td><td align="left">Unmounted cleanly</td></tr><tr><td align="left">EXT2_ERROR_FS</td><td align="left">2</td><td align="left">Errors detected</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-errors"></a>s_errors</h3></div></div></div><p>
+ 16bit value indicating what the file system driver should do when an
+ error is detected. The following values have been defined:
+ </p><div class="table"><a id="ext2-errors"></a><p class="title"><strong>Table 3.5. Defined s_errors Values</strong></p><div class="table-contents"><table summary="Defined s_errors Values" width="100%" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">EXT2_ERRORS_CONTINUE</td><td align="left">1</td><td align="left">continue as if nothing happened</td></tr><tr><td align="left">EXT2_ERRORS_RO</td><td align="left">2</td><td align="left">remount read-only</td></tr><tr><td align="left">EXT2_ERRORS_PANIC</td><td align="left">3</td><td align="left">cause a kernel panic</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-minor-rev-level"></a>s_minor_rev_level</h3></div></div></div><p>
+ 16bit value identifying the minor revision level within its
+ <a class="link" href="#s-rev-level" title="s_rev_level">revision level</a>.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-lastcheck"></a>s_lastcheck</h3></div></div></div><p>
+ Unix time, as defined by POSIX, of the last file system check.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-checkinterval"></a>s_checkinterval</h3></div></div></div><p>
+ Maximum Unix time interval, as defined by POSIX, allowed between file
+ system checks.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-creator-os"></a>s_creator_os</h3></div></div></div><p>
+ 32bit identifier of the os that created the file system. Defined
+ values are:
+ </p><div class="table"><a id="s-creator-os-values"></a><p class="title"><strong>Table 3.6. Defined s_creator_os Values</strong></p><div class="table-contents"><table summary="Defined s_creator_os Values" width="100%" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">EXT2_OS_LINUX</td><td align="left">0</td><td align="left">Linux</td></tr><tr><td align="left">EXT2_OS_HURD</td><td align="left">1</td><td align="left">GNU HURD</td></tr><tr><td align="left">EXT2_OS_MASIX</td><td align="left">2</td><td align="left">MASIX</td></tr><tr><td align="left">EXT2_OS_FREEBSD</td><td align="left">3</td><td align="left">FreeBSD</td></tr><tr><td align="left">EXT2_OS_LITES</td><td align="left">4</td><td align="left">Lites</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-rev-level"></a>s_rev_level</h3></div></div></div><p>
+ 32bit revision level value.
+ </p><div class="table"><a id="s-rev-level-values"></a><p class="title"><strong>Table 3.7. Defined s_rev_level Values</strong></p><div class="table-contents"><table summary="Defined s_rev_level Values" width="100%" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">EXT2_GOOD_OLD_REV</td><td align="left">0</td><td align="left">Revision 0</td></tr><tr><td align="left">EXT2_DYNAMIC_REV</td><td align="left">1</td><td align="left">Revision 1 with variable inode sizes, extended attributes, etc.</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-def-resuid"></a>s_def_resuid</h3></div></div></div><p>
+ 16bit value used as the default user id for reserved blocks.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ In Linux this defaults to <code class="constant">EXT2_DEF_RESUID</code> of 0.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-def-resgid"></a>s_def_resgid</h3></div></div></div><p>
+ 16bit value used as the default group id for reserved blocks.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ In Linux this defaults to <code class="constant">EXT2_DEF_RESGID</code> of 0.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-first-ino"></a>s_first_ino</h3></div></div></div><p>
+ 32bit value used as index to the first inode useable for standard
+ files. In revision 0, the first non-reserved inode is fixed to
+ 11 (<code class="constant">EXT2_GOOD_OLD_FIRST_INO</code>). In revision 1 and later
+ this value may be set to any value.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-inode-size"></a>s_inode_size</h3></div></div></div><p>
+ 16bit value indicating the size of the inode structure. In revision 0, this
+ value is always 128 (<code class="constant">EXT2_GOOD_OLD_INODE_SIZE</code>). In revision 1
+ and later, this value must be a perfect power of 2 and must be smaller or
+ equal to the block size (1&lt;&lt;s_log_block_size).
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-block-group-nr"></a>s_block_group_nr</h3></div></div></div><p>
+ 16bit value used to indicate the block group number hosting this
+ superblock structure. This can be used to rebuild the file system
+ from any superblock backup.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-feature-compat"></a>s_feature_compat</h3></div></div></div><p>
+ 32bit bitmask of compatible features. The file system implementation
+ is free to support them or not without risk of damaging the meta-data.
+ </p><div class="table"><a id="s-feature-compat-values"></a><p class="title"><strong>Table 3.8. Defined s_feature_compat Values</strong></p><div class="table-contents"><table summary="Defined s_feature_compat Values" width="100%" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td colspan="3" align="left">EXT2_FEATURE_COMPAT_DIR_PREALLOC</td></tr><tr><td align="left"> </td><td align="left">0x0001</td><td align="left">Block pre-allocation for new directories</td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_COMPAT_IMAGIC_INODES</td></tr><tr><td align="left"> </td><td align="left">0x0002</td><td align="left"> </td></tr><tr><td colspan="3" align="left">EXT3_FEATURE_COMPAT_HAS_JOURNAL</td></tr><tr><td align="left"> </td><td align="left">0x0004</td><td align="left">An Ext3 journal exists</td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_COMPAT_EXT_ATTR</td></tr><tr><td align="left"> </td><td align="left">0x0008</td><td align="left">Extended inode attributes are present</td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_COMPAT_RESIZE_INO</td></tr><tr><td align="left"> </td><td align="left">0x0010</td><td align="left">Non-standard inode size used</td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_COMPAT_DIR_INDEX</td></tr><tr><td align="left"> </td><td align="left">0x0020</td><td align="left">Directory indexing (HTree)</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-feature-incompat"></a>s_feature_incompat</h3></div></div></div><p>
+ 32bit bitmask of incompatible features. The file system
+ implementation should refuse to mount the file system if any of
+ the indicated feature is unsupported.
+ </p><p>
+ An implementation not supporting these features would be unable to
+ properly use the file system. For example, if compression is being
+ used and an executable file would be unusable after being read from
+ the disk if the system does not know how to uncompress it.
+ </p><div class="table"><a id="s-feature-incompat-values"></a><p class="title"><strong>Table 3.9. Defined s_feature_incompat Values</strong></p><div class="table-contents"><table summary="Defined s_feature_incompat Values" width="100%" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td colspan="3" align="left">EXT2_FEATURE_INCOMPAT_COMPRESSION</td></tr><tr><td align="left"> </td><td align="left">0x0001</td><td align="left">Disk/File compression is used</td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_INCOMPAT_FILETYPE</td></tr><tr><td align="left"> </td><td align="left">0x0002</td><td align="left"> </td></tr><tr><td colspan="3" align="left">EXT3_FEATURE_INCOMPAT_RECOVER</td></tr><tr><td align="left"> </td><td align="left">0x0004</td><td align="left"> </td></tr><tr><td colspan="3" align="left">EXT3_FEATURE_INCOMPAT_JOURNAL_DEV</td></tr><tr><td align="left"> </td><td align="left">0x0008</td><td align="left"> </td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_INCOMPAT_META_BG</td></tr><tr><td align="left"> </td><td align="left">0x0010</td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-feature-ro-compat"></a>s_feature_ro_compat</h3></div></div></div><p>
+ 32bit bitmask of <span class="quote">“<span class="quote">read-only</span>”</span> features. The file system
+ implementation should mount as read-only if any of the indicated
+ feature is unsupported.
+ </p><div class="table"><a id="s-feature-ro-compat-values"></a><p class="title"><strong>Table 3.10. Defined s_feature_ro_compat Values</strong></p><div class="table-contents"><table summary="Defined s_feature_ro_compat Values" width="100%" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td colspan="3" align="left">EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER</td></tr><tr><td align="left"> </td><td align="left">0x0001</td><td align="left">Sparse Superblock</td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_RO_COMPAT_LARGE_FILE</td></tr><tr><td align="left"> </td><td align="left">0x0002</td><td align="left">Large file support, 64-bit file size</td></tr><tr><td colspan="3" align="left">EXT2_FEATURE_RO_COMPAT_BTREE_DIR</td></tr><tr><td align="left"> </td><td align="left">0x0004</td><td align="left">Binary tree sorted directory files</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-uuid"></a>s_uuid</h3></div></div></div><p>
+ 128bit value used as the volume id. This should, as much as possible,
+ be unique for each file system formatted.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-volume-name"></a>s_volume_name</h3></div></div></div><p>
+ 16 bytes volume name, mostly unusued. A valid volume name would consist
+ of only ISO-Latin-1 characters and be 0 terminated.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-last-mounted"></a>s_last_mounted</h3></div></div></div><p>
+ 64 bytes directory path where the file system was last mounted. While
+ not normally used, it could serve for auto-finding the mountpoint when
+ not indicated on the command line. Again the path should be zero
+ terminated for compatibility reasons. Valid path is constructed from
+ ISO-Latin-1 characters.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-algo-bitmap"></a>s_algo_bitmap</h3></div></div></div><p>
+ 32bit value used by compression algorithms to determine the compression
+ method(s) used.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Compression is supported in Linux 2.4 and 2.6 via the e2compr patch. For
+ more information, visit http://e2compr.sourceforge.net/
+ </p></div><div class="table"><a id="s-algo-bitmap-values"></a><p class="title"><strong>Table 3.11. Defined s_algo_bitmap Values</strong></p><div class="table-contents"><table summary="Defined s_algo_bitmap Values" width="100%" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Bit Number</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">EXT2_LZV1_ALG</td><td align="left">0</td><td align="left">Binary value of 0x00000001</td></tr><tr><td align="left">EXT2_LZRW3A_ALG</td><td align="left">1</td><td align="left">Binary value of 0x00000002</td></tr><tr><td align="left">EXT2_GZIP_ALG</td><td align="left">2</td><td align="left">Binary value of 0x00000004</td></tr><tr><td align="left">EXT2_BZIP2_ALG</td><td align="left">3</td><td align="left">Binary value of 0x00000008</td></tr><tr><td align="left">EXT2_LZO_ALG</td><td align="left">4</td><td align="left">Binary value of 0x00000010</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-prealloc-blocks"></a>s_prealloc_blocks</h3></div></div></div><p>
+ 8-bit value representing the number of blocks the implementation should
+ attempt to pre-allocate when creating a new regular file.
+ </p><p>
+ Linux 2.6.28 will only perform pre-allocation using Ext4 although no
+ problem is expected if any version of Linux encounters a file with more
+ blocks present than required.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-prealloc-dir-blocks"></a>s_prealloc_dir_blocks</h3></div></div></div><p>
+ 8-bit value representing the number of blocks the implementation should
+ attempt to pre-allocate when creating a new directory.
+ </p><p>
+ Linux 2.6.28 will only perform pre-allocation using Ext4 and only if
+ the <code class="constant">EXT4_FEATURE_COMPAT_DIR_PREALLOC</code> flag is present. Since
+ Linux does not de-allocate blocks from directories after they were
+ allocated, it should be safe to perform pre-allocation and maintain
+ compatibility with Linux.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-journal-uuid"></a>s_journal_uuid</h3></div></div></div><p>
+ 16-byte value containing the uuid of the journal superblock. See Ext3
+ Journaling for more information.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-journal-inum"></a>s_journal_inum</h3></div></div></div><p>
+ 32-bit inode number of the journal file. See Ext3 Journaling for more
+ information.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-journal-dev"></a>s_journal_dev</h3></div></div></div><p>
+ 32-bit device number of the journal file. See Ext3 Journaling for more
+ information.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-last-orphan"></a>s_last_orphan</h3></div></div></div><p>
+ 32-bit inode number, pointing to the first inode in the list of inodes
+ to delete. See Ext3 Journaling for more information.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-hash-seed"></a>s_hash_seed</h3></div></div></div><p>
+ An array of 4 32bit values containing the seeds used for the hash
+ algorithm for directory indexing.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-def-hash-version"></a>s_def_hash_version</h3></div></div></div><p>
+ An 8bit value containing the default hash version used for directory indexing.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-default-mount-options"></a>s_default_mount_options</h3></div></div></div><p>
+ A 32bit value containing the default mount options for this file system. TODO: Add more information here!
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="s-first-meta-bg"></a>s_first_meta_bg</h3></div></div></div><p>
+ A 32bit value indicating the block group ID of the first meta block group. TODO: Research if this is an Ext3-only extension.
+ </p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="block-group-descriptor-table"></a>Block Group Descriptor Table</h2></div></div></div><p>
+ The block group descriptor table is an array of
+ <a class="link" href="#block-group-descriptor-structure" title="Table 3.12. Block Group Descriptor Structure">block group descriptor</a>,
+ used to define parameters of all the
+ <a class="link" href="#def-block-groups" title="Block Groups">block groups</a>. It provides the location
+ of the inode bitmap and inode table, block bitmap, number of free blocks and
+ inodes, and some other useful information.
+ </p><p>
+ The block group descriptor table starts on the first block following the
+ superblock. This would be the third block on a 1KiB block file system, or the
+ second block for 2KiB and larger block file systems. Shadow copies of the
+ block group descriptor table are also stored with every copy of the
+ superblock.
+ </p><p>
+ Depending on how many block groups are defined, this table can require
+ multiple blocks of storage. Always refer to the superblock in case of
+ doubt.
+ </p><p>
+ The layout of a block group descriptor is as follows:
+ </p><div class="table"><a id="block-group-descriptor-structure"></a><p class="title"><strong>Table 3.12. Block Group Descriptor Structure</strong></p><div class="table-contents"><table summary="Block Group Descriptor Structure" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>4</td><td><a class="link" href="#bg-block-bitmap" title="bg_block_bitmap">bg_block_bitmap</a></td></tr><tr><td>4</td><td>4</td><td><a class="link" href="#bg-inode-bitmap" title="bg_inode_bitmap">bg_inode_bitmap</a></td></tr><tr><td>8</td><td>4</td><td><a class="link" href="#bg-inode-table" title="bg_inode_table">bg_inode_table</a></td></tr><tr><td>12</td><td>2</td><td><a class="link" href="#bg-free-blocks-count" title="bg_free_blocks_count">bg_free_blocks_count</a></td></tr><tr><td>14</td><td>2</td><td><a class="link" href="#bg-free-inodes-count" title="bg_free_inodes_count">bg_free_inodes_count</a></td></tr><tr><td>16</td><td>2</td><td><a class="link" href="#bg-used-dirs-count" title="bg_used_dirs_count">bg_used_dirs_count</a></td></tr><tr><td>18</td><td>2</td><td><a class="link" href="#bg-pad" title="bg_pad">bg_pad</a></td></tr><tr><td>20</td><td>12</td><td><a class="link" href="#bg-reserved" title="bg_reserved">bg_reserved</a></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For each block group in the file system, such a <span class="structname">group_desc</span> is
+ created. Each represent a single block group within the
+ file system and the information within any one of them is pertinent
+ only to the group it is describing. Every block group descriptor table
+ contains all the information about all the block groups.
+ </p><p>
+ NOTE: All indicated <span class="quote">“<span class="quote">block id</span>”</span> are absolute.
+ </p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-block-bitmap"></a>bg_block_bitmap</h3></div></div></div><p>
+ 32bit block id of the first block of the
+ <span class="quote">“<span class="quote"><a class="link" href="#block-bitmap" title="Block Bitmap">block bitmap</a></span>”</span>
+ for the group represented.
+ </p><p>
+ The actual block bitmap is located within its own allocated blocks
+ starting at the block ID specified by this value.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-inode-bitmap"></a>bg_inode_bitmap</h3></div></div></div><p>
+ 32bit block id of the first block of the
+ <span class="quote">“<span class="quote"><a class="link" href="#inode-bitmap" title="Inode Bitmap">inode bitmap</a></span>”</span>
+ for the group represented.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-inode-table"></a>bg_inode_table</h3></div></div></div><p>
+ 32bit block id of the first block of the
+ <span class="quote">“<span class="quote"><a class="link" href="#inode-table" title="Inode Table">inode table</a></span>”</span>
+ for the group represented.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-free-blocks-count"></a>bg_free_blocks_count</h3></div></div></div><p>
+ 16bit value indicating the total number of free blocks for
+ the represented group.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-free-inodes-count"></a>bg_free_inodes_count</h3></div></div></div><p>
+ 16bit value indicating the total number of free inodes for
+ the represented group.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-used-dirs-count"></a>bg_used_dirs_count</h3></div></div></div><p>
+ 16bit value indicating the number of inodes allocated to
+ directories for the represented group.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-pad"></a>bg_pad</h3></div></div></div><p>
+ 16bit value used for padding the structure on a 32bit boundary.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="bg-reserved"></a>bg_reserved</h3></div></div></div><p>
+ 12 bytes of reserved space for future revisions.
+ </p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="block-bitmap"></a>Block Bitmap</h2></div></div></div><p>
+ On small file systems, the <span class="quote">“<span class="quote">Block Bitmap</span>”</span> is normally located
+ at the first block, or second block if a superblock backup is present,
+ of each block group. Its official location can be determined by reading the
+ <span class="quote">“<span class="quote"><a class="link" href="#bg-block-bitmap" title="bg_block_bitmap">bg_block_bitmap</a></span>”</span>
+ in its associated <a class="link" href="#block-group-descriptor-table" title="Block Group Descriptor Table">group descriptor</a>.
+ </p><p>
+ Each bit represent the current state of a block within that block group,
+ where 1 means <span class="quote">“<span class="quote">used</span>”</span> and 0 <span class="quote">“<span class="quote">free/available</span>”</span>. The
+ first block of this block group is represented by bit 0 of byte 0,
+ the second by bit 1 of byte 0. The 8th block is represented by bit 7
+ (most significant bit) of byte 0 while the 9th block is represented by
+ bit 0 (least significant bit) of byte 1.
+ </p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="inode-bitmap"></a>Inode Bitmap</h2></div></div></div><p>
+ The <span class="quote">“<span class="quote">Inode Bitmap</span>”</span> works in a similar way as the
+ <span class="quote">“<span class="quote"><a class="link" href="#block-bitmap" title="Block Bitmap">Block Bitmap</a></span>”</span>,
+ difference being in each bit representing an inode in the
+ <span class="quote">“<span class="quote"><a class="link" href="#inode-table" title="Inode Table">Inode Table</a></span>”</span> rather
+ than a block. Since inode numbers start from 1 rather than 0, the
+ first bit in the first block group's inode bitmap represent inode
+ number 1.
+ </p><p>
+ There is one inode bitmap per group and its location may be
+ determined by reading the
+ <span class="quote">“<span class="quote"><a class="link" href="#bg-inode-bitmap" title="bg_inode_bitmap">bg_inode_bitmap</a></span>”</span>
+ in its associated <a class="link" href="#block-group-descriptor-table" title="Block Group Descriptor Table">group descriptor</a>.
+ </p><p>
+ When the inode table is created, all the reserved inodes are marked
+ as used. In revision 0 this is the first 11 inodes.
+ </p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="inode-table"></a>Inode Table</h2></div></div></div><p>
+ The inode table is used to keep track of every directory,
+ regular file, symbolic link, or special file; their
+ location, size, type and access rights are all stored in inodes. There
+ is no filename stored in the inode itself, names are contained in
+ <a class="link" href="#directory" title="Chapter 4. Directory Structure">directory</a> files only.
+ </p><p>
+ There is one inode table per block group and it can be located by reading the
+ <a class="link" href="#bg-inode-table" title="bg_inode_table">bg_inode_table</a>
+ in its associated <a class="link" href="#block-group-descriptor-table" title="Block Group Descriptor Table">group descriptor</a>.
+ There are <a class="link" href="#s-inodes-per-group" title="s_inodes_per_group">s_inodes_per_group</a>
+ inodes per table.
+ </p><p>
+ Each inode contain the information about a single physical file on the
+ system. A file can be a directory, a socket, a buffer, character or
+ block device, symbolic link or a regular file. So an inode can be
+ seen as a block of information related to an entity, describing its
+ location on disk, its size and its owner. An inode looks like this:
+ </p><div class="table"><a id="inode-structure"></a><p class="title"><strong>Table 3.13. Inode Structure</strong></p><div class="table-contents"><table summary="Inode Structure" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>2</td><td><a class="link" href="#i-mode" title="i_mode">i_mode</a></td></tr><tr><td>2</td><td>2</td><td><a class="link" href="#i-uid" title="i_uid">i_uid</a></td></tr><tr><td>4</td><td>4</td><td><a class="link" href="#i-size" title="i_size">i_size</a></td></tr><tr><td>8</td><td>4</td><td><a class="link" href="#i-atime" title="i_atime">i_atime</a></td></tr><tr><td>12</td><td>4</td><td><a class="link" href="#i-ctime" title="i_ctime">i_ctime</a></td></tr><tr><td>16</td><td>4</td><td><a class="link" href="#i-mtime" title="i_mtime">i_mtime</a></td></tr><tr><td>20</td><td>4</td><td><a class="link" href="#i-dtime" title="i_dtime">i_dtime</a></td></tr><tr><td>24</td><td>2</td><td><a class="link" href="#i-gid" title="i_gid">i_gid</a></td></tr><tr><td>26</td><td>2</td><td><a class="link" href="#i-links-count" title="i_links_count">i_links_count</a></td></tr><tr><td>28</td><td>4</td><td><a class="link" href="#i-blocks" title="i_blocks">i_blocks</a></td></tr><tr><td>32</td><td>4</td><td><a class="link" href="#i-flags" title="i_flags">i_flags</a></td></tr><tr><td>36</td><td>4</td><td><a class="link" href="#i-osd1" title="i_osd1">i_osd1</a></td></tr><tr><td>40</td><td>15 x 4</td><td><a class="link" href="#i-block" title="i_block">i_block</a></td></tr><tr><td>100</td><td>4</td><td><a class="link" href="#i-generation" title="i_generation">i_generation</a></td></tr><tr><td>104</td><td>4</td><td><a class="link" href="#i-file-acl" title="i_file_acl">i_file_acl</a></td></tr><tr><td>108</td><td>4</td><td><a class="link" href="#i-dir-acl" title="i_dir_acl">i_dir_acl</a></td></tr><tr><td>112</td><td>4</td><td><a class="link" href="#i-faddr" title="i_faddr">i_faddr</a></td></tr><tr><td>116</td><td>12</td><td><a class="link" href="#i-osd2" title="Inode i_osd2 Structure">i_osd2</a></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The first few entries of the inode tables are reserved. In revision
+ 0 there are 11 entries reserved while in revision 1
+ (EXT2_DYNAMIC_REV) and later the number of reserved inodes entries is
+ specified in the <a class="link" href="#s-first-ino" title="s_first_ino">s_first_ino</a> of the
+ superblock structure. Here's a listing of the known reserved inode
+ entries:
+ </p><div class="table"><a id="reserved-inodes-values"></a><p class="title"><strong>Table 3.14. Defined Reserved Inodes</strong></p><div class="table-contents"><table summary="Defined Reserved Inodes" width="100%" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">EXT2_BAD_INO</td><td align="left">1</td><td align="left">bad blocks inode</td></tr><tr><td align="left">EXT2_ROOT_INO</td><td align="left">2</td><td align="left">root directory inode</td></tr><tr><td align="left">EXT2_ACL_IDX_INO</td><td align="left">3</td><td align="left">ACL index inode (deprecated?)</td></tr><tr><td align="left">EXT2_ACL_DATA_INO</td><td align="left">4</td><td align="left">ACL data inode (deprecated?)</td></tr><tr><td align="left">EXT2_BOOT_LOADER_INO</td><td align="left">5</td><td align="left">boot loader inode</td></tr><tr><td align="left">EXT2_UNDEL_DIR_INO</td><td align="left">6</td><td align="left">undelete directory inode</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-mode"></a>i_mode</h3></div></div></div><p>
+ 16bit value used to indicate the format of the described file and the
+ access rights. Here are the possible values, which can be combined
+ in various ways:
+ </p><div class="table"><a id="idm140660447480672"></a><p class="title"><strong>Table 3.15. Defined i_mode Values</strong></p><div class="table-contents"><table summary="Defined i_mode Values" width="100%" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /></colgroup><thead><tr><th align="left">Constant</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td colspan="3" align="left">-- file format --</td></tr><tr><td align="left">EXT2_S_IFSOCK</td><td align="left">0xC000</td><td align="left">socket</td></tr><tr><td align="left">EXT2_S_IFLNK</td><td align="left">0xA000</td><td align="left">symbolic link</td></tr><tr><td align="left">EXT2_S_IFREG</td><td align="left">0x8000</td><td align="left">regular file</td></tr><tr><td align="left">EXT2_S_IFBLK</td><td align="left">0x6000</td><td align="left">block device</td></tr><tr><td align="left">EXT2_S_IFDIR</td><td align="left">0x4000</td><td align="left">directory</td></tr><tr><td align="left">EXT2_S_IFCHR</td><td align="left">0x2000</td><td align="left">character device</td></tr><tr><td align="left">EXT2_S_IFIFO</td><td align="left">0x1000</td><td align="left">fifo</td></tr><tr><td colspan="3" align="left">-- process execution user/group override --</td></tr><tr><td align="left">EXT2_S_ISUID</td><td align="left">0x0800</td><td align="left">Set process User ID</td></tr><tr><td align="left">EXT2_S_ISGID</td><td align="left">0x0400</td><td align="left">Set process Group ID</td></tr><tr><td align="left">EXT2_S_ISVTX</td><td align="left">0x0200</td><td align="left">sticky bit</td></tr><tr><td colspan="3" align="left">-- access rights --</td></tr><tr><td align="left">EXT2_S_IRUSR</td><td align="left">0x0100</td><td align="left">user read</td></tr><tr><td align="left">EXT2_S_IWUSR</td><td align="left">0x0080</td><td align="left">user write</td></tr><tr><td align="left">EXT2_S_IXUSR</td><td align="left">0x0040</td><td align="left">user execute</td></tr><tr><td align="left">EXT2_S_IRGRP</td><td align="left">0x0020</td><td align="left">group read</td></tr><tr><td align="left">EXT2_S_IWGRP</td><td align="left">0x0010</td><td align="left">group write</td></tr><tr><td align="left">EXT2_S_IXGRP</td><td align="left">0x0008</td><td align="left">group execute</td></tr><tr><td align="left">EXT2_S_IROTH</td><td align="left">0x0004</td><td align="left">others read</td></tr><tr><td align="left">EXT2_S_IWOTH</td><td align="left">0x0002</td><td align="left">others write</td></tr><tr><td align="left">EXT2_S_IXOTH</td><td align="left">0x0001</td><td align="left">others execute</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-uid"></a>i_uid</h3></div></div></div><p>
+ 16bit user id associated with the file.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-size"></a>i_size</h3></div></div></div><p>
+ In revision 0, (signed) 32bit value indicating the size of the file in
+ bytes. In revision 1 and later revisions, and only for regular files, this
+ represents the lower 32-bit of the file size; the upper 32-bit is located
+ in the i_dir_acl.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-atime"></a>i_atime</h3></div></div></div><p>
+ 32bit value representing the number of seconds since january 1st 1970
+ of the last time this inode was accessed.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-ctime"></a>i_ctime</h3></div></div></div><p>
+ 32bit value representing the number of seconds since january 1st 1970, of
+ when the inode was created.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-mtime"></a>i_mtime</h3></div></div></div><p>
+ 32bit value representing the number of seconds since january 1st 1970,
+ of the last time this inode was modified.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-dtime"></a>i_dtime</h3></div></div></div><p>
+ 32bit value representing the number of seconds since january 1st 1970, of
+ when the inode was deleted.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-gid"></a>i_gid</h3></div></div></div><p>
+ 16bit value of the POSIX group having access to this file.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-links-count"></a>i_links_count</h3></div></div></div><p>
+ 16bit value indicating how many times this particular inode is linked
+ (referred to). Most files will have a link count of 1. Files with hard
+ links pointing to them will have an additional count for each hard link.
+ </p><p>
+ Symbolic links do not affect the link count of an inode. When the link count
+ reaches 0 the inode and all its associated blocks are freed.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-blocks"></a>i_blocks</h3></div></div></div><p>
+ 32-bit value representing the total number of 512-bytes blocks reserved to contain the
+ data of this inode, regardless if these blocks are used or not. The block
+ numbers of these reserved blocks are contained in the
+ <a class="link" href="#i-block" title="i_block">i_block</a> array.
+ </p><p>
+ Since this value represents 512-byte blocks and not file system blocks,
+ this value should not be directly used as an index to the i_block array.
+ Rather, the maximum index of the i_block array should be computed from
+ i_blocks / ((1024&lt;&lt;s_log_block_size)/512), or once simplified, i_blocks/(2&lt;&lt;s_log_block_size).
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-flags"></a>i_flags</h3></div></div></div><p>
+ 32bit value indicating how the ext2 implementation should behave when
+ accessing the data for this inode.
+ </p><div class="table"><a id="defined-i-flags-values"></a><p class="title"><strong>Table 3.16. Defined i_flags Values</strong></p><div class="table-contents"><table summary="Defined i_flags Values" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Constant Name</th><th>Value</th><th>Description</th></tr></thead><tbody><tr><td><a class="link" href="#ext2-secrm-fl" title="EXT2_SECRM_FL - Secure Deletion">EXT2_SECRM_FL</a></td><td>0x00000001</td><td>secure deletion</td></tr><tr><td><a class="link" href="#ext2-unrm-fl" title="EXT2_UNRM_FL - Record for Undelete">EXT2_UNRM_FL</a></td><td>0x00000002</td><td>record for undelete</td></tr><tr><td><a class="link" href="#ext2-compr-fl" title="EXT2_COMPR_FL - Compressed File">EXT2_COMPR_FL</a></td><td>0x00000004</td><td>compressed file</td></tr><tr><td><a class="link" href="#ext2-sync-fl" title="EXT2_SYNC_FL - Synchronous Updates">EXT2_SYNC_FL</a></td><td>0x00000008</td><td>synchronous updates</td></tr><tr><td><a class="link" href="#ext2-immutable-fl" title="EXT2_IMMUTABLE_FL - Immutable File">EXT2_IMMUTABLE_FL</a></td><td>0x00000010</td><td>immutable file</td></tr><tr><td><a class="link" href="#ext2-append-fl" title="EXT2_APPEND_FL - Append Only">EXT2_APPEND_FL</a></td><td>0x00000020</td><td>append only</td></tr><tr><td><a class="link" href="#ext2-nodump-fl" title="EXT2_NODUMP_FL - Do No Dump/Delete">EXT2_NODUMP_FL</a></td><td>0x00000040</td><td>do not dump/delete file</td></tr><tr><td><a class="link" href="#ext2-noatime-fl" title="EXT2_NOATIME_FL - Do Not Update .i_atime">EXT2_NOATIME_FL</a></td><td>0x00000080</td><td>do not update .i_atime</td></tr><tr><td colspan="3" align="left">-- Reserved for compression usage --</td></tr><tr><td><a class="link" href="#ext2-dirty-fl" title="EXT2_DIRTY_FL - Dirty">EXT2_DIRTY_FL</a></td><td>0x00000100</td><td>Dirty (modified)</td></tr><tr><td><a class="link" href="#ext2-comprblk-fl" title="EXT2_COMPRBLK_FL - Compressed Blocks">EXT2_COMPRBLK_FL</a></td><td>0x00000200</td><td>compressed blocks</td></tr><tr><td><a class="link" href="#ext2-nocompr-fl" title="EXT2_NOCOMPR_FL - Access Raw Compressed Data">EXT2_NOCOMPR_FL</a></td><td>0x00000400</td><td>access raw compressed data</td></tr><tr><td><a class="link" href="#ext2-ecompr-fl" title="EXT2_ECOMPR_FL - Compression Error">EXT2_ECOMPR_FL</a></td><td>0x00000800</td><td>compression error</td></tr><tr><td colspan="3" align="left">-- End of compression flags --</td></tr><tr><td><a class="link" href="#ext2-btree-fl" title="EXT2_BTREE_FL - B-Tree Format Directory">EXT2_BTREE_FL</a></td><td>0x00001000</td><td>b-tree format directory</td></tr><tr><td><a class="link" href="#ext2-index-fl" title="EXT2_INDEX_FL - Hash Indexed Directory">EXT2_INDEX_FL</a></td><td>0x00001000</td><td>hash indexed directory</td></tr><tr><td><a class="link" href="#ext2-imagic-fl" title="EXT2_IMAGIC_FL -">EXT2_IMAGIC_FL</a></td><td>0x00002000</td><td>AFS directory</td></tr><tr><td><a class="link" href="#ext3-journal-data-fl" title="EXT2_JOURNAL_DATA_FL - Journal File Data">EXT3_JOURNAL_DATA_FL</a></td><td>0x00004000</td><td>journal file data</td></tr><tr><td><a class="link" href="#ext2-reserved-fl" title="EXT2_RESERVED_FL - Reserved">EXT2_RESERVED_FL</a></td><td>0x80000000</td><td>reserved for ext2 library</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-osd1"></a>i_osd1</h3></div></div></div><p>
+ 32bit OS dependant value.
+ </p><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="i-osd1-hurd"></a>Hurd</h4></div></div></div><p>
+ 32bit value labeled as <span class="quote">“<span class="quote">translator</span>”</span>.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="i-osd1-linux"></a>Linux</h4></div></div></div><p>
+ 32bit value currently reserved.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="i-osd1-masix"></a>Masix</h4></div></div></div><p>
+ 32bit value currently reserved.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-block"></a>i_block</h3></div></div></div><p>
+ 15 x 32bit block numbers pointing to the blocks containing the data for
+ this inode. The first 12 blocks are direct blocks. The 13th entry in this
+ array is the block number of the first indirect block; which is a block
+ containing an array of block ID containing the data. Therefore, the 13th
+ block of the file will be the first block ID contained in the indirect block.
+ With a 1KiB block size, blocks 13 to 268 of the file data are contained
+ in this indirect block.
+ </p><p>
+ The 14th entry in this array is the block number of the first doubly-indirect
+ block; which is a block containing an array of indirect block IDs, with each
+ of those indirect blocks containing an array of blocks containing the data.
+ In a 1KiB block size, there would be 256 indirect blocks per doubly-indirect
+ block, with 256 direct blocks per indirect block for a total of 65536 blocks
+ per doubly-indirect block.
+ </p><p>
+ The 15th entry in this array is the block number of the triply-indirect
+ block; which is a block containing an array of doubly-indrect block IDs,
+ with each of those doubly-indrect block containing an array of indrect block,
+ and each of those indirect block containing an array of direct block. In a
+ 1KiB file system, this would be a total of 16777216 blocks per
+ triply-indirect block.
+ </p><p>
+ In the original implementation of Ext2, a value of 0 in this array effectively
+ terminated it with no further block defined. In sparse files, it is possible
+ to have some blocks allocated and some others not yet allocated with the value 0
+ being used to indicate which blocks are not yet allocated for this file.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-generation"></a>i_generation</h3></div></div></div><p>
+ 32bit value used to indicate the file version (used by NFS).
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-file-acl"></a>i_file_acl</h3></div></div></div><p>
+ 32bit value indicating the block number containing the extended
+ attributes. In revision 0 this value is always 0.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Patches and implementation status of ACL under Linux can generally be found at http://acl.bestbits.at/
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-dir-acl"></a>i_dir_acl</h3></div></div></div><p>
+ In revision 0 this 32bit value is always 0. In revision 1, for regular
+ files this 32bit value contains the high 32 bits of the 64bit file size.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Linux sets this value to 0 if the file is not a regular file (i.e. block
+ devices, directories, etc). In theory, this value could be set to point
+ to a block containing extended attributes of the directory or special file.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-faddr"></a>i_faddr</h3></div></div></div><p>
+ 32bit value indicating the location of the file fragment.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ In Linux and GNU HURD, since fragments are unsupported this value is always
+ 0. In Ext4 this value is now marked as obsolete.
+ </p><p>
+ In theory, this should contain the block number which hosts the
+ actual fragment. The fragment number and its size would be contained
+ in the <a class="link" href="#i-osd2" title="Inode i_osd2 Structure">i_osd2</a> structure.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="i-osd2"></a>Inode i_osd2 Structure</h3></div></div></div><p>
+ 96bit OS dependant structure.
+ </p><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="i-osd2-hurd"></a>Hurd</h4></div></div></div><div class="table"><a id="i-osd2-hurd-structure"></a><p class="title"><strong>Table 3.17. Inode i_osd2 Structure: Hurd</strong></p><div class="table-contents"><table summary="Inode i_osd2 Structure: Hurd" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>1</td><td><a class="link" href="#h-i-frag" title="h_i_frag">h_i_frag</a></td></tr><tr><td>1</td><td>1</td><td><a class="link" href="#h-i-fsize" title="h_i_fsize">h_i_fsize</a></td></tr><tr><td>2</td><td>2</td><td><a class="link" href="#h-i-mode-high" title="h_i_mode_high">h_i_mode_high</a></td></tr><tr><td>4</td><td>2</td><td><a class="link" href="#h-i-uid-high" title="h_i_uid_high">h_i_uid_high</a></td></tr><tr><td>6</td><td>2</td><td><a class="link" href="#h-i-gid-high" title="h_i_gid_high">h_i_gid_high</a></td></tr><tr><td>8</td><td>4</td><td><a class="link" href="#h-i-author" title="h_i_author">h_i_author</a></td></tr></tbody></table></div></div><br class="table-break" /><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="h-i-frag"></a>h_i_frag</h5></div></div></div><p>
+ 8bit fragment number. Always 0 GNU HURD since fragments are
+ not supported. Obsolete with Ext4.
+ </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="h-i-fsize"></a>h_i_fsize</h5></div></div></div><p>
+ 8bit fragment size. Always 0 in GNU HURD since fragments are
+ not supported. Obsolete with Ext4.
+ </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="h-i-mode-high"></a>h_i_mode_high</h5></div></div></div><p>
+ High 16bit of the 32bit mode.
+ </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="h-i-uid-high"></a>h_i_uid_high</h5></div></div></div><p>
+ High 16bit of <a class="link" href="#i-uid" title="i_uid">user id</a>.
+ </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="h-i-gid-high"></a>h_i_gid_high</h5></div></div></div><p>
+ High 16bit of <a class="link" href="#i-gid" title="i_gid">group id</a>.
+ </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="h-i-author"></a>h_i_author</h5></div></div></div><p>
+ 32bit user id of the assigned file author. If this value is set to -1, the
+ POSIX <a class="link" href="#i-uid" title="i_uid">user id</a> will be used.
+ </p></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="i-osd2-linux"></a>Linux</h4></div></div></div><div class="table"><a id="i-osd2-linux-structure"></a><p class="title"><strong>Table 3.18. Inode i_osd2 Structure: Linux</strong></p><div class="table-contents"><table summary="Inode i_osd2 Structure: Linux" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>1</td><td><a class="link" href="#l-i-frag" title="l_i_frag">l_i_frag</a></td></tr><tr><td>1</td><td>1</td><td><a class="link" href="#l-i-fsize" title="l_i_fsize">l_i_fsize</a></td></tr><tr><td>2</td><td>2</td><td>reserved</td></tr><tr><td>4</td><td>2</td><td><a class="link" href="#l-i-uid-high" title="l_i_uid_high">l_i_uid_high</a></td></tr><tr><td>6</td><td>2</td><td><a class="link" href="#l-i-gid-high" title="l_i_gid_high">l_i_gid_high</a></td></tr><tr><td>8</td><td>4</td><td>reserved</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="l-i-frag"></a>l_i_frag</h5></div></div></div><p>
+ 8bit fragment number.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Always 0 in Linux since fragments are not supported.
+ </p></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Important</h3><p>
+ A new implementation of Ext2 should completely disregard this field
+ if the <a class="link" href="#i-faddr" title="i_faddr">i_faddr</a> value is 0; in Ext4 this
+ field is combined with <a class="link" href="#l-i-fsize" title="l_i_fsize">l_i_fsize</a> to
+ become the high 16bit of the 48bit blocks count for the inode data.
+ </p></div></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="l-i-fsize"></a>l_i_fsize</h5></div></div></div><p>
+ 8bit fragment size.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Always 0 in Linux since fragments are not supported.
+ </p></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Important</h3><p>
+ A new implementation of Ext2 should completely disregard this field
+ if the <a class="link" href="#i-faddr" title="i_faddr">i_faddr</a> value is 0; in Ext4 this
+ field is combined with <a class="link" href="#l-i-frag" title="l_i_frag">l_i_frag</a> to
+ become the high 16bit of the 48bit blocks count for the inode data.
+ </p></div></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="l-i-uid-high"></a>l_i_uid_high</h5></div></div></div><p>
+ High 16bit of <a class="link" href="#i-uid" title="i_uid">user id</a>.
+ </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="l-i-gid-high"></a>l_i_gid_high</h5></div></div></div><p>
+ High 16bit of <a class="link" href="#i-gid" title="i_gid">group id</a>.
+ </p></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="i-osd2-masix"></a>Masix</h4></div></div></div><div class="table"><a id="i-osd2-masix-structure"></a><p class="title"><strong>Table 3.19. Inode i_osd2 Structure: Masix</strong></p><div class="table-contents"><table summary="Inode i_osd2 Structure: Masix" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>1</td><td><a class="link" href="#m-i-frag" title="m_i_frag">m_i_frag</a></td></tr><tr><td>1</td><td>1</td><td><a class="link" href="#m-i-fsize" title="m_i_fsize">m_i_fsize</a></td></tr><tr><td>2</td><td>10</td><td>reserved</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="m-i-frag"></a>m_i_frag</h5></div></div></div><p>
+ 8bit fragment number. Always 0 in Masix as framgents are not
+ supported. Obsolete with Ext4.
+ </p></div><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a id="m-i-fsize"></a>m_i_fsize</h5></div></div></div><p>
+ 8bit fragment size. Always 0 in Masix as fragments are not
+ supported. Obsolete with Ext4.
+ </p></div></div></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="idm140660447281728"></a>Locating an Inode</h2></div></div></div><p>
+ Inodes are all numerically ordered. The <span class="quote">“<span class="quote">inode number</span>”</span> is
+ an index in the <a class="link" href="#inode-table" title="Inode Table">inode table</a> to an
+ <a class="link" href="#inode-structure" title="Table 3.13. Inode Structure">inode</a> structure. The size of the
+ inode table is fixed at format time; it is built to hold a maximum
+ number of entries. Due to the large amount of entries
+ created, the table is quite big and thus, it is split equally among
+ all the <a class="link" href="#block-group-descriptor-table" title="Block Group Descriptor Table">block groups</a>
+ (see <a class="xref" href="#disk-organisation" title="Chapter 3. Disk Organization">Chapter 3, <em>Disk Organization</em></a> for more information).
+ </p><p>
+ The <a class="link" href="#s-inodes-per-group" title="s_inodes_per_group">s_inodes_per_group</a> field in
+ the <a class="link" href="#superblock" title="Superblock">superblock</a> structure tells us how many
+ inodes are defined per group. Knowing that inode 1 is the first inode
+ defined in the inode table, one can use the following formulaes:
+ </p><pre class="programlisting">
+block group = (inode - 1) / s_inodes_per_group
+ </pre><p>
+ Once the block is identified, the local inode index for the local inode
+ table can be identified using:
+ </p><pre class="programlisting">
+local inode index = (inode - 1) % s_inodes_per_group
+ </pre><p>
+ Here are a couple of sample values that could be used to test
+ your implementation:
+ </p><div class="table"><a id="inode-computation-sample"></a><p class="title"><strong>Table 3.20. Sample Inode Computations</strong></p><div class="table-contents"><table summary="Sample Inode Computations" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Inode Number</th><th>Block Group Number</th><th>Local Inode Index</th></tr></thead><tbody><tr><td colspan="3">s_inodes_per_group = 1712</td></tr><tr><td>1</td><td>0</td><td>0</td></tr><tr><td>963</td><td>0</td><td>962</td></tr><tr><td>1712</td><td>0</td><td>1711</td></tr><tr><td>1713</td><td>1</td><td>0</td></tr><tr><td>3424</td><td>1</td><td>1711</td></tr><tr><td>3425</td><td>2</td><td>0</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ As many of you are most likely already familiar with, an index of 0
+ means the first entry. The reason behind using 0 rather than 1 is that
+ it can more easily be multiplied by the structure size to find the
+ final byte offset of its location in memory or on disk.
+ </p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="directory"></a>Chapter 4. Directory Structure</h1></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="#linked-directories">Linked List Directory</a></span></dt><dd><dl><dt><span class="sect2"><a href="#ifdir-inode">inode</a></span></dt><dt><span class="sect2"><a href="#ifdir-rec-len">rec_len</a></span></dt><dt><span class="sect2"><a href="#ifdir-name-len">name_len</a></span></dt><dt><span class="sect2"><a href="#ifdir-file-type">file_type</a></span></dt><dt><span class="sect2"><a href="#ifdir-name">name</a></span></dt><dt><span class="sect2"><a href="#dir-sample">Sample Directory</a></span></dt></dl></dd><dt><span class="sect1"><a href="#indexed-directory">Indexed Directory Format</a></span></dt><dd><dl><dt><span class="sect2"><a href="#dx-root">Indexed Directory Root</a></span></dt><dt><span class="sect2"><a href="#dx-entry">Indexed Directory Entry</a></span></dt><dt><span class="sect2"><a href="#contrib-lookup-algorithm">Lookup Algorithm</a></span></dt><dt><span class="sect2"><a href="#contrib-insert-algorithm">Insert Algorithm</a></span></dt><dt><span class="sect2"><a href="#contrib-splitting">Splitting</a></span></dt><dt><span class="sect2"><a href="#contrib-key-collisions">Key Collisions</a></span></dt><dt><span class="sect2"><a href="#contrib-hash-function">Hash Function</a></span></dt><dt><span class="sect2"><a href="#contrib-performance">Performance</a></span></dt></dl></dd></dl></div><p>
+ Directories are used to hierarchically organize files. Each directory
+ can contain other directories, regular files and special files.
+ </p><p>
+ Directories are stored as data block and referenced by an inode. They
+ can be identified by the file type
+ <code class="constant">EXT2_S_IFDIR</code> stored in the <a class="link" href="#i-mode" title="i_mode">i_mode</a>
+ field of the <a class="link" href="#inode-structure" title="Table 3.13. Inode Structure">inode</a> structure.
+ </p><p>
+ The second entry of the <a class="link" href="#inode-table" title="Inode Table">Inode table</a> contains
+ the inode pointing to the data of the root directory; as defined by the
+ <code class="constant">EXT2_ROOT_INO</code> constant.
+ </p><p>
+ In revision 0 directories could only be stored in a linked list. Revision 1
+ and later introduced indexed directories. The indexed directory is backward
+ compatible with the linked list directory; this is achieved by inserting
+ empty directory entry records to skip over the hash indexes.
+ </p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="linked-directories"></a>Linked List Directory</h2></div></div></div><p>
+ A directory file is a linked list of
+ <a class="link" href="#linked-directory-entry-structure" title="Table 4.1. Linked Directory Entry Structure">directory entry</a>
+ structures. Each structure contains the name of the entry, the inode
+ associated with the data of this entry, and the distance within the
+ directory file to the next entry.
+ </p><p>
+ In revision 0, the type of the entry (file, directory, special file, etc)
+ has to be looked up in the inode of the file. In revision 0.5 and later,
+ the file type is also contained in the
+ <a class="link" href="#linked-directory-entry-structure" title="Table 4.1. Linked Directory Entry Structure">directory entry</a> structure.
+ </p><div class="table"><a id="linked-directory-entry-structure"></a><p class="title"><strong>Table 4.1. Linked Directory Entry Structure</strong></p><div class="table-contents"><table summary="Linked Directory Entry Structure" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>4</td><td><a class="link" href="#ifdir-inode" title="inode">inode</a></td></tr><tr><td>4</td><td>2</td><td><a class="link" href="#ifdir-rec-len" title="rec_len">rec_len</a></td></tr><tr><td>6</td><td>1</td><td><a class="link" href="#ifdir-name-len" title="name_len">name_len</a><a href="#ftn.idm140660447232656" class="footnote" id="idm140660447232656"><sup class="footnote">[a]</sup></a></td></tr><tr><td>7</td><td>1</td><td><a class="link" href="#ifdir-file-type" title="file_type">file_type</a><a href="#ftn.idm140660447228944" class="footnote" id="idm140660447228944"><sup class="footnote">[b]</sup></a></td></tr><tr><td>8</td><td>0-255</td><td><a class="link" href="#ifdir-name" title="name">name</a></td></tr></tbody><tbody class="footnotes"><tr><td colspan="3"><div id="ftn.idm140660447232656" class="footnote"><p><a href="#idm140660447232656" class="para"><sup class="para">[a] </sup></a>
+ Revision 0 of Ext2 used a 16bit <em class="structfield"><code>name_len</code></em>;
+ since most implementations restricted filenames to a maximum of 255
+ characters this value was truncated to 8bit with the upper 8bit
+ recycled as <a class="link" href="#ifdir-file-type" title="file_type">file_type</a>.
+ </p></div><div id="ftn.idm140660447228944" class="footnote"><p><a href="#idm140660447228944" class="para"><sup class="para">[b] </sup></a>
+ Not available in revision 0; this field was part of the 16bit
+ <a class="link" href="#ifdir-name-len" title="name_len">name_len</a> field.
+ </p></div></td></tr></tbody></table></div></div><br class="table-break" /><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ifdir-inode"></a>inode</h3></div></div></div><p>
+ 32bit inode number of the file entry. A value of 0 indicate that the entry
+ is not used.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ifdir-rec-len"></a>rec_len</h3></div></div></div><p>
+ 16bit unsigned displacement to the next directory entry from the start of the
+ current directory entry. This field must have a value at least equal to the
+ length of the current record.
+ </p><p>
+ The directory entries must be aligned on 4 bytes boundaries and there cannot
+ be any directory entry spanning multiple data blocks. If an entry cannot
+ completely fit in one block, it must be pushed to the next data block and the
+ rec_len of the previous entry properly adjusted.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Since this value cannot be negative, when a file is removed the previous
+ record within the block has to be modified to point to the next valid record
+ within the block or to the end of the block when no other directory entry is
+ present.
+ </p><p>
+ If the first entry within the block is removed, a blank record
+ will be created and point to the next directory entry or to the end of the
+ block.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ifdir-name-len"></a>name_len</h3></div></div></div><p>
+ 8bit unsigned value indicating how many bytes of character data are contained in the name.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ This value must never be larger than rec_len - 8. If the directory entry
+ name is updated and cannot fit in the existing directory entry, the entry may
+ have to be relocated in a new directory entry of sufficient size and
+ possibly stored in a new data block.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ifdir-file-type"></a>file_type</h3></div></div></div><p>
+ 8bit unsigned value used to indicate file type.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ In revision 0, this field was the upper 8-bit of the then 16-bit name_len.
+ Since all implementations still limited the file names to 255 characters this
+ 8-bit value was always 0.
+ </p><p>
+ This value must match the inode type defined in the related inode entry.
+ </p></div><div class="table"><a id="ifdir-file-type-values"></a><p class="title"><strong>Table 4.2. Defined Inode File Type Values</strong></p><div class="table-contents"><table summary="Defined Inode File Type Values" width="100%" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /></colgroup><thead><tr><th align="left">Constant Name</th><th align="left">Value</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">EXT2_FT_UNKNOWN</td><td align="left">0</td><td align="left">Unknown File Type</td></tr><tr><td align="left">EXT2_FT_REG_FILE</td><td align="left">1</td><td align="left">Regular File</td></tr><tr><td align="left">EXT2_FT_DIR</td><td align="left">2</td><td align="left">Directory File</td></tr><tr><td align="left">EXT2_FT_CHRDEV</td><td align="left">3</td><td align="left">Character Device</td></tr><tr><td align="left">EXT2_FT_BLKDEV</td><td align="left">4</td><td align="left">Block Device</td></tr><tr><td align="left">EXT2_FT_FIFO</td><td align="left">5</td><td align="left">Buffer File</td></tr><tr><td align="left">EXT2_FT_SOCK</td><td align="left">6</td><td align="left">Socket File</td></tr><tr><td align="left">EXT2_FT_SYMLINK</td><td align="left">7</td><td align="left">Symbolic Link</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ifdir-name"></a>name</h3></div></div></div><p>
+ Name of the entry. The ISO-Latin-1 character set is expected in most system.
+ The name must be no longer than 255 bytes after encoding.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="dir-sample"></a>Sample Directory</h3></div></div></div><p>
+ Here's a sample of the home directory of one user on my system:
+ </p><pre class="programlisting">
+$ ls -1a ~
+.
+..
+.bash_profile
+.bashrc
+mbox
+public_html
+tmp
+ </pre><p>
+ For which the following data representation can be found on the storage
+ device:
+ </p><div class="table"><a id="sample-linked-directory-data"></a><p class="title"><strong>Table 4.3. Sample Linked Directory Data Layout, 4KiB blocks</strong></p><div class="table-contents"><table summary="Sample Linked Directory Data Layout, 4KiB blocks" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td colspan="3" align="left">Directory Entry 0</td></tr><tr><td>0</td><td>4</td><td>inode number: 783362</td></tr><tr><td>4</td><td>2</td><td>record length: 12</td></tr><tr><td>6</td><td>1</td><td>name length: 1</td></tr><tr><td>7</td><td>1</td><td>file type: <code class="constant">EXT2_FT_DIR</code>=2</td></tr><tr><td>8</td><td>1</td><td>name: .</td></tr><tr><td>9</td><td>3</td><td>padding</td></tr><tr><td colspan="3" align="left">Directory Entry 1</td></tr><tr><td>12</td><td>4</td><td>inode number: 1109761</td></tr><tr><td>16</td><td>2</td><td>record length: 12</td></tr><tr><td>18</td><td>1</td><td>name length: 2</td></tr><tr><td>19</td><td>1</td><td>file type: <code class="constant">EXT2_FT_DIR</code>=2</td></tr><tr><td>20</td><td>2</td><td>name: ..</td></tr><tr><td>22</td><td>2</td><td>padding</td></tr><tr><td colspan="3" align="left">Directory Entry 2</td></tr><tr><td>24</td><td>4</td><td>inode number: 783364</td></tr><tr><td>28</td><td>2</td><td>record length: 24</td></tr><tr><td>30</td><td>1</td><td>name length: 13</td></tr><tr><td>31</td><td>1</td><td>file type: <code class="constant">EXT2_FT_REG_FILE</code></td></tr><tr><td>32</td><td>13</td><td>name: .bash_profile</td></tr><tr><td>45</td><td>3</td><td>padding</td></tr><tr><td colspan="3" align="left">Directory Entry 3</td></tr><tr><td>48</td><td>4</td><td>inode number: 783363</td></tr><tr><td>52</td><td>2</td><td>record length: 16</td></tr><tr><td>54</td><td>1</td><td>name length: 7</td></tr><tr><td>55</td><td>1</td><td>file type: <code class="constant">EXT2_FT_REG_FILE</code></td></tr><tr><td>56</td><td>7</td><td>name: .bashrc</td></tr><tr><td>63</td><td>1</td><td>padding</td></tr><tr><td colspan="3" align="left">Directory Entry 4</td></tr><tr><td>64</td><td>4</td><td>inode number: 783377</td></tr><tr><td>68</td><td>2</td><td>record length: 12</td></tr><tr><td>70</td><td>1</td><td>name length: 4</td></tr><tr><td>71</td><td>1</td><td>file type: <code class="constant">EXT2_FT_REG_FILE</code></td></tr><tr><td>72</td><td>4</td><td>name: mbox</td></tr><tr><td colspan="3" align="left">Directory Entry 5</td></tr><tr><td>76</td><td>4</td><td>inode number: 783545</td></tr><tr><td>80</td><td>2</td><td>record length: 20</td></tr><tr><td>82</td><td>1</td><td>name length: 11</td></tr><tr><td>83</td><td>1</td><td>file type: <code class="constant">EXT2_FT_DIR</code>=2</td></tr><tr><td>84</td><td>11</td><td>name: public_html</td></tr><tr><td>95</td><td>1</td><td>padding</td></tr><tr><td colspan="3" align="left">Directory Entry 6</td></tr><tr><td>96</td><td>4</td><td>inode number: 669354</td></tr><tr><td>100</td><td>2</td><td>record length: 12</td></tr><tr><td>102</td><td>1</td><td>name length: 3</td></tr><tr><td>103</td><td>1</td><td>file type: <code class="constant">EXT2_FT_DIR</code>=2</td></tr><tr><td>104</td><td>3</td><td>name: tmp</td></tr><tr><td>107</td><td>1</td><td>padding</td></tr><tr><td colspan="3" align="left">Directory Entry 7</td></tr><tr><td>108</td><td>4</td><td>inode number: 0</td></tr><tr><td>112</td><td>2</td><td>record length: 3988</td></tr><tr><td>114</td><td>1</td><td>name length: 0</td></tr><tr><td>115</td><td>1</td><td>file type: <code class="constant">EXT2_FT_UNKNOWN</code></td></tr><tr><td>116</td><td>0</td><td>name:</td></tr><tr><td>116</td><td>3980</td><td>padding</td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="indexed-directory"></a>Indexed Directory Format</h2></div></div></div><p>
+ Using the standard linked list directory format can become very slow
+ once the number of files starts growing. To improve performances in
+ such a system, a hashed index is used, which allow to quickly
+ locate the particular file searched.
+ </p><p>
+ Bit <a class="link" href="#ext2-index-fl" title="EXT2_INDEX_FL - Hash Indexed Directory">EXT2_INDEX_FL</a> in the
+ <a class="link" href="#i-flags" title="i_flags">i_flags</a> of the directory inode
+ is set if the indexed directory format is used.
+ </p><p>
+ In order to maintain backward compatibility with older implementations,
+ the indexed directory also maintains a linked directory format side-by-side.
+ In case there's any discrepency between the indexed and linked directories,
+ the linked directory is preferred.
+ </p><p>
+ This backward compatibility is achieved by placing a fake directory entries
+ at the beginning of block 0 of the indexed directory data blocks. These
+ fake entries are part of the <a class="link" href="#dx-root-structure" title="Table 4.4. Indexed Directory Root Structure">dx_root</a>
+ structure and host the linked directory information for the "." and ".."
+ folder entries.
+ </p><p>
+ Immediately following the <a class="xref" href="#dx-root" title="Indexed Directory Root">the section called “Indexed Directory Root”</a> structure is an array
+ of <a class="xref" href="#dx-entry" title="Indexed Directory Entry">the section called “Indexed Directory Entry”</a> up to the end of the data block or until
+ all files have been indexed.
+ </p><p>
+ When the number of files to be indexed exceeds the number of <a class="xref" href="#dx-entry" title="Indexed Directory Entry">the section called “Indexed Directory Entry”</a>
+ that can fit in a block (<a class="xref" href="#dx-entry-countlimit-limit" title="limit">the section called “limit”</a>), a level
+ of indirect indexes is created. An indirect index is another data block allocated
+ to the directory inode that contains directory entries.
+ </p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="dx-root"></a>Indexed Directory Root</h3></div></div></div><div class="table"><a id="dx-root-structure"></a><p class="title"><strong>Table 4.4. Indexed Directory Root Structure</strong></p><div class="table-contents"><table summary="Indexed Directory Root Structure" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td colspan="3" align="left">-- Linked Directory Entry: . --</td></tr><tr><td>0</td><td>4</td><td>inode: this directory</td></tr><tr><td>4</td><td>2</td><td>rec_len: 12</td></tr><tr><td>6</td><td>1</td><td>name_len: 1</td></tr><tr><td>7</td><td>1</td><td>file_type: <code class="constant">EXT2_FT_DIR</code>=2</td></tr><tr><td>8</td><td>1</td><td>name: .</td></tr><tr><td>9</td><td>3</td><td>padding</td></tr><tr><td colspan="3" align="left">-- Linked Directory Entry: .. --</td></tr><tr><td>12</td><td>4</td><td>inode: parent directory</td></tr><tr><td>16</td><td>2</td><td>rec_len: (blocksize - this entry's length(12))</td></tr><tr><td>18</td><td>1</td><td>name_len: 2</td></tr><tr><td>19</td><td>1</td><td>file_type: <code class="constant">EXT2_FT_DIR</code>=2</td></tr><tr><td>20</td><td>2</td><td>name: ..</td></tr><tr><td>22</td><td>2</td><td>padding</td></tr><tr><td colspan="3" align="left">-- Indexed Directory Root Information Structure --</td></tr><tr><td>24</td><td>4</td><td>reserved, zero</td></tr><tr><td>28</td><td>1</td><td><a class="link" href="#dx-hash-version" title="hash_version">hash_version</a></td></tr><tr><td>29</td><td>1</td><td><a class="link" href="#dx-info-length" title="info_length">info_length</a></td></tr><tr><td>30</td><td>1</td><td><a class="link" href="#dx-indirect-levels" title="indirect_levels">indirect_levels</a></td></tr><tr><td>31</td><td>1</td><td>reserved - unused flags</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="dx-hash-version"></a>hash_version</h4></div></div></div><p>
+ 8bit value representing the hash version used in this indexed directory.
+ </p><div class="table"><a id="defined-dx-hash-version-values"></a><p class="title"><strong>Table 4.5. Defined Indexed Directory Hash Versions</strong></p><div class="table-contents"><table summary="Defined Indexed Directory Hash Versions" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Constant Name</th><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>DX_HASH_LEGACY</td><td>0</td><td>TODO: link to section</td></tr><tr><td>DX_HASH_HALF_MD4</td><td>1</td><td>TODO: link to section</td></tr><tr><td>DX_HASH_TEA</td><td>2</td><td>TODO: link to section</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="dx-info-length"></a>info_length</h4></div></div></div><p>
+ 8bit length of the indexed directory information structure (dx_root);
+ currently equal to 8.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="dx-indirect-levels"></a>indirect_levels</h4></div></div></div><p>
+ 8bit value indicating how many indirect levels of indexing are present in
+ this hash.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ In Linux, as of 2.6.28, the maximum indirect levels value supported is 1.
+ </p></div></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="dx-entry"></a>Indexed Directory Entry</h3></div></div></div><p>
+ The indexed directory entries are used to quickly lookup the inode number
+ associated with the hash of a filename. These entries are located immediately
+ following the fake linked directory entry of the directory data blocks, or
+ immediately following the <a class="xref" href="#dx-root" title="Indexed Directory Root">the section called “Indexed Directory Root”</a>.
+ </p><p>
+ The first indexed directory entry, rather than containing an actual hash and
+ block number, contains the maximum number of indexed directory entries that
+ can fit in the block and the actual number of indexed directory entries
+ stored in the block. The format of this special entry is detailed in
+ <a class="xref" href="#dx-entry-countlimit" title="Table 4.7. Indexed Directory Entry Count and Limit Structure">Table 4.7, “Indexed Directory Entry Count and Limit Structure”</a>.
+ </p><p>
+ The other directory entries are sorted by hash value starting from the
+ smallest to the largest numerical value.
+ </p><div class="table"><a id="dx-entry-structure"></a><p class="title"><strong>Table 4.6. Indexed Directory Entry Structure (dx_entry)</strong></p><div class="table-contents"><table summary="Indexed Directory Entry Structure (dx_entry)" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>4</td><td><a class="link" href="#dx-entry-hash" title="hash">hash</a></td></tr><tr><td>4</td><td>4</td><td><a class="link" href="#dx-entry-block" title="block">block</a></td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="dx-entry-countlimit"></a><p class="title"><strong>Table 4.7. Indexed Directory Entry Count and Limit Structure</strong></p><div class="table-contents"><table summary="Indexed Directory Entry Count and Limit Structure" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytes)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>2</td><td><a class="link" href="#dx-entry-countlimit-limit" title="limit">limit</a></td></tr><tr><td>2</td><td>2</td><td><a class="link" href="#dx-entry-countlimit-count" title="count">count</a></td></tr></tbody></table></div></div><br class="table-break" /><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="dx-entry-hash"></a>hash</h4></div></div></div><p>
+ 32bit hash of the filename represented by this entry.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="dx-entry-block"></a>block</h4></div></div></div><p>
+ 32bit block index of the directory inode data block containing the (linked) directory entry for the filename.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="dx-entry-countlimit-limit"></a>limit</h4></div></div></div><p>
+ 16bit value representing the total number of indexed directory entries that
+ fit within the block, after removing the other structures, but including
+ the count/limit entry.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="dx-entry-countlimit-count"></a>count</h4></div></div></div><p>
+ 16bit value representing the total number of indexed directory entries
+ present in the block. TODO: Research if this value includes the count/limit entry.
+ </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="contrib-lookup-algorithm"></a>Lookup Algorithm</h3></div></div></div><p>
+ Lookup is straightforword:
+ </p><pre class="programlisting">
+- Compute a hash of the name
+- Read the index root
+- Use binary search (linear in the current code) to find the
+ first index or leaf block that could contain the target hash
+ (in tree order)
+- Repeat the above until the lowest tree level is reached
+- Read the leaf directory entry block and do a normal Ext2
+ directory block search in it.
+- If the name is found, return its directory entry and buffer
+- Otherwise, if the collision bit of the next directory entry is
+ set, continue searching in the successor block
+ </pre><p>
+ Normally, two logical blocks of the file will need to be accessed, and
+ one or two metadata index blocks. The effect of the metadata index
+ blocks can largely be ignored in terms of disk access time since these
+ blocks are unlikely to be evicted from cache. There is some small CPU
+ cost that can be addressed by moving the whole directory into the page
+ cache.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="contrib-insert-algorithm"></a>Insert Algorithm</h3></div></div></div><p>
+ Insertion of new entries into the directory is considerably more
+ complex than lookup, due to the need to split leaf blocks when they
+ become full, and to satisfy the conditions that allow hash key
+ collisions to be handled reliably and efficiently. I'll just summarize
+ here:
+ </p><pre class="programlisting">
+- Probe the index as for lookup
+- If the target leaf block is full, split it and note the block
+ that will receive the new entry
+- Insert the new entry in the leaf block using the normal Ext2
+ directory entry insertion code.
+ </pre><p>
+ The details of splitting and hash collision handling are somewhat
+ messy, but I will be happy to dwell on them at length if anyone is
+ interested.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="contrib-splitting"></a>Splitting</h3></div></div></div><p>
+ In brief, when a leaf node fills up and we want to put a new entry into
+ it the leaf has to be split, and its share of the hash space has to
+ be partitioned. The most straightforward way to do this is to sort the
+ entrys by hash value and split somewhere in the middle of the sorted
+ list. This operation is log(number_of_entries_in_leaf) and is not a
+ great cost so long as an efficient sorter is used. I used Combsort
+ for this, although Quicksort would have been just as good in this
+ case since average case performance is more important than worst case.
+ </p><p>
+ An alternative approach would be just to guess a median value for the
+ hash key, and the partition could be done in linear time, but the
+ resulting poorer partitioning of hash key space outweighs the small
+ advantage of the linear partition algorithm. In any event, the number
+ of entries needing sorting is bounded by the number that fit in a leaf.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="contrib-key-collisions"></a>Key Collisions</h3></div></div></div><p>
+ Some complexity is introduced by the need to handle sequences of hash
+ key collisions. It is desireable to avoid splitting such sequences
+ between blocks, so the split point of a block is adjusted with this in
+ mind. But the possibility still remains that if the block fills up
+ with identically-hashed entries, the sequence may still have to be
+ split. This situation is flagged by placing a 1 in the low bit of the
+ index entry that points at the sucessor block, which is naturally
+ interpreted by the index probe as an intermediate value without any
+ special coding. Thus, handling the collision problem imposes no real
+ processing overhead, just come extra code and a slight reduction in the
+ hash key space. The hash key space remains sufficient for any
+ conceivable number of directory entries, up into the billions.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="contrib-hash-function"></a>Hash Function</h3></div></div></div><p>
+ The exact properties of the hash function critically affect the
+ performance of this indexing strategy, as I learned by trying a number
+ of poor hash functions, at times intentionally. A poor hash function
+ will result in many collisions or poor partitioning of the hash space.
+ To illustrate why the latter is a problem, consider what happens when a
+ block is split such that it covers just a few distinct hash values.
+ The probability of later index entries hashing into the same, small
+ hash space is very small. In practice, once a block is split, if its
+ hash space is too small it tends to stay half full forever, an effect I
+ observed in practice.
+ </p><p>
+ After some experimentation I came up with a hash function that gives
+ reasonably good dispersal of hash keys across the entire 31 bit key
+ space. This improved the average fullness of leaf blocks considerably,
+ getting much closer to the theoretical average of 3/4 full.
+ </p><p>
+ But the current hash function is just a place holder, waiting for
+ an better version based on some solid theory. I currently favor the
+ idea of using crc32 as the default hash function, but I welcome
+ suggestions.
+ </p><p>
+ Inevitably, no matter how good a hash function I come up with, somebody
+ will come up with a better one later. For this reason the design
+ allows for additional hash functiones to be added, with backward
+ compatibility. This is accomplished simply, by including a hash
+ function number in the index root. If a new, improved hash function is
+ added, all the previous versions remain available, and previously
+ created indexes remain readable.
+ </p><p>
+ Of course, the best strategy is to have a good hash function right from
+ the beginning. The initial, quick hack has produced results that
+ certainly have not been disappointing.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="contrib-performance"></a>Performance</h3></div></div></div><p>
+ OK, if you have read this far then this is no doubt the part you've
+ been waiting for. In short, the performance improvement over normal
+ Ext2 has been stunning. With very small directories performance is
+ similar to standard Ext2, but as directory size increases standard
+ Ext2 quickly blows up quadratically, while htree-enhanced Ext2
+ continues to scale linearly.
+ </p><p>
+ Uli Luckas ran benchmarks for file creation in various sizes of
+ directories ranging from 10,000 to 90,000 files. The results are
+ pleasing: total file creation time stays very close to linear, versus
+ quadratic increase with normal Ext2.
+ </p><p>
+ Time to create:
+ </p><div class="figure"><a id="idm140660446987040"></a><p class="title"><strong>Figure 4.1. Performance of Indexed Directories</strong></p><div class="figure-contents"><pre class="programlisting">
+ Indexed Normal
+ ======= ======
+10000 Files: 0m1.350s 0m23.670s
+20000 Files: 0m2.720s 1m20.470s
+30000 Files: 0m4.330s 3m9.320s
+40000 Files: 0m5.890s 5m48.750s
+50000 Files: 0m7.040s 9m31.270s
+60000 Files: 0m8.610s 13m52.250s
+70000 Files: 0m9.980s 19m24.070s
+80000 Files: 0m12.060s 25m36.730s
+90000 Files: 0m13.400s 33m18.550s
+ </pre></div></div><br class="figure-break" /><p>
+ The original paper by Daniel Phillips is at https://www.kernel.org/doc/ols/2002/ols2002-pages-425-438.pdf
+ </p><p>
+ All of these tests are CPU-bound, which may come as a surprise. The
+ directories fit easily in cache, and the limiting factor in the case of
+ standard Ext2 is the looking up of directory blocks in buffer cache,
+ and the low level scan of directory entries. In the case of htree
+ indexing there are a number of costs to be considered, all of them
+ pretty well bounded. Notwithstanding, there are a few obvious
+ optimizations to be done:
+ </p><pre class="programlisting">
+- Use binary search instead of linear search in the interior index
+ nodes.
+
+- If there is only one leaf block in a directory, bypass the index
+ probe, go straight to the block.
+
+- Map the directory into the page cache instead of the buffer cache.
+ </pre><p>
+ Each of these optimizations will produce a noticeable improvement in
+ performance, but naturally it will never be anything like the big jump
+ going from N**2 to Log512(N), ~= N. In time the optimizations will be
+ applied and we can expect to see another doubling or so in performance.
+ </p><p>
+ There will be a very slight performance hit when the directory gets big
+ enough to need a second level. Because of caching this will be very
+ small. Traversing the directories metadata index blocks will be a
+ bigger cost, and once again, this cost can be reduced by moving the
+ directory blocks into the page cache.
+ </p><p>
+ Typically, we will traverse 3 blocks to read or write a directory
+ entry, and that number increases to 4-5 with really huge directories.
+ But this is really nothing compared to normal Ext2, which traverses
+ several hundred blocks in the same situation.
+ </p></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="idm140660446981504"></a>Chapter 5. File Attributes</h1></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="#idm140660446979776">Standard Attributes</a></span></dt><dd><dl><dt><span class="sect2"><a href="#idm140660446979264">SUID, SGID and -rwxrwxrwx</a></span></dt><dt><span class="sect2"><a href="#idm140660446977504">File Size</a></span></dt><dt><span class="sect2"><a href="#idm140660446975776">Owner and Group</a></span></dt></dl></dd><dt><span class="sect1"><a href="#contrib-extended-attributes">Extended Attributes</a></span></dt><dd><dl><dt><span class="sect2"><a href="#extended-attribute-layout">Extended Attribute Block Layout</a></span></dt><dt><span class="sect2"><a href="#attribute-block-header">Extended Attribute Block Header</a></span></dt><dt><span class="sect2"><a href="#idm140660446913440">Attribute Entry Header</a></span></dt></dl></dd><dt><span class="sect1"><a href="#behaviour-flags">Behaviour Control Flags</a></span></dt><dd><dl><dt><span class="sect2"><a href="#ext2-secrm-fl">EXT2_SECRM_FL - Secure Deletion</a></span></dt><dt><span class="sect2"><a href="#ext2-unrm-fl">EXT2_UNRM_FL - Record for Undelete</a></span></dt><dt><span class="sect2"><a href="#ext2-compr-fl">EXT2_COMPR_FL - Compressed File</a></span></dt><dt><span class="sect2"><a href="#ext2-sync-fl">EXT2_SYNC_FL - Synchronous Updates</a></span></dt><dt><span class="sect2"><a href="#ext2-immutable-fl">EXT2_IMMUTABLE_FL - Immutable File</a></span></dt><dt><span class="sect2"><a href="#ext2-append-fl">EXT2_APPEND_FL - Append Only</a></span></dt><dt><span class="sect2"><a href="#ext2-nodump-fl">EXT2_NODUMP_FL - Do No Dump/Delete</a></span></dt><dt><span class="sect2"><a href="#ext2-noatime-fl">EXT2_NOATIME_FL - Do Not Update .i_atime</a></span></dt><dt><span class="sect2"><a href="#ext2-dirty-fl">EXT2_DIRTY_FL - Dirty</a></span></dt><dt><span class="sect2"><a href="#ext2-comprblk-fl">EXT2_COMPRBLK_FL - Compressed Blocks</a></span></dt><dt><span class="sect2"><a href="#ext2-nocompr-fl">EXT2_NOCOMPR_FL - Access Raw Compressed Data</a></span></dt><dt><span class="sect2"><a href="#ext2-ecompr-fl">EXT2_ECOMPR_FL - Compression Error</a></span></dt><dt><span class="sect2"><a href="#ext2-btree-fl">EXT2_BTREE_FL - B-Tree Format Directory</a></span></dt><dt><span class="sect2"><a href="#ext2-index-fl">EXT2_INDEX_FL - Hash Indexed Directory</a></span></dt><dt><span class="sect2"><a href="#ext2-imagic-fl">EXT2_IMAGIC_FL - </a></span></dt><dt><span class="sect2"><a href="#ext3-journal-data-fl">EXT2_JOURNAL_DATA_FL - Journal File Data</a></span></dt><dt><span class="sect2"><a href="#ext2-reserved-fl">EXT2_RESERVED_FL - Reserved</a></span></dt></dl></dd></dl></div><p>
+ Most of the file (also directory, symlink, device...) attributes are
+ located in the <a class="link" href="#inode-table" title="Inode Table">inode</a> associated with the file.
+ Some other attributes are only available as extended attributes.
+ </p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="idm140660446979776"></a>Standard Attributes</h2></div></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="idm140660446979264"></a>SUID, SGID and -rwxrwxrwx</h3></div></div></div><p>
+ There isn't much to say about those, they are located with the SGID and SUID bits in
+ <a class="link" href="#i-mode" title="i_mode">ext2_inode.i_mode</a>.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="idm140660446977504"></a>File Size</h3></div></div></div><p>
+ The size of a file can be determined by looking at the
+ <a class="link" href="#i-size" title="i_size">ext2_inode.i_size</a> field.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="idm140660446975776"></a>Owner and Group</h3></div></div></div><p>
+ Under most implementations, the owner and group are 16bit values, but on
+ some recent Linux and Hurd implementations the owner and group id are
+ 32bit. When 16bit values are used, only the <span class="quote">“<span class="quote">low</span>”</span> part should
+ be used as valid, while when using 32bit value, both the <span class="quote">“<span class="quote">low</span>”</span>
+ and <span class="quote">“<span class="quote">high</span>”</span> part should be used, the high part being shifted left
+ 16 places then added to the low part.
+ </p><p>
+ The low part of owner and group are located in
+ <a class="link" href="#i-uid" title="i_uid">ext2_inode.i_uid</a> and
+ <a class="link" href="#i-gid" title="i_gid">ext2_inode.i_gid</a> respectively.
+ </p><p>
+ The high part of owner and group are located in
+ <a class="link" href="#h-i-uid-high" title="h_i_uid_high">ext2_inode.osd2.hurd.h_i_uid_high</a> and
+ <a class="link" href="#l-i-gid-high" title="l_i_gid_high">ext2_inode.osd2.hurd.h_i_gid_high</a>,
+ respectively, for Hurd and located in
+ <a class="link" href="#l-i-uid-high" title="l_i_uid_high">ext2_inode.osd2.linux.l_i_uid_high</a> and
+ <a class="link" href="#l-i-gid-high" title="l_i_gid_high">ext2_inode.osd2.linux.l_i_gid_high</a>,
+ respectively, for Linux.
+ </p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="contrib-extended-attributes"></a>Extended Attributes</h2></div></div></div><p>
+ Extended attributes are name:value pairs associated permanently with
+ files and directories, similar to the environment strings associated
+ with a process. An attribute may be defined or undefined. If it is
+ defined, its value may be empty or non-empty.
+ </p><p>
+ Extended attributes are extensions to the normal attributes which are
+ associated with all inodes in the system. They are often used to
+ provide additional functionality to a filesystem - for example,
+ additional security features such as Access Control Lists (ACLs) may
+ be implemented using extended attributes.
+ </p><p>
+ Extended attributes are accessed as atomic objects. Reading retrieves
+ the whole value of an attribute and stores it in a buffer. Writing
+ replaces any previous value with the new value.
+ </p><p>
+ Extended attributes are stored on disk blocks allocated outside of
+ any inode. The <a class="link" href="#i-file-acl" title="i_file_acl">i_file_acl</a> field (for
+ regular files) or the <a class="link" href="#i-dir-acl" title="i_dir_acl">i_dir_acl</a> field
+ (for directories) fields contain the block number of the allocated data
+ block used to store the extended attributes.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Inodes which have all identical extended attributes may share the same
+ extended attribute block.
+ </p></div><p>
+ The attribute values are on the same block as their attribute entry
+ descriptions, aligned to the end of the attribute block. This allows
+ for additional attributes to be added more easily. The size of entry
+ headers varies with the length of the attribute name.
+ </p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="extended-attribute-layout"></a>Extended Attribute Block Layout</h3></div></div></div><p>
+ The block header is followed by multiple entry descriptors. These entry
+ descriptors are variable in size, and aligned to <code class="constant">EXT2_XATTR_PAD</code>
+ (4) byte boundaries. The entry descriptors are sorted by attribute name,
+ so that two extended attribute blocks can be compared efficiently.
+ </p><p>
+ Attribute values are aligned to the end of the block, stored in
+ no specific order. They are also padded to <code class="constant">EXT2_XATTR_PAD</code> (4)
+ byte boundaries. No additional gaps are left between them.
+ </p><div class="table"><a id="extended-attribute-block-layout"></a><p class="title"><strong>Table 5.1. Extended Attribute Block Layout</strong></p><div class="table-contents"><table summary="Extended Attribute Block Layout" width="100%" border="1"><colgroup><col class="c1" /><col align="center" class="c2" /><col class="c3" /></colgroup><tbody><tr><td>Attribute Block Header</td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td>Attribute Entry 1</td><td align="center">|</td><td class="auto-generated"> </td></tr><tr><td>Attribute Entry 2</td><td align="center">|</td><td>growing downwards</td></tr><tr><td>Attribute Entry 3</td><td align="center">V</td><td class="auto-generated"> </td></tr><tr><td>4 null bytes</td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td>unused space...</td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td>Attribute Value 1</td><td align="center">^</td><td class="auto-generated"> </td></tr><tr><td>Attribute Value 3</td><td align="center">|</td><td>growing upwards</td></tr><tr><td>Attribute Value 2</td><td align="center">|</td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="attribute-block-header"></a>Extended Attribute Block Header</h3></div></div></div><div class="table"><a id="attribute-block-header-structure"></a><p class="title"><strong>Table 5.2. ext2_xattr_header structure</strong></p><div class="table-contents"><table summary="ext2_xattr_header structure" width="100%" border="1"><colgroup><col class="c1" /><col class="c2" /><col class="c3" /></colgroup><thead><tr><th>Offset (bytes)</th><th>Size (bytse)</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>4</td><td><a class="link" href="#xattr-h-magic" title="h_magic">h_magic</a></td></tr><tr><td>4</td><td>4</td><td><a class="link" href="#xattr-h-refcount" title="h_refcount">h_refcount</a></td></tr><tr><td>8</td><td>4</td><td><a class="link" href="#xattr-h-blocks" title="h_blocks">h_blocks</a></td></tr><tr><td>12</td><td>4</td><td><a class="link" href="#xattr-h-hash" title="h_hash">h_hash</a></td></tr><tr><td>16</td><td>16</td><td>reserved</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-h-magic"></a>h_magic</h4></div></div></div><p>
+ 32bit magic number of identification, <code class="constant">EXT2_XATTR_MAGIC</code> = 0xEA020000.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-h-refcount"></a>h_refcount</h4></div></div></div><p>
+ 32bit value used as reference count. This value is incremented everytime
+ a link is created to this attribute block and decremented when a link is
+ destroyed. Whenever this value reaches 0 the attribute block can be freed.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-h-blocks"></a>h_blocks</h4></div></div></div><p>
+ 32bit value indicating how many blocks are currently used by the
+ extended attributes.
+ </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ In Linux a value of h_blocks higher than 1 is considered invalid. This
+ effectively restrict the amount of extended attributes to what can be
+ fit in a single block.
+ </p><p>
+ There does not seem to be any support for extended attributes in Ext2 under
+ GNU HURD.
+ </p></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-h-hash"></a>h_hash</h4></div></div></div><p>
+ 32bit hash value of all attribute entry header hashes.
+ </p><div class="procedure"><a id="xattr-h-hash-procedure"></a><p class="title"><strong>Procedure 5.1. Procedure to compute Extended Attribute Header Hash</strong></p><ol class="procedure" type="1"><li class="step"><p>Initialize the 32bit hash to 0</p></li><li class="step"><a id="xattr-h-hash-procedure-loop"></a><p>Check if there are any extended
+ attribute entry to process, if not we are done.</p></li><li class="step"><p>Do a cyclic bit shift of 16 bits to the left of the
+ 32bits hash value, effectively swapping the upper and lower 16bits of the hash</p></li><li class="step"><p>Perform a bitwise OR between the extended attribute entry
+ <a class="link" href="#xattr-e-hash" title="e_hash">hash</a> and the header hash being computed.</p></li><li class="step"><p>Go back to <a class="xref" href="#xattr-h-hash-procedure-loop" title="Step 2">Step 2</a>.</p></li></ol></div></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="idm140660446913440"></a>Attribute Entry Header</h3></div></div></div><div class="figure"><a id="idm140660446912928"></a><p class="title"><strong>Figure 5.1. ext2_xattr_header structure</strong></p><div class="figure-contents"><pre class="programlisting">
+offset size description
+------- ------- -----------
+ 0 1 <a class="link" href="#xattr-e-name-len" title="e_name_len">e_name_len</a>
+ 1 1 <a class="link" href="#xattr-e-name-index" title="e_name_index">e_name_index</a>
+ 2 2 <a class="link" href="#xattr-e-value-offs" title="e_value_offs">e_value_offs</a>
+ 4 4 <a class="link" href="#xattr-e-value-block" title="e_value_block">e_value_block</a>
+ 8 4 <a class="link" href="#xattr-e-value-size" title="e_value_size">e_value_size</a>
+ 12 4 <a class="link" href="#xattr-e-hash" title="e_hash">e_hash</a>
+ 16 ... <a class="link" href="#xattr-e-name" title="e_name">e_name</a>
+ </pre></div></div><br class="figure-break" /><p>
+ The total size of an attribute entry is always rounded to the
+ next 4-bytes boundary.
+ </p><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-e-name-len"></a>e_name_len</h4></div></div></div><p>
+ 8bit unsigned value indicating the length of the name.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-e-name-index"></a>e_name_index</h4></div></div></div><p>
+ 8bit unsigned value used as attribute name index.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-e-value-offs"></a>e_value_offs</h4></div></div></div><p>
+ 16bit unsigned offset to the value within the value block.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-e-value-block"></a>e_value_block</h4></div></div></div><p>
+ 32bit id of the block holding the value.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-e-value-size"></a>e_value_size</h4></div></div></div><p>
+ 32bit unsigned value indicating the size of the attribute value.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-e-hash"></a>e_hash</h4></div></div></div><p>
+ 32bit hash of attribute name and value.
+ </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a id="xattr-e-name"></a>e_name</h4></div></div></div><p>
+ Attribute name.
+ </p></div></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="behaviour-flags"></a>Behaviour Control Flags</h2></div></div></div><p>
+ The <a class="link" href="#i-flags" title="i_flags">i_flags</a> value in the
+ <a class="link" href="#inode-structure" title="Table 3.13. Inode Structure">inode</a> structure allows to specify how the
+ file system should behave in regard to the file. The following bits
+ are currently defined:
+ </p><div class="table"><a id="idm140660446894752"></a><p class="title"><strong>Table 5.3. Behaviour Control Flags</strong></p><div class="table-contents"><table summary="Behaviour Control Flags" width="100%" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><a class="link" href="#ext2-secrm-fl" title="EXT2_SECRM_FL - Secure Deletion">EXT2_SECRM_FL</a></td><td align="left">0x00000001</td><td align="left">secure deletion</td></tr><tr><td align="left"><a class="link" href="#ext2-unrm-fl" title="EXT2_UNRM_FL - Record for Undelete">EXT2_UNRM_FL</a></td><td align="left">0x00000002</td><td align="left">record for undelete</td></tr><tr><td align="left"><a class="link" href="#ext2-compr-fl" title="EXT2_COMPR_FL - Compressed File">EXT2_COMPR_FL</a></td><td align="left">0x00000004</td><td align="left">compressed file</td></tr><tr><td align="left"><a class="link" href="#ext2-sync-fl" title="EXT2_SYNC_FL - Synchronous Updates">EXT2_SYNC_FL</a></td><td align="left">0x00000008</td><td align="left">synchronous updates</td></tr><tr><td align="left"><a class="link" href="#ext2-immutable-fl" title="EXT2_IMMUTABLE_FL - Immutable File">EXT2_IMMUTABLE_FL</a></td><td align="left">0x00000010</td><td align="left">immutable file</td></tr><tr><td align="left"><a class="link" href="#ext2-append-fl" title="EXT2_APPEND_FL - Append Only">EXT2_APPEND_FL</a></td><td align="left">0x00000020</td><td align="left">append only</td></tr><tr><td align="left"><a class="link" href="#ext2-nodump-fl" title="EXT2_NODUMP_FL - Do No Dump/Delete">EXT2_NODUMP_FL</a></td><td align="left">0x00000040</td><td align="left">do not dump/delete file</td></tr><tr><td align="left"><a class="link" href="#ext2-noatime-fl" title="EXT2_NOATIME_FL - Do Not Update .i_atime">EXT2_NOATIME_FL</a></td><td align="left">0x00000080</td><td align="left">do not update .i_atime</td></tr><tr><td align="left"><a class="link" href="#ext2-dirty-fl" title="EXT2_DIRTY_FL - Dirty">EXT2_DIRTY_FL</a></td><td align="left">0x00000100</td><td align="left">dirty (file is in use?)</td></tr><tr><td align="left"><a class="link" href="#ext2-comprblk-fl" title="EXT2_COMPRBLK_FL - Compressed Blocks">EXT2_COMPRBLK_FL</a></td><td align="left">0x00000200</td><td align="left">compressed blocks</td></tr><tr><td align="left"><a class="link" href="#ext2-nocompr-fl" title="EXT2_NOCOMPR_FL - Access Raw Compressed Data">EXT2_NOCOMPR_FL</a></td><td align="left">0x00000400</td><td align="left">access raw compressed data</td></tr><tr><td align="left"><a class="link" href="#ext2-ecompr-fl" title="EXT2_ECOMPR_FL - Compression Error">EXT2_ECOMPR_FL</a></td><td align="left">0x00000800</td><td align="left">compression error</td></tr><tr><td align="left"><a class="link" href="#ext2-btree-fl" title="EXT2_BTREE_FL - B-Tree Format Directory">EXT2_BTREE_FL</a></td><td align="left">0x00001000</td><td align="left">b-tree format directory</td></tr><tr><td align="left"><a class="link" href="#ext2-index-fl" title="EXT2_INDEX_FL - Hash Indexed Directory">EXT2_INDEX_FL</a></td><td align="left">0x00001000</td><td align="left">Hash indexed directory</td></tr><tr><td align="left"><a class="link" href="#ext2-imagic-fl" title="EXT2_IMAGIC_FL -">EXT2_IMAGIC_FL</a></td><td align="left">0x00002000</td><td align="left">?</td></tr><tr><td align="left"><a class="link" href="#ext3-journal-data-fl" title="EXT2_JOURNAL_DATA_FL - Journal File Data">EXT3_JOURNAL_DATA_FL</a></td><td align="left">0x00004000</td><td align="left">journal file data</td></tr><tr><td align="left"><a class="link" href="#ext2-reserved-fl" title="EXT2_RESERVED_FL - Reserved">EXT2_RESERVED_FL</a></td><td align="left">0x80000000</td><td align="left">reserved for ext2 implementation</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-secrm-fl"></a>EXT2_SECRM_FL - Secure Deletion</h3></div></div></div><p>
+ Enabling this bit will cause random data to be written over the file's
+ content several times before the blocks are unlinked. Note that this
+ is highly implementation dependant and as such, it should not be assumed
+ to be 100% secure. Make sure to study the implementation notes before
+ relying on this option.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-unrm-fl"></a>EXT2_UNRM_FL - Record for Undelete</h3></div></div></div><p>
+ When supported by the implementation, setting this bit will cause the
+ deleted data to be moved to a temporary location, where the user can
+ restore the original file without any risk of data lost. This is most
+ useful when using ext2 on a desktop or workstation.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-compr-fl"></a>EXT2_COMPR_FL - Compressed File</h3></div></div></div><p>
+ The file's content is compressed. There is no note about the particular
+ algorithm used other than maybe the
+ <a class="link" href="#s-algo-bitmap" title="s_algo_bitmap">s_algo_bitmap</a> field of the
+ <a class="link" href="#superblock" title="Superblock">superblock</a> structure.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-sync-fl"></a>EXT2_SYNC_FL - Synchronous Updates</h3></div></div></div><p>
+ The file's content in memory will be constantly synchronized with the
+ content on disk. This is mostly used for very sensitive boot files
+ or encryption keys that you do not want to lose in case of a crash.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-immutable-fl"></a>EXT2_IMMUTABLE_FL - Immutable File</h3></div></div></div><p>
+ The blocks associated with the file will not be exchanged. If for
+ any reason a file system defragmentation is launched, such files will
+ not be moved. Mostly used for stage2 and stage1.5 boot loaders.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-append-fl"></a>EXT2_APPEND_FL - Append Only</h3></div></div></div><p>
+ Writing can only be used to append content at the end of the file and
+ not modify the current content. Example of such use could be mailboxes,
+ where anybody could send a message to a user but not modify any already
+ present.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-nodump-fl"></a>EXT2_NODUMP_FL - Do No Dump/Delete</h3></div></div></div><p>
+ Setting this bit will protect the file from deletion. As long as this
+ bit is set, even if the <a class="link" href="#i-links-count" title="i_links_count">i_links_count</a>
+ is 0, the file will not be removed.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-noatime-fl"></a>EXT2_NOATIME_FL - Do Not Update .i_atime</h3></div></div></div><p>
+ The <a class="link" href="#i-atime" title="i_atime">i_atime</a> field of the
+ <a class="link" href="#inode-structure" title="Table 3.13. Inode Structure">inode</a> structure will not be modified when the
+ file is accessed if this bit is set. The only good use I can think of
+ that are related to security.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-dirty-fl"></a>EXT2_DIRTY_FL - Dirty</h3></div></div></div><p>
+ I do not have information at this moment about the use of this bit.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-comprblk-fl"></a>EXT2_COMPRBLK_FL - Compressed Blocks</h3></div></div></div><p>
+ This flag is set if one or more blocks are compressed. You can have
+ more information about compression on ext2 at
+ http://www.netspace.net.au/~reiter/e2compr/ Note that the project has
+ not been updated since 1999.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-nocompr-fl"></a>EXT2_NOCOMPR_FL - Access Raw Compressed Data</h3></div></div></div><p>
+ When this flag is set, the file system implementation will not uncompress
+ the data before fowarding it to the application but will rather give it as
+ is.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-ecompr-fl"></a>EXT2_ECOMPR_FL - Compression Error</h3></div></div></div><p>
+ This flag is set if an error was detected when trying to uncompress the
+ file.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-btree-fl"></a>EXT2_BTREE_FL - B-Tree Format Directory</h3></div></div></div><p>
+
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-index-fl"></a>EXT2_INDEX_FL - Hash Indexed Directory</h3></div></div></div><p>
+ When this bit is set, the format of the directory file is hash indexed.
+ This is covered in details in <a class="xref" href="#indexed-directory" title="Indexed Directory Format">the section called “Indexed Directory Format”</a>.
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-imagic-fl"></a>EXT2_IMAGIC_FL - </h3></div></div></div><p>
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext3-journal-data-fl"></a>EXT2_JOURNAL_DATA_FL - Journal File Data</h3></div></div></div><p>
+ </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="ext2-reserved-fl"></a>EXT2_RESERVED_FL - Reserved</h3></div></div></div><p>
+ </p></div></div></div><div class="appendix"><div class="titlepage"><div><div><h1 class="title"><a id="idm140660446838800"></a>Appendix A. Credits</h1></div></div></div><p>
+ I would like to personally thank everybody who contributed to this document,
+ you are numerous and in many cases I haven't kept track of all of you. Be
+ sure that if you are not in this list, it's a mistake and do not hesitate
+ to contact me, it will be a pleasure to add your name to the list.
+ </p><pre class="programlisting">
+Peter Rottengatter ([email protected])
+ Corrections to <a class="xref" href="#s-inodes-per-group" title="s_inodes_per_group">the section called “s_inodes_per_group”</a>
+ Corrections to <a class="xref" href="#disk-layout-sample-floppy" title="Table 3.1. Sample Floppy Disk Layout, 1KiB blocks">Table 3.1, “Sample Floppy Disk Layout, 1KiB blocks”</a> and <a class="xref" href="#disk-layout-sample-20mb" title="Table 3.2. Sample 20mb Partition Layout">Table 3.2, “Sample 20mb Partition Layout”</a>
+ Corrections to <a class="xref" href="#block-group-descriptor-table" title="Block Group Descriptor Table">the section called “Block Group Descriptor Table”</a>
+
+Ryan Cuthbertson ([email protected])
+ Corrections to <a class="xref" href="#i-blocks" title="i_blocks">the section called “i_blocks”</a>
+ Corrections to <a class="xref" href="#disk-organisation" title="Chapter 3. Disk Organization">Chapter 3, <em>Disk Organization</em></a>
+
+Andreas Gruenbacher ([email protected])
+ <a class="xref" href="#contrib-extended-attributes" title="Extended Attributes">the section called “Extended Attributes”</a>
+
+Daniel Phillips ([email protected])
+ <a class="xref" href="#contrib-lookup-algorithm" title="Lookup Algorithm">the section called “Lookup Algorithm”</a>
+ <a class="xref" href="#contrib-insert-algorithm" title="Insert Algorithm">the section called “Insert Algorithm”</a>
+ <a class="xref" href="#contrib-splitting" title="Splitting">the section called “Splitting”</a>
+ <a class="xref" href="#contrib-key-collisions" title="Key Collisions">the section called “Key Collisions”</a>
+ <a class="xref" href="#contrib-hash-function" title="Hash Function">the section called “Hash Function”</a>
+ <a class="xref" href="#contrib-performance" title="Performance">the section called “Performance”</a>
+
+Jeremy Stanley of Access Data Inc.
+ Pointed out the inversed values for EXT2_S_IFSOCK and EXT2_S_IFLNK
+
+Ahmed S. Darwish ([email protected])
+ Clarification on <a class="xref" href="#inode-bitmap" title="Inode Bitmap">the section called “Inode Bitmap”</a>
+
+Sami Besalel ([email protected])
+ Typography correction in <a class="xref" href="#ext2-secrm-fl" title="EXT2_SECRM_FL - Secure Deletion">the section called “EXT2_SECRM_FL - Secure Deletion”</a>.
+
+Kwan Fong ([email protected])
+ Improvement to wording in <a class="xref" href="#s-log-block-size" title="s_log_block_size">the section called “s_log_block_size”</a>
+
+Jonatan Schroeder ([email protected])
+ Corrections to <a class="xref" href="#i-block" title="i_block">the section called “i_block”</a> with sparse files.
+
+ </pre></div></div></body></html> \ No newline at end of file
diff --git a/build/ext2-doc/ext2-doc_color_en.pdf b/build/ext2-doc/ext2-doc_color_en.pdf
new file mode 100644
index 0000000..e7864fa
--- /dev/null
+++ b/build/ext2-doc/ext2-doc_color_en.pdf
Binary files differ
diff --git a/makefile b/makefile
deleted file mode 100644
index cd0aa8e..0000000
--- a/makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-DOC = ext2
-SRC = ext2.sgml
-
-.PHONY: all pdf dvi ps html rtf clean
-
-all: pdf ps html rtf dvi
-
-pdf: $(DOC).pdf
-dvi: $(DOC).dvi
-ps: $(DOC).ps
-html: $(DOC).html
-rtf: $(DOC).rtf
-
-$(DOC).pdf: $(SRC) makefile
- db2pdf $(SRC)
-
-$(DOC).dvi: $(SRC) makefile
- db2dvi $(SRC)
-
-$(DOC).ps: $(SRC) makefile
- db2ps $(SRC)
-
-$(DOC).html: $(SRC) makefile
- db2html -u $(SRC)
- mv ext2/ext2.html .
- rm -rf ext2.junk ext2
-
-$(DOC).rtf: $(SRC) makefile
- db2rtf $(SRC)
-
-clean:
- rm -rf $(DOC) $(DOC).pdf $(DOC).ps $(DOC).rtf $(DOC).dvi $(DOC).html
-
-install:
- mv -f $(DOC).pdf $(DOC).ps $(DOC).rtf $(DOC).dvi $(DOC).html ../../web/ext2-doc/
-
-