Ext2: Difference between revisions

12,790 bytes added ,  1 year ago
→‎Base Superblock Fields: clarify the superblock block number field is also the starting block number
[unchecked revision][unchecked revision]
(→‎Base Superblock Fields: clarify the superblock block number field is also the starting block number)
 
(36 intermediate revisions by 13 users not shown)
Line 1:
{{Filesystems}}
The Second Extended Filesystem (ext2fs) was the default filesystem of Linux prior the advent of the journaling file systems ext3fs and ReiserFS. It has native support for UNIX ownership / access rights, symbolic and hard links and other Unix-native properties. Like HPFS, it tries to minimize head movement by distributing data across the disk. Also, by using "groups", it minimizes the impact of fragmentation. It is another "inode" based system. An ext2fs-partition is made up from blocks, which normally are 1K each. The first block (the bootblock) is zeroized, all the other blocks are divided into so-called block groups (normally, between 256 and 8192 blocks form a group). Each block group contains:
The '''Second Extended Filesystem''' ('''ext2fs''') is a rewrite of the original ''Extended Filesystem'' and as such, is also based around the concept of "inodes." Ext2 served as the de facto filesystem of Linux for nearly a decade from the early 1990s to the early 2000s when it was superseded by the journaling file systems [[Ext3|ext3]] and [[ReiserFS]]. It has native support for UNIX ownership / access rights, symbolic- and hard-links, and other properties that are common among UNIX-like operating systems. Organizationally, it divides disk space up into groups called "block groups." Having these groups results in distribution of data across the disk which helps to minimize head movement as well as the impact of fragmentation. Further, some (if not all) groups are required to contain backups of important data that can be used to rebuild the file system in the event of disaster.
 
''Note: Most of the information here is based off of work done by Dave Poirier on the ext2-doc project (see the [[#Links|links section]]) which is graciously released under the [http://www.fsf.org/licenses/fdl.html GNU Free Documentation License]. Be sure to buy him a beer the next time you see him.''
== File Sytem Structure ==
 
== Basic Concepts ==
The Ext2 file system is split up into blocks size defined in the superblock. each block is then grouped together into block groups. Each block group contains a backup copy of the superblock, and group descriptor table. Each block group also contains a block bitmap (bitmap of allocated blocks within the group) inode bitmap (bitmap of allocated inodes within the group) and an Inode Table.
'''Important Note: All values are little-endian unless otherwise specified'''
 
=== SuperblockWhat is a Block? ===
The Ext2 file system divides up disk space into logical blocks of contiguous space. The size of blocks need not be the same size as the sector size of the disk the file system resides on. The size of blocks can be determined by reading the field starting at byte 24 in the [[#Superblock|Superblock]].
 
=== What is a Block Group? ===
The superblock (which contains important information about the layout of the file system) is located at byte 1024 and is 1024 bytes in length. From the superblock we can learn, the size of each block(bytes 24–27), Number of inodes (bytes 0-3), number of blocks (bytes 4-7), number of block per group (bytes 32–35), number of inodes in each group (bytes 40–43) and where the first block group is located. From this information we can find the group an inode belongs to, total number of groups in the filesystem.
Blocks, along with inodes, are divided up into "block groups." These are nothing more than contiguous groups of blocks.
 
Each block group reserves a few of its blocks for special purposes such as:
=== Group Descriptor Table ===
* A bitmap of free/allocated blocks within the group
* A bitmap of allocated inodes within the group
* A table of inode structures that belong to the group
* Depending upon the revision of Ext2 used, some or all block groups may also contain a backup copy of the [[#Superblock|Superblock]] and the [[#Block_Group_Descriptor_Table|Block Group Descriptor Table]].
 
=== What is an Inode? ===
The Group Descriptor Table contains an entry for each block group within the filesystem. The table is located in the next block after the superblock. Each Descriptor contains information regarding whre inportant datastructure are for that group.
An inode is a structure on the disk that represents a file, directory, symbolic link, etc. Inodes do not contain the data of the file / directory / etc. that they represent. Instead, they link to the blocks that actually contain the data. This lets the inodes themselves have a well-defined size which lets them be placed in easily indexed arrays. Each block group has an array of inodes it is responsible for, and conversely every inode within a file system belongs to one of such tables (and one of such block groups).
 
=== INodesSuperblock ===
The first step in implementing an Ext2 driver is to find, extract, and parse the superblock. The Superblock contains all information about the layout of the file system and possibly contains other important information like what optional features were used to create the file system. Once you have finished with the Superblock, the next step is to look at the [[#Block_Group_Descriptor_Table|Block Group Descriptor Table]]
 
=== Locating the Superblock ===
One inode is allocated to every file and directory, and each inode has an address. From a inode address, we can determine which group the inode is in, by using the following formula.
The Superblock is always located at byte 1024 from the beginning of the volume and is exactly 1024 bytes in length. For example, if the disk uses 512 byte sectors, the Superblock will begin at LBA 2 and will occupy all of sector 2 and 3.
 
=== Determining the Number of Block Groups ===
group = (inode – 1) / INODES_PER_GROUP
From the Superblock, extract the size of each block, the total number of inodes, the total number of blocks, the number of blocks per block group, and the number of inodes in each block group. From this information we can infer the number of block groups there are by:
* Rounding up the total number of blocks divided by the number of blocks per block group
* Rounding up the total number of inodes divided by the number of inodes per block group
* Both (and check them against each other)
 
=== Base Superblock Fields ===
Inodes 1 to 10 are typically reserved and should be in an allocated state. The superblock has
These fields are present in all versions of Ext2
the value of the first non-reserved inode. Of the reserved inodes, only number 2 has a specific
{| {{wikitable}}
function, and it is used for the root directory. Inode 1 keeps track of bad blocks, but it does
! Starting
not have any special status in the Linux kernel.
Byte
 
! Ending
Each inode has a static number of fields, and additional information might be stored in
Byte
extended attributes and indirect block pointers. The allocation status of an inode is determined using the inode bitmap, whose location is
! Size
given in the group descriptor.
in Bytes
 
! Field Description
Ext2, like UFS, was designed for efficiency of small files. Therefore, each inode can store
the addresses of the first 12 blocks that a file has allocated. These are called direct pointers. If
a file needs more than 12 blocks, a block is allocated to store the remaining addresses. The
pointer to the block is called an indirect block pointer. The addresses in the block are all four
bytes, and the total number in each block is based on the block size. The indirect block
pointer is stored in the inode.
 
If a file has more blocks than can fit in the 12 direct pointers and the indirect block, a double indirect block is used. A double indirect block is when the inode points to a block that
contains a list of single indirect block pointers, each of which point to blocks that contain a
list of direct pointers. Lastly, if a file needs still more space, it can use a triple indirect block
pointer. A triple indirect block contains addresses of double indirect blocks, which contain
addresses of single indirect blocks. Each inode contains 12 direct pointers, one single
indirect pointer, one double indirect block pointer, and one triple indirect pointer.
 
An inode also contains the file's size, ownership, and temporal information. The size value in
newer versions of ExtX is 64 bits, but older versions had only 32 bits and therefore could not
handle files over 4GB. Newer versions utilize an unused field for the upper 32 bits of the size
value and set a read-only compatible feature flag when a large file exists.
 
"Ownership" information is stored using the user and group ID.
 
=== Directories ===
Directories are files which contains information needed to find files within the filesystem. The root directory is Inode 2.
 
== Implementation ==
=== Reading a file ===
 
To read a file the following step are needed:
 
# Read the superblock to find the size of each block, the number of blocks per group, number Inodes per group, the starting block of the first group.
# Read the first entry of the Group Descriptor Table, to find the location of the Inode table. get Inode 2, this will be the root directory.
# The directory information is located within the data blocks that the Inode points to, read all the data blocks associated within the Inode.
# Interate through the directory information to find the directory/file.
# Read the inode bitmap to find out weather the inode pointed to by the directory structure is allocated.
# if Allocated and is a directory go to step 3. If not allocated continue with step 4.
# Read the inode the block information, to get where the directory information is located.
# Read the first 12 blocks, (if file is less then 12 blocks, only read the number of blocks needed specified by the inode (i.e to get the number of block the file takes, divide the size of the file by the size of each block).
# If is larger than 12 blocks.
## Read indirect block.
## foreach block larger than 12 blocks, read the pointer from the block. (i.e if reading block 13, pointer 1 from the block should be read).
## if the file needs more blocks. then read the double pointer will be a pointer to a block containing pointers to blocks of data.
## if the file still need more blocks, than read the triple indirect pointer.
 
== Data structures ==
 
=== Superblock ===
{| {{Wikitable}}
|-
| 0 || 3 || 4 || Total number of inodes in file system
! Byte Range
! Description
|-
| 0–34 || 7 Number|| 4 || Total number of inodesblocks in file system
|-
| 4–78 || 11 || 4 || Number of blocks inreserved for superuser (see fileoffset system80)
|-
| 12 || 15 || 4 || Total number of unallocated blocks
| 8–11 || Number of blocks reserved to prevent file system from filling up
|-
| 12–1516 || Number19 || 4 || Total number of unallocated blocksinodes
|-
| 20 || 23 || 4 || Block number of the block containing the superblock (also the starting block number, NOT always zero.)
| 16–19 || Number of unallocated inodes
|-
| 24 || 27 || 4 || ''log''<sub>2</sub> (block size) - 10. (In other words, the number to shift 1,024 to the left by to obtain the block size)
| 20–23 || Block where block group 0 starts
|-
| 24–2728 || 31 Block|| 4 || ''log''<sub>2</sub> (fragment size) - 10. (savedIn asother words, the number of places to shift 1,024 to the left by to obtain the fragment size)
|-
| 32 || 35 || 4 || Number of blocks in each block group
| 28–31 || Fragment size (saved as the number of bits to shift 1,024 to the left)
|-
| 32–3536 || 39 || 4 || Number of blocksfragments in each block group
|-
| 36–3940 || 43 || 4 || Number of fragmentsinodes in each block group
|-
| 44 || 47 || 4 || Last mount time (in [http://en.wikipedia.org/wiki/Unix_time POSIX time])
| 40–43 || Number of inodes in each block group
|-
| 48 || 51 || 4 || Last written time (in [http://en.wikipedia.org/wiki/Unix_time POSIX time])
| 44–47 || Last mount time
|-
| 52 || 53 || 2 || Number of times the volume has been mounted since its last consistency check ([http://en.wikipedia.org/wiki/Fsck fsck])
| 48–51 || Last written time
|-
| 54 || 55 || 2 || Number of mounts allowed before a consistency check ([http://en.wikipedia.org/wiki/Fsck fsck]) must be done
| 52–53 || Current mount count
|-
| 56 || 57 || 2 || Ext2 signature (0xef53), used to help confirm the presence of Ext2 on a volume
| 54–55 || Maximum mount count
|-
| 58 || 59 || 2 || File system state ([[#File_System_States|see below]])
| 56–57 || Signature (0xef53)
|-
| 60 || 61 || 2 || What to do when an error is detected ([[#Error_Handling_Methods|see below]])
| 58–59 || File system state (see below)
|-
| 62 || 63 || 2 || Minor portion of version (combine with Major portion below to construct full version field)
| 60–61 || Error handling method (see below)
|-
| 64 || 67 || 4 || [http://en.wikipedia.org/wiki/Unix_time POSIX time] of last consistency check ([http://en.wikipedia.org/wiki/Fsck fsck])
| 62–63 || Minor version
|-
| 68 || 71 || 4 || Interval (in [http://en.wikipedia.org/wiki/Unix_time POSIX time]) between forced consistency checks ([http://en.wikipedia.org/wiki/Fsck fsck])
| 64–67 || Last consistency check time
|-
| 72 || 75 || 4 || Operating system ID from which the filesystem on this volume was created ([[#Creator_Operating_System_IDs|see below]])
| 68–71 || Interval between forced consistency checks
|-
| 76 || 79 || 4 || Major portion of version (combine with Minor portion above to construct full version field)
| 72–75 || Creator OS (see below)
|-
| 80 || 81 || 2 || User ID that can use reserved blocks
| 76–79 || Major version (see below)
|-
| 80–8182 || 83 UID|| 2 || Group ID that can use reserved blocks
|}
==== File System States ====
{| {{Wikitable}}
! Value
! State Description
|-
| 1 || File system is clean
| 82–83 || GID that can use reserved blocks
|-
| 2 || File system has errors
| 84–87 || First non-reserved inode in file system
|}
==== Error Handling Methods ====
{| {{Wikitable}}
! Value
! Action to Take
|-
| 1 || Ignore the error (continue on)
| 88–89 || Size of each inode structure
|-
| 2 || Remount file system as read-only
| 90–91 || Block group that this superblock is part of (if backup copy)
|-
| 3 || Kernel panic
| 92–95 || Compatible feature flags (see below)
|}
==== Creator Operating System IDs ====
{| {{Wikitable}}
! Value
! Operating System
|-
| 0 || [http://kernel.org/ Linux]
| 96–99 || Incompatible feature flags (see Table below)
|-
| 1 || [http://www.gnu.org/software/hurd/hurd.html GNU HURD]
| 100–103 || Read only feature flags (see Table below)
|-
| 2 || MASIX (an operating system developed by Rémy Card, one of the developers of ext2)
| 104–119 || File system ID
|-
| 3 || [http://www.freebsd.org/ FreeBSD]
| 120–135 || Volume name
|-
| 4 || Other "Lites" (BSD4.4-Lite derivatives such as [http://www.netbsd.org/ NetBSD], [http://www.openbsd.org/ OpenBSD], [http://www.opensource.apple.com/source/xnu/ XNU/Darwin], etc.)
| 136–199 || Path where last mounted on
|}
 
=== Extended Superblock Fields ===
These fields are only present if Major version (specified in the base superblock fields), is greater than or equal to 1.
{| {{Wikitable}}
! Starting
Byte
! Ending
Byte
! Size
in Bytes
! Field Description
|-
| 84 || 87 || 4 || First non-reserved inode in file system. (In versions < 1.0, this is fixed as 11)
| 200–203 || Algorithm usage bitmap
|-
| 88 || 89 || 2 || Size of each inode structure in bytes. (In versions < 1.0, this is fixed as 128)
| 204–204 || Number of blocks to preallocate for files
|-
| 90 || 91 || 2 || Block group that this superblock is part of (if backup copy)
| 205–205 || Number of blocks to preallocate for directories
|-
| 92 || 95 || 4 || Optional features present (features that are not required to read or write, but usually result in a performance increase. [[#Optional_Feature_Flags|see below]])
| 206–207 || Unused
|-
| 96 || 99 || 4 || Required features present (features that are required to be supported to read or write. [[#Required_Feature_Flags|see below]])
| 208–223 || Journal ID
|-
| 100 || 103 || 4 || Features that if not supported, the volume must be mounted read-only [[#Read-Only_Feature_Flags|see below]])
| 224–227 || Journal inode
|-
| 104 || 119 || 16 || File system ID (what is output by blkid)
| 228–231 || Journal device
|-
| 120 || 135 || 16 || Volume name (C-style string: characters terminated by a 0 byte)
| 232–235 || Head of orphan inode list
|-
| 136 || 199 || 64 || Path volume was last mounted to (C-style string: characters terminated by a 0 byte)
| 236–1023 || Unused
|}
 
==== System State Flags ====
{| {{Wikitable}}
|-
| 200 || 203 || 4 || Compression algorithms used (see Required features above)
! Flag Value
! Description
|-
| 204 || 204 || 1 || Number of blocks to preallocate for files
| 0x0001 || File system is clean
|-
| 205 || 205 || 1 || Number of blocks to preallocate for directories
| 0x0002 || File system has errors
|-
| 0x0004206 || Orphan207 inodes|| are2 being|| recovered(Unused)
|-
| 208 || 223 || 16 || Journal ID (same style as the File system ID above)
|}
==== Error-Handling Flags ====
{| {{Wikitable}}
|-
| 224 || 227 || 4 || Journal inode
! Value
! Description
|-
| 228 || 231 || 4 || Journal device
| 1 || Continue
|-
| 2232 || Remount235 file|| 4 || Head systemof asorphan readinode onlylist
|-
| 236 || 1023 || X || (Unused)
| 3 || Panic
|}
==== Optional Feature Flags ====
 
These are optional features for an implementation to support, but offer performance or reliability gains to implementations that do support them.
==== Creator OS Flags ====
{| {{Wikitable}}
|-
! Value
! Description
|-
| 0 || Linux
|-
| 1 || GNU Hurd
|-
| 2 || Masix
|-
| 3 || FreeBSD
|-
| 4 || Lites
|}
 
==== Compatible Features Flags ====
{| {{Wikitable}}
|-
Line 215 ⟶ 185:
! Description
|-
| 0x0001 || Preallocate directorysome number of (contiguous?) blocks (see byte 205 in the superblock) to a directory when creating a new one (to reduce fragmentation?)
|-
| 0x0002 || AFS server inodes exist
Line 228 ⟶ 198:
|}
 
==== IncompatibleRequired FeaturesFeature Flags ====
These features if present on a file system are required to be supported by an implementation in order to correctly read from or write to the file system.
{| {{Wikitable}}
|-
Line 234 ⟶ 205:
! Description
|-
| 0x0001 || Compression is used
|-
| 0x0002 || Directory entries contain a file type field
|-
| 0x0004 || File system needs recoveryto replay its journal
|-
| 0x0008 || File system uses a journal device
|}
 
==== Read -Only Compatible FeaturesFeature Flags ====
These features, if present on a file system, are required in order for an implementation to write to the file system, but are not required to read from the file system.
{| {{Wikitable}}
|-
Line 251 ⟶ 223:
| 0x0001 || Sparse superblocks and group descriptor tables
|-
| 0x0002 || File system containsuses a large64-bit file size
|-
| 0x0004 || Directory contents are stored in the form of a [http://en.wikipedia.org/wiki/Binary_tree Binary Tree]
| 0x0004 || Directories use B-Trees
|}
 
=== Block Group Descriptor Table ===
The Block Group Descriptor Table contains a descriptor for each block group within the file system. The number of block groups within the file system, and correspondingly, the number of entries in the Block Group Descriptor Table, is described [[#Determining_the_Number_of_Block_Groups|above]]. Each descriptor contains information regarding where important data structures for that group are located.
 
=== Locating the Block Group Descriptor Table ===
Each entry contains the following
The table is located in the block immediately following the Superblock. So if the block size (determined from a field in the superblock) is 1024 bytes per block, the Block Group Descriptor Table will begin at block 2. For any other block size, it will begin at block 1. Remember that blocks are numbered starting at 0, and that block numbers don't usually correspond to physical block addresses.
 
=== Block Group Descriptor ===
A Block Group Descriptor contains information regarding where important data structures for that block group are located.
{| {{Wikitable}}
! Starting
Byte
! Ending
Byte
! Size
in Bytes
! Field Description
|-
| 0 || 3 || 4 || Block address of block usage bitmap
! Byte Range
! Description
|-
| 0–34 || Starting7 block|| 4 || Block address of blockinode usage bitmap
|-
| 4–78 || 11 || 4 || Starting block address of inode bitmaptable
|-
| 12 || 13 || 2 || Number of unallocated blocks in group
| 8–11 || Starting block address of inode table
|-
| 12–1314 || 15 || 2 || Number of unallocated blocksinodes in group
|-
| 14–1516 || 17 || 2 || Number of unallocated inodesdirectories in group
|-
| 16–1718 || Number31 of|| directoriesX in|| group(Unused)
|-
| 18–31 || Unused
|}
 
=== InodeInodes ===
Like blocks, each inode has a numerical address. It is extremely important to note that unlike block addresses, '''inode addresses start at 1'''.
 
With Ext2 versions prior to Major version 1, inodes 1 to 10 are reserved and should be in an allocated state. Starting with version 1, the first non-reserved inode is indicated via a field in the Superblock. Of the reserved inodes, number 2 subjectively has the most significance as it is used for the root directory.
 
Inodes have a fixed size of either 128 for version 0 Ext2 file systems, or as dictated by the field in the Superblock for version 1 file systems. All inodes reside in inode tables that belong to block groups. Therefore, looking up an inode is simply a matter of determining which block group it belongs to and indexing that block group's inode table.
 
=== Determining which Block Group contains an Inode ===
From an inode address (remember that they start at 1), we can determine which group the inode is in, by using the formula:
 
block group = (inode – 1) / INODES_PER_GROUP
 
where INODES_PER_GROUP is a field in the Superblock
 
=== Finding an inode inside of a Block Group ===
Once we know which group an inode resides in, we can look up the actual inode by first retrieving that block group's inode table's starting address (see [[#Block_Group_Descriptor|Block Group Descriptor]] above). The index of our inode in this block group's inode table can be determined by using the formula:
 
index = (inode – 1) % INODES_PER_GROUP
 
where % denotes the [http://en.wikipedia.org/wiki/Modulo_operation Modulo operation] and INODES_PER_GROUP is a field in the Superblock (the same field which was used to determine which block group the inode belongs to).
 
Next, we have to determine which block contains our inode. This is achieved from:
 
containing block = (index * INODE_SIZE) / BLOCK_SIZE
 
where INODE_SIZE is either fixed at 128 if VERSION < 1 or defined by a field in the Superblock if VERSION >= 1.0, and BLOCK_SIZE is defined by a field in the Superblock.
 
Finally, mask and shift as necessary to extract only the inode data from the containing block.
 
=== Reading the contents of an inode ===
Each inode contains 12 direct pointers, one singly indirect pointer, one doubly indirect block pointer, and one triply indirect pointer. The direct space "overflows" into the singly indirect space, which overflows into the doubly indirect space, which overflows into the triply indirect space.
 
'''Direct Block Pointers''': There are 12 direct block pointers. If valid, the value is non-zero. Each pointer is the block address of a block containing data for this inode.
 
'''Singly Indirect Block Pointer''': If a file needs more than 12 blocks, a separate block is allocated to store the block addresses of the remaining data blocks needed to store its contents. This separate block is called an indirect block because it adds an extra step (a level of indirection) between an inode and its data. The block addresses stored in the block are all 32-bit, and the capacity of stored addresses in this block is a function of the block size. The address of this indirect block is stored in the inode in the "Singly Indirect Block Pointer" field.
 
'''Doubly Indirect Block Pointer''': If a file has more blocks than can fit in the 12 direct pointers and the indirect block, a double indirect block is used. A double indirect block is an extension of the indirect block described above only now we have two intermediate blocks between the inode and data blocks. The inode structure has a "Doubly Indirect Block Pointer" field that points to this block if necessary.
 
'''Triply Indirect Block Pointer''': Lastly, if a file needs still more space, it can use a triple indirect block. Again, this is an extension of the double indirect block. So, a triple indirect block contains addresses of double indirect blocks, which contain addresses of single indirect blocks, which contain address of data blocks. The inode structure has a "Triply Indirect Block Pointer" field that points to this block if present.
 
[http://en.wikipedia.org/wiki/File:Ext2-inode.gif This image from Wikipedia] illustrates what is described above pretty well.
 
=== Inode Data Structure ===
 
{| {{Wikitable}}
! Starting
Byte
! Ending
Byte
! Size
in Bytes
! Field Description
|-
| 0 || 1 || 2 || Type and Permissions ([[#Inode_Type_and_Permissions|see below]])
! Byte Range
! Description
|-
| 0–12 || File3 mode|| (type2 || andUser permissions)ID
|-
| 2–34 || 7 || 4 || Lower 1632 bits of usersize in IDbytes
|-
| 8 || 11 || 4 || Last Access Time (in [http://en.wikipedia.org/wiki/Unix_time POSIX time])
| 4–7 || Lower 32 bits of size in bytes
|-
| 12 || 15 || 4 || Creation Time (in [http://en.wikipedia.org/wiki/Unix_time POSIX time])
| 8–11 || Access Time
|-
| 16 || 19 || 4 || Last Modification time (in [http://en.wikipedia.org/wiki/Unix_time POSIX time])
| 12–15 || Change Time
|-
| 20 || 23 || 4 || Deletion time (in [http://en.wikipedia.org/wiki/Unix_time POSIX time])
| 16–19 || Modification time
|-
| 24 || 25 || 2 || Group ID
| 20–23 || Deletion time
|-
| 26 || 27 || 2 || Count of hard links (directory entries) to this inode. When this reaches 0, the data blocks are marked as unallocated.
| 24–25 || Lower 16 bits of group ID
|-
| 28 || 31 || 4 || Count of disk sectors (not Ext2 blocks) in use by this inode, not counting the actual inode structure nor directory entries linking to the inode.
| 26–27 || Link count
|-
| 32 || 35 || 4 || Flags ([[#Inode_Flags|see below]])
| 28–31 || Sector count
|-
| 36 || 39 || 4 || [[#OS_Specific_Value_1|Operating System Specific value #1]]
| 32–35 || Flags
|-
| 40 || 43 || 4 || Direct Block Pointer 0
| 36–39 || Unused
|-
| 44 || 47 || 4 || Direct Block Pointer 1
| 40–87 || 12 direct block pointers
|-
| 48 || 51 || 4 || Direct Block Pointer 2
| 88–91 || 1 single indirect block pointer
|-
| 52 || 55 || 4 || Direct Block Pointer 3
| 92–95 || 1 double indirect block pointer
|-
| 56 || 59 || 4 || Direct Block Pointer 4
| 96–99 || 1 triple indirect block pointer
|-
| 60 || 63 || 4 || Direct Block Pointer 5
| 100–103 || Generation number (NFS)
|-
| 64 || 67 || 4 || Direct Block Pointer 6
| 104–107 || Extended attribute block (File ACL)
|-
| 108–11168 || Upper71 32|| bits4 of size /|| DirectoryDirect ACLBlock YesPointer /7
|-
| 72 || 75 || 4 || Direct Block Pointer 8
| 112–115 || Block address of fragment
|-
| 76 || 79 || 4 || Direct Block Pointer 9
| 116–116 || Fragment index in block
|-
| 80 || 83 || 4 || Direct Block Pointer 10
| 117–117 || Fragment size
|-
| 84 || 87 || 4 || Direct Block Pointer 11
| 118–119 || Unused
|-
| 88 || 91 || 4 || Singly Indirect Block Pointer (Points to a block that is a list of block pointers to data)
| 120–121 || Upper 16 bits of user ID
|-
| 92 || 95 || 4 || Doubly Indirect Block Pointer (Points to a block that is a list of block pointers to Singly Indirect Blocks)
| 122–123 || Upper 16 bits of group ID
|-
| 96 || 99 || 4 || Triply Indirect Block Pointer (Points to a block that is a list of block pointers to Doubly Indirect Blocks)
| 124–127 || Unused
|}
 
==== Filemode flags ====
{| {{Wikitable}}
|+ Bits 0-8
|-
| 100 || 103 || 4 || Generation number (Primarily used for NFS)
! Permission Flag
! Description
|-
| 104 || 107 || 4 || In Ext2 version 0, this field is reserved. In version >= 1, Extended attribute block (File ACL).
| 0x001 || Other—execute permission
|-
| 108 || 111 || 4 || In Ext2 version 0, this field is reserved. In version >= 1, Upper 32 bits of file size (if feature bit set) if it's a file, Directory ACL if it's a directory
| 0x002 || Other—write permission
|-
| 112 || 115 || 4 || Block address of fragment
| 0x004 || Other—read permission
|-
| 116 || 127 || 12 || [[#OS_Specific_Value_2|Operating System Specific Value #2]]
| 0x008 || Group—execute permission
|}
 
==== Inode Type and Permissions ====
{| {{Wikitable}}
|+The type indicator occupies the top hex digit (bits 15 to 12) of this 16-bit field
! Type value
in hex
! Type Description
|-
| 0x1000 || FIFO
| 0x010 || Group—write permission
|-
| 0x2000 || Character device
| 0x020 || Group—read permission
|-
| 0x4000 || Directory
| 0x040 || User—execute permission
|-
| 0x6000 || Block device
| 0x080 || User—write permission
|-
| 0x1000x8000 || User—readRegular permissionfile
|-
| 0xA000 || Symbolic link
|-
| 0xC000 || Unix socket
|}
 
{| {{Wikitable}}
|+Permissions occupy the bottom 12 bits of this 16-bit field
|+ Bits 9-11
! Permission
value in hex
! Permission
value in octal
! Permission Description
|-
| 0x001 || 00001 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions Other—execute permission]
! Flag Value
! Description
|-
| 0x002 || 00002 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions Other—write permission]
| 0x200 || Sticky bit
|-
| 0x004 || 00004 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions Other—read permission]
| 0x400 || Set group ID
|-
| 0x008 || 00010 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions Group—execute permission]
| 0x800 || Set user ID
|}
 
Bits 12-15
 
{| {{Wikitable}}
|-
| 0x010 || 00020 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions Group—write permission]
! Tyep Value
! Description
|-
| 0x020 || 00040 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions Group—read permission]
| 0x1000 || FIFO
|-
| 0x040 || 00100 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions User—execute permission]
| 0x2000 || Character device
|-
| 0x080 || 00200 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions User—write permission]
| 0x4000 || Directory
|-
| 0x100 || 00400 || [http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions User—read permission]
| 0x6000 || Block device
|-
| 0x200 || 01000 || [http://en.wikipedia.org/wiki/Sticky_bit Sticky Bit]
| 0x8000 || Regular file
|-
| 0x400 || 02000 || Set group ID
| 0xA000 || Symbolic link
|-
| 0xC0000x800 || Unix04000 socket|| Set user ID
|}
 
==== Inode flagsFlags ====
{| {{Wikitable}}
|-
Line 421 ⟶ 452:
| 0x00000040 || File is not included in 'dump' command
|-
| 0x00000080 || A-Last accessed time isshould not updated
|-
| ... || (Reserved)
| 0x00001000 || Hash indexed directory
|-
| 0x00010000 || Hash indexed directory
| 0x00002000 || File data is journaled with Ext3
|-
| 0x00020000 || AFS directory
|-
| 0x00040000 || Journal file data
|}
==== OS Specific Value 1 ====
{| {{Wikitable}}
! Operating
System
! How they use this field
|-
| Linux || (reserved)
|-
| HURD || "translator"?
|-
| MASIX || (reserved)
|}
==== OS Specific Value 2 ====
{| {{Wikitable}}
! Operating
System
! How they use this field
|-
| Linux ||
{| {{Wikitable}}
! Starting
Byte
! Ending
Byte
! Size
in Bytes
! Field Description
|-
| 116 || 116 || 1 || Fragment number
|-
| 117 || 117 || 1 || Fragment size
|-
| 118 || 119 || 2 || (reserved)
|-
| 120 || 121 || 2 || High 16 bits of 32-bit User ID
|-
| 122 || 123 || 2 || High 16 bits of 32-bit Group ID
|-
| 124 || 127 || 4 || (reserved)
|}
|-
| HURD ||
{| {{Wikitable}}
! Starting
Byte
! Ending
Byte
! Size
in Bytes
! Field Description
|-
| 116 || 116 || 1 || Fragment number
|-
| 117 || 117 || 1 || Fragment size
|-
| 118 || 119 || 2 || High 16 bits of 32-bit "Type and Permissions" field
|-
| 120 || 121 || 2 || High 16 bits of 32-bit User ID
|-
| 122 || 123 || 2 || High 16 bits of 32-bit Group ID
|-
| 124 || 127 || 4 || User ID of author (if == 0xFFFFFFFF, the normal User ID will be used)
|}
|-
| MASIX ||
{| {{Wikitable}}
! Starting
Byte
! Ending
Byte
! Size
in Bytes
! Field Description
|-
| 116 || 116 || 1 || Fragment number
|-
| 117 || 117 || 1 || Fragment size
|-
| 118 || 127 || X || (reserved)
|}
|}
 
=== Directories ===
Directories are inodes which contain some number of "entries" as their contents. These entries are nothing more than a name/inode pair. For instance the inode corresponding to the root directory might have an entry with the name of "etc" and an inode value of 50. A directory inode stores these entries in a linked-list fashion in its contents blocks.
 
The root directory is Inode 2.
=== Directory Information ===
 
The total size of a directory entry may be longer then the length of the name would imply (The name may not span to the end of the record), and records have to be aligned to 4-byte boundaries. Directory entries are also not allowed to span multiple blocks on the file-system, so there may be empty space in-between directory entries. Empty space is however not allowed in-between directory entries, so any possible empty space will be used as part of the preceding record by increasing its record length to include the empty space. Empty space may also be equivalently marked by a separate directory entry with an inode number of zero, indicating that directory entry should be skipped.
 
=== Directory Entry ===
 
{| {{Wikitable}}
! Starting
Byte
! Ending
Byte
! Size
in Bytes
! Field Description
|-
| 0 || 3 || 4 || Inode
! Byte Range
! Description
|-
| 4 || 5 || 2 || Total size of this entry (Including all subfields)
| 0–3 || Inode
|-
| 6 || 6 || 1 || Name Length least-significant 8 bits
| 4-5 || Record Length (Will get you to the next record)
|-
| 7 || 7 || 1 || [[#Directory_Entry_Type_Indicators|Type indicator]] (only if the feature bit for "directory entries have file type byte" is set, else this is the most-significant 8 bits of the Name Length)
| 6 || Name Length
|-
| 7 || File Type
|-
| 8-X || File name data
|-
| 8 || 8+N-1 || N || Name characters
|}
 
 
==== FiletypesDirectory Entry Type Indicators ====
 
{| {{Wikitable}}
|-
! Description
! Value
! Type Description
|-
| 0 || Unknown type
|EXT2_FT_UNKNOWN || 0
|-
| 1 || Regular file
|EXT2_FT_REG_FILE || 1
|-
| 2 || Directory
|EXT2_FT_DIR || 2
|-
| 3 || Character device
|EXT2_FT_CHRDEV ||3
|-
| 4 || Block device
|EXT2_FT_BLKDEV ||4
|-
|EXT2_FT_FIFO 5 ||5 FIFO
|-
| 6 || Socket
|EXT2_FT_SOCK ||6
|-
| 7 || Symbolic link (soft link)
|EXT2_FT_SYMLINK ||7
|-
|EXT2_FT_MAX ||8
|}
 
== LinksQuick Summaries ==
=== How To Read An Inode ===
# Read the Superblock to find the size of each block, the number of blocks per group, number Inodes per group, and the starting block of the first group (Block Group Descriptor Table).
# Determine which block group the inode belongs to.
# Read the Block Group Descriptor corresponding to the Block Group which contains the inode to be looked up.
# From the Block Group Descriptor, extract the location of the block group's inode table.
# Determine the index of the inode in the inode table.
# Index the inode table (taking into account non-standard inode size).
 
Directory entry information and file contents are located within the data blocks that the Inode points to.
 
=== How To Read the Root Directory ===
The root directory's inode is defined to always be 2. Read/parse the contents of inode 2.
 
==See Also==
===External Links===
* [http://www.nongnu.org/ext2-doc/ ext2-doc project: Second Extended File System] - implementation-oriented documentation, describes internal structure in human language.
* [http://web.mit.edu/tytso/www/linux/ext2intro.html Design and Implementation of the Second Extended Filesystem] (overview)
* [http://ext2.sourceforge.net/2005-ols/paper-html/ State of the Art: Where we are with the Ext3 filesystem] - Paper by Mingming Cao, Theodore Y. Ts'o, Badari Pulavarty, and Suparna Bhattacharya describing extended features for ext2
 
[[Category:Filesystems]]
[[de:Ext2]]
Anonymous user