1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593SmuzhiyunIndex Nodes 4*4882a593Smuzhiyun----------- 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunIn a regular UNIX filesystem, the inode stores all the metadata 7*4882a593Smuzhiyunpertaining to the file (time stamps, block maps, extended attributes, 8*4882a593Smuzhiyunetc), not the directory entry. To find the information associated with a 9*4882a593Smuzhiyunfile, one must traverse the directory files to find the directory entry 10*4882a593Smuzhiyunassociated with a file, then load the inode to find the metadata for 11*4882a593Smuzhiyunthat file. ext4 appears to cheat (for performance reasons) a little bit 12*4882a593Smuzhiyunby storing a copy of the file type (normally stored in the inode) in the 13*4882a593Smuzhiyundirectory entry. (Compare all this to FAT, which stores all the file 14*4882a593Smuzhiyuninformation directly in the directory entry, but does not support hard 15*4882a593Smuzhiyunlinks and is in general more seek-happy than ext4 due to its simpler 16*4882a593Smuzhiyunblock allocator and extensive use of linked lists.) 17*4882a593Smuzhiyun 18*4882a593SmuzhiyunThe inode table is a linear array of ``struct ext4_inode``. The table is 19*4882a593Smuzhiyunsized to have enough blocks to store at least 20*4882a593Smuzhiyun``sb.s_inode_size * sb.s_inodes_per_group`` bytes. The number of the 21*4882a593Smuzhiyunblock group containing an inode can be calculated as 22*4882a593Smuzhiyun``(inode_number - 1) / sb.s_inodes_per_group``, and the offset into the 23*4882a593Smuzhiyungroup's table is ``(inode_number - 1) % sb.s_inodes_per_group``. There 24*4882a593Smuzhiyunis no inode 0. 25*4882a593Smuzhiyun 26*4882a593SmuzhiyunThe inode checksum is calculated against the FS UUID, the inode number, 27*4882a593Smuzhiyunand the inode structure itself. 28*4882a593Smuzhiyun 29*4882a593SmuzhiyunThe inode table entry is laid out in ``struct ext4_inode``. 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun.. list-table:: 32*4882a593Smuzhiyun :widths: 8 8 24 40 33*4882a593Smuzhiyun :header-rows: 1 34*4882a593Smuzhiyun :class: longtable 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun * - Offset 37*4882a593Smuzhiyun - Size 38*4882a593Smuzhiyun - Name 39*4882a593Smuzhiyun - Description 40*4882a593Smuzhiyun * - 0x0 41*4882a593Smuzhiyun - \_\_le16 42*4882a593Smuzhiyun - i\_mode 43*4882a593Smuzhiyun - File mode. See the table i_mode_ below. 44*4882a593Smuzhiyun * - 0x2 45*4882a593Smuzhiyun - \_\_le16 46*4882a593Smuzhiyun - i\_uid 47*4882a593Smuzhiyun - Lower 16-bits of Owner UID. 48*4882a593Smuzhiyun * - 0x4 49*4882a593Smuzhiyun - \_\_le32 50*4882a593Smuzhiyun - i\_size\_lo 51*4882a593Smuzhiyun - Lower 32-bits of size in bytes. 52*4882a593Smuzhiyun * - 0x8 53*4882a593Smuzhiyun - \_\_le32 54*4882a593Smuzhiyun - i\_atime 55*4882a593Smuzhiyun - Last access time, in seconds since the epoch. However, if the EA\_INODE 56*4882a593Smuzhiyun inode flag is set, this inode stores an extended attribute value and 57*4882a593Smuzhiyun this field contains the checksum of the value. 58*4882a593Smuzhiyun * - 0xC 59*4882a593Smuzhiyun - \_\_le32 60*4882a593Smuzhiyun - i\_ctime 61*4882a593Smuzhiyun - Last inode change time, in seconds since the epoch. However, if the 62*4882a593Smuzhiyun EA\_INODE inode flag is set, this inode stores an extended attribute 63*4882a593Smuzhiyun value and this field contains the lower 32 bits of the attribute value's 64*4882a593Smuzhiyun reference count. 65*4882a593Smuzhiyun * - 0x10 66*4882a593Smuzhiyun - \_\_le32 67*4882a593Smuzhiyun - i\_mtime 68*4882a593Smuzhiyun - Last data modification time, in seconds since the epoch. However, if the 69*4882a593Smuzhiyun EA\_INODE inode flag is set, this inode stores an extended attribute 70*4882a593Smuzhiyun value and this field contains the number of the inode that owns the 71*4882a593Smuzhiyun extended attribute. 72*4882a593Smuzhiyun * - 0x14 73*4882a593Smuzhiyun - \_\_le32 74*4882a593Smuzhiyun - i\_dtime 75*4882a593Smuzhiyun - Deletion Time, in seconds since the epoch. 76*4882a593Smuzhiyun * - 0x18 77*4882a593Smuzhiyun - \_\_le16 78*4882a593Smuzhiyun - i\_gid 79*4882a593Smuzhiyun - Lower 16-bits of GID. 80*4882a593Smuzhiyun * - 0x1A 81*4882a593Smuzhiyun - \_\_le16 82*4882a593Smuzhiyun - i\_links\_count 83*4882a593Smuzhiyun - Hard link count. Normally, ext4 does not permit an inode to have more 84*4882a593Smuzhiyun than 65,000 hard links. This applies to files as well as directories, 85*4882a593Smuzhiyun which means that there cannot be more than 64,998 subdirectories in a 86*4882a593Smuzhiyun directory (each subdirectory's '..' entry counts as a hard link, as does 87*4882a593Smuzhiyun the '.' entry in the directory itself). With the DIR\_NLINK feature 88*4882a593Smuzhiyun enabled, ext4 supports more than 64,998 subdirectories by setting this 89*4882a593Smuzhiyun field to 1 to indicate that the number of hard links is not known. 90*4882a593Smuzhiyun * - 0x1C 91*4882a593Smuzhiyun - \_\_le32 92*4882a593Smuzhiyun - i\_blocks\_lo 93*4882a593Smuzhiyun - Lower 32-bits of “block” count. If the huge\_file feature flag is not 94*4882a593Smuzhiyun set on the filesystem, the file consumes ``i_blocks_lo`` 512-byte blocks 95*4882a593Smuzhiyun on disk. If huge\_file is set and EXT4\_HUGE\_FILE\_FL is NOT set in 96*4882a593Smuzhiyun ``inode.i_flags``, then the file consumes ``i_blocks_lo + (i_blocks_hi 97*4882a593Smuzhiyun << 32)`` 512-byte blocks on disk. If huge\_file is set and 98*4882a593Smuzhiyun EXT4\_HUGE\_FILE\_FL IS set in ``inode.i_flags``, then this file 99*4882a593Smuzhiyun consumes (``i_blocks_lo + i_blocks_hi`` << 32) filesystem blocks on 100*4882a593Smuzhiyun disk. 101*4882a593Smuzhiyun * - 0x20 102*4882a593Smuzhiyun - \_\_le32 103*4882a593Smuzhiyun - i\_flags 104*4882a593Smuzhiyun - Inode flags. See the table i_flags_ below. 105*4882a593Smuzhiyun * - 0x24 106*4882a593Smuzhiyun - 4 bytes 107*4882a593Smuzhiyun - i\_osd1 108*4882a593Smuzhiyun - See the table i_osd1_ for more details. 109*4882a593Smuzhiyun * - 0x28 110*4882a593Smuzhiyun - 60 bytes 111*4882a593Smuzhiyun - i\_block[EXT4\_N\_BLOCKS=15] 112*4882a593Smuzhiyun - Block map or extent tree. See the section “The Contents of inode.i\_block”. 113*4882a593Smuzhiyun * - 0x64 114*4882a593Smuzhiyun - \_\_le32 115*4882a593Smuzhiyun - i\_generation 116*4882a593Smuzhiyun - File version (for NFS). 117*4882a593Smuzhiyun * - 0x68 118*4882a593Smuzhiyun - \_\_le32 119*4882a593Smuzhiyun - i\_file\_acl\_lo 120*4882a593Smuzhiyun - Lower 32-bits of extended attribute block. ACLs are of course one of 121*4882a593Smuzhiyun many possible extended attributes; I think the name of this field is a 122*4882a593Smuzhiyun result of the first use of extended attributes being for ACLs. 123*4882a593Smuzhiyun * - 0x6C 124*4882a593Smuzhiyun - \_\_le32 125*4882a593Smuzhiyun - i\_size\_high / i\_dir\_acl 126*4882a593Smuzhiyun - Upper 32-bits of file/directory size. In ext2/3 this field was named 127*4882a593Smuzhiyun i\_dir\_acl, though it was usually set to zero and never used. 128*4882a593Smuzhiyun * - 0x70 129*4882a593Smuzhiyun - \_\_le32 130*4882a593Smuzhiyun - i\_obso\_faddr 131*4882a593Smuzhiyun - (Obsolete) fragment address. 132*4882a593Smuzhiyun * - 0x74 133*4882a593Smuzhiyun - 12 bytes 134*4882a593Smuzhiyun - i\_osd2 135*4882a593Smuzhiyun - See the table i_osd2_ for more details. 136*4882a593Smuzhiyun * - 0x80 137*4882a593Smuzhiyun - \_\_le16 138*4882a593Smuzhiyun - i\_extra\_isize 139*4882a593Smuzhiyun - Size of this inode - 128. Alternately, the size of the extended inode 140*4882a593Smuzhiyun fields beyond the original ext2 inode, including this field. 141*4882a593Smuzhiyun * - 0x82 142*4882a593Smuzhiyun - \_\_le16 143*4882a593Smuzhiyun - i\_checksum\_hi 144*4882a593Smuzhiyun - Upper 16-bits of the inode checksum. 145*4882a593Smuzhiyun * - 0x84 146*4882a593Smuzhiyun - \_\_le32 147*4882a593Smuzhiyun - i\_ctime\_extra 148*4882a593Smuzhiyun - Extra change time bits. This provides sub-second precision. See Inode 149*4882a593Smuzhiyun Timestamps section. 150*4882a593Smuzhiyun * - 0x88 151*4882a593Smuzhiyun - \_\_le32 152*4882a593Smuzhiyun - i\_mtime\_extra 153*4882a593Smuzhiyun - Extra modification time bits. This provides sub-second precision. 154*4882a593Smuzhiyun * - 0x8C 155*4882a593Smuzhiyun - \_\_le32 156*4882a593Smuzhiyun - i\_atime\_extra 157*4882a593Smuzhiyun - Extra access time bits. This provides sub-second precision. 158*4882a593Smuzhiyun * - 0x90 159*4882a593Smuzhiyun - \_\_le32 160*4882a593Smuzhiyun - i\_crtime 161*4882a593Smuzhiyun - File creation time, in seconds since the epoch. 162*4882a593Smuzhiyun * - 0x94 163*4882a593Smuzhiyun - \_\_le32 164*4882a593Smuzhiyun - i\_crtime\_extra 165*4882a593Smuzhiyun - Extra file creation time bits. This provides sub-second precision. 166*4882a593Smuzhiyun * - 0x98 167*4882a593Smuzhiyun - \_\_le32 168*4882a593Smuzhiyun - i\_version\_hi 169*4882a593Smuzhiyun - Upper 32-bits for version number. 170*4882a593Smuzhiyun * - 0x9C 171*4882a593Smuzhiyun - \_\_le32 172*4882a593Smuzhiyun - i\_projid 173*4882a593Smuzhiyun - Project ID. 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun.. _i_mode: 176*4882a593Smuzhiyun 177*4882a593SmuzhiyunThe ``i_mode`` value is a combination of the following flags: 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun.. list-table:: 180*4882a593Smuzhiyun :widths: 16 64 181*4882a593Smuzhiyun :header-rows: 1 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun * - Value 184*4882a593Smuzhiyun - Description 185*4882a593Smuzhiyun * - 0x1 186*4882a593Smuzhiyun - S\_IXOTH (Others may execute) 187*4882a593Smuzhiyun * - 0x2 188*4882a593Smuzhiyun - S\_IWOTH (Others may write) 189*4882a593Smuzhiyun * - 0x4 190*4882a593Smuzhiyun - S\_IROTH (Others may read) 191*4882a593Smuzhiyun * - 0x8 192*4882a593Smuzhiyun - S\_IXGRP (Group members may execute) 193*4882a593Smuzhiyun * - 0x10 194*4882a593Smuzhiyun - S\_IWGRP (Group members may write) 195*4882a593Smuzhiyun * - 0x20 196*4882a593Smuzhiyun - S\_IRGRP (Group members may read) 197*4882a593Smuzhiyun * - 0x40 198*4882a593Smuzhiyun - S\_IXUSR (Owner may execute) 199*4882a593Smuzhiyun * - 0x80 200*4882a593Smuzhiyun - S\_IWUSR (Owner may write) 201*4882a593Smuzhiyun * - 0x100 202*4882a593Smuzhiyun - S\_IRUSR (Owner may read) 203*4882a593Smuzhiyun * - 0x200 204*4882a593Smuzhiyun - S\_ISVTX (Sticky bit) 205*4882a593Smuzhiyun * - 0x400 206*4882a593Smuzhiyun - S\_ISGID (Set GID) 207*4882a593Smuzhiyun * - 0x800 208*4882a593Smuzhiyun - S\_ISUID (Set UID) 209*4882a593Smuzhiyun * - 210*4882a593Smuzhiyun - These are mutually-exclusive file types: 211*4882a593Smuzhiyun * - 0x1000 212*4882a593Smuzhiyun - S\_IFIFO (FIFO) 213*4882a593Smuzhiyun * - 0x2000 214*4882a593Smuzhiyun - S\_IFCHR (Character device) 215*4882a593Smuzhiyun * - 0x4000 216*4882a593Smuzhiyun - S\_IFDIR (Directory) 217*4882a593Smuzhiyun * - 0x6000 218*4882a593Smuzhiyun - S\_IFBLK (Block device) 219*4882a593Smuzhiyun * - 0x8000 220*4882a593Smuzhiyun - S\_IFREG (Regular file) 221*4882a593Smuzhiyun * - 0xA000 222*4882a593Smuzhiyun - S\_IFLNK (Symbolic link) 223*4882a593Smuzhiyun * - 0xC000 224*4882a593Smuzhiyun - S\_IFSOCK (Socket) 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun.. _i_flags: 227*4882a593Smuzhiyun 228*4882a593SmuzhiyunThe ``i_flags`` field is a combination of these values: 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun.. list-table:: 231*4882a593Smuzhiyun :widths: 16 64 232*4882a593Smuzhiyun :header-rows: 1 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun * - Value 235*4882a593Smuzhiyun - Description 236*4882a593Smuzhiyun * - 0x1 237*4882a593Smuzhiyun - This file requires secure deletion (EXT4\_SECRM\_FL). (not implemented) 238*4882a593Smuzhiyun * - 0x2 239*4882a593Smuzhiyun - This file should be preserved, should undeletion be desired 240*4882a593Smuzhiyun (EXT4\_UNRM\_FL). (not implemented) 241*4882a593Smuzhiyun * - 0x4 242*4882a593Smuzhiyun - File is compressed (EXT4\_COMPR\_FL). (not really implemented) 243*4882a593Smuzhiyun * - 0x8 244*4882a593Smuzhiyun - All writes to the file must be synchronous (EXT4\_SYNC\_FL). 245*4882a593Smuzhiyun * - 0x10 246*4882a593Smuzhiyun - File is immutable (EXT4\_IMMUTABLE\_FL). 247*4882a593Smuzhiyun * - 0x20 248*4882a593Smuzhiyun - File can only be appended (EXT4\_APPEND\_FL). 249*4882a593Smuzhiyun * - 0x40 250*4882a593Smuzhiyun - The dump(1) utility should not dump this file (EXT4\_NODUMP\_FL). 251*4882a593Smuzhiyun * - 0x80 252*4882a593Smuzhiyun - Do not update access time (EXT4\_NOATIME\_FL). 253*4882a593Smuzhiyun * - 0x100 254*4882a593Smuzhiyun - Dirty compressed file (EXT4\_DIRTY\_FL). (not used) 255*4882a593Smuzhiyun * - 0x200 256*4882a593Smuzhiyun - File has one or more compressed clusters (EXT4\_COMPRBLK\_FL). (not used) 257*4882a593Smuzhiyun * - 0x400 258*4882a593Smuzhiyun - Do not compress file (EXT4\_NOCOMPR\_FL). (not used) 259*4882a593Smuzhiyun * - 0x800 260*4882a593Smuzhiyun - Encrypted inode (EXT4\_ENCRYPT\_FL). This bit value previously was 261*4882a593Smuzhiyun EXT4\_ECOMPR\_FL (compression error), which was never used. 262*4882a593Smuzhiyun * - 0x1000 263*4882a593Smuzhiyun - Directory has hashed indexes (EXT4\_INDEX\_FL). 264*4882a593Smuzhiyun * - 0x2000 265*4882a593Smuzhiyun - AFS magic directory (EXT4\_IMAGIC\_FL). 266*4882a593Smuzhiyun * - 0x4000 267*4882a593Smuzhiyun - File data must always be written through the journal 268*4882a593Smuzhiyun (EXT4\_JOURNAL\_DATA\_FL). 269*4882a593Smuzhiyun * - 0x8000 270*4882a593Smuzhiyun - File tail should not be merged (EXT4\_NOTAIL\_FL). (not used by ext4) 271*4882a593Smuzhiyun * - 0x10000 272*4882a593Smuzhiyun - All directory entry data should be written synchronously (see 273*4882a593Smuzhiyun ``dirsync``) (EXT4\_DIRSYNC\_FL). 274*4882a593Smuzhiyun * - 0x20000 275*4882a593Smuzhiyun - Top of directory hierarchy (EXT4\_TOPDIR\_FL). 276*4882a593Smuzhiyun * - 0x40000 277*4882a593Smuzhiyun - This is a huge file (EXT4\_HUGE\_FILE\_FL). 278*4882a593Smuzhiyun * - 0x80000 279*4882a593Smuzhiyun - Inode uses extents (EXT4\_EXTENTS\_FL). 280*4882a593Smuzhiyun * - 0x100000 281*4882a593Smuzhiyun - Verity protected file (EXT4\_VERITY\_FL). 282*4882a593Smuzhiyun * - 0x200000 283*4882a593Smuzhiyun - Inode stores a large extended attribute value in its data blocks 284*4882a593Smuzhiyun (EXT4\_EA\_INODE\_FL). 285*4882a593Smuzhiyun * - 0x400000 286*4882a593Smuzhiyun - This file has blocks allocated past EOF (EXT4\_EOFBLOCKS\_FL). 287*4882a593Smuzhiyun (deprecated) 288*4882a593Smuzhiyun * - 0x01000000 289*4882a593Smuzhiyun - Inode is a snapshot (``EXT4_SNAPFILE_FL``). (not in mainline) 290*4882a593Smuzhiyun * - 0x04000000 291*4882a593Smuzhiyun - Snapshot is being deleted (``EXT4_SNAPFILE_DELETED_FL``). (not in 292*4882a593Smuzhiyun mainline) 293*4882a593Smuzhiyun * - 0x08000000 294*4882a593Smuzhiyun - Snapshot shrink has completed (``EXT4_SNAPFILE_SHRUNK_FL``). (not in 295*4882a593Smuzhiyun mainline) 296*4882a593Smuzhiyun * - 0x10000000 297*4882a593Smuzhiyun - Inode has inline data (EXT4\_INLINE\_DATA\_FL). 298*4882a593Smuzhiyun * - 0x20000000 299*4882a593Smuzhiyun - Create children with the same project ID (EXT4\_PROJINHERIT\_FL). 300*4882a593Smuzhiyun * - 0x80000000 301*4882a593Smuzhiyun - Reserved for ext4 library (EXT4\_RESERVED\_FL). 302*4882a593Smuzhiyun * - 303*4882a593Smuzhiyun - Aggregate flags: 304*4882a593Smuzhiyun * - 0x705BDFFF 305*4882a593Smuzhiyun - User-visible flags. 306*4882a593Smuzhiyun * - 0x604BC0FF 307*4882a593Smuzhiyun - User-modifiable flags. Note that while EXT4\_JOURNAL\_DATA\_FL and 308*4882a593Smuzhiyun EXT4\_EXTENTS\_FL can be set with setattr, they are not in the kernel's 309*4882a593Smuzhiyun EXT4\_FL\_USER\_MODIFIABLE mask, since it needs to handle the setting of 310*4882a593Smuzhiyun these flags in a special manner and they are masked out of the set of 311*4882a593Smuzhiyun flags that are saved directly to i\_flags. 312*4882a593Smuzhiyun 313*4882a593Smuzhiyun.. _i_osd1: 314*4882a593Smuzhiyun 315*4882a593SmuzhiyunThe ``osd1`` field has multiple meanings depending on the creator: 316*4882a593Smuzhiyun 317*4882a593SmuzhiyunLinux: 318*4882a593Smuzhiyun 319*4882a593Smuzhiyun.. list-table:: 320*4882a593Smuzhiyun :widths: 8 8 24 40 321*4882a593Smuzhiyun :header-rows: 1 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun * - Offset 324*4882a593Smuzhiyun - Size 325*4882a593Smuzhiyun - Name 326*4882a593Smuzhiyun - Description 327*4882a593Smuzhiyun * - 0x0 328*4882a593Smuzhiyun - \_\_le32 329*4882a593Smuzhiyun - l\_i\_version 330*4882a593Smuzhiyun - Inode version. However, if the EA\_INODE inode flag is set, this inode 331*4882a593Smuzhiyun stores an extended attribute value and this field contains the upper 32 332*4882a593Smuzhiyun bits of the attribute value's reference count. 333*4882a593Smuzhiyun 334*4882a593SmuzhiyunHurd: 335*4882a593Smuzhiyun 336*4882a593Smuzhiyun.. list-table:: 337*4882a593Smuzhiyun :widths: 8 8 24 40 338*4882a593Smuzhiyun :header-rows: 1 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun * - Offset 341*4882a593Smuzhiyun - Size 342*4882a593Smuzhiyun - Name 343*4882a593Smuzhiyun - Description 344*4882a593Smuzhiyun * - 0x0 345*4882a593Smuzhiyun - \_\_le32 346*4882a593Smuzhiyun - h\_i\_translator 347*4882a593Smuzhiyun - ?? 348*4882a593Smuzhiyun 349*4882a593SmuzhiyunMasix: 350*4882a593Smuzhiyun 351*4882a593Smuzhiyun.. list-table:: 352*4882a593Smuzhiyun :widths: 8 8 24 40 353*4882a593Smuzhiyun :header-rows: 1 354*4882a593Smuzhiyun 355*4882a593Smuzhiyun * - Offset 356*4882a593Smuzhiyun - Size 357*4882a593Smuzhiyun - Name 358*4882a593Smuzhiyun - Description 359*4882a593Smuzhiyun * - 0x0 360*4882a593Smuzhiyun - \_\_le32 361*4882a593Smuzhiyun - m\_i\_reserved 362*4882a593Smuzhiyun - ?? 363*4882a593Smuzhiyun 364*4882a593Smuzhiyun.. _i_osd2: 365*4882a593Smuzhiyun 366*4882a593SmuzhiyunThe ``osd2`` field has multiple meanings depending on the filesystem creator: 367*4882a593Smuzhiyun 368*4882a593SmuzhiyunLinux: 369*4882a593Smuzhiyun 370*4882a593Smuzhiyun.. list-table:: 371*4882a593Smuzhiyun :widths: 8 8 24 40 372*4882a593Smuzhiyun :header-rows: 1 373*4882a593Smuzhiyun 374*4882a593Smuzhiyun * - Offset 375*4882a593Smuzhiyun - Size 376*4882a593Smuzhiyun - Name 377*4882a593Smuzhiyun - Description 378*4882a593Smuzhiyun * - 0x0 379*4882a593Smuzhiyun - \_\_le16 380*4882a593Smuzhiyun - l\_i\_blocks\_high 381*4882a593Smuzhiyun - Upper 16-bits of the block count. Please see the note attached to 382*4882a593Smuzhiyun i\_blocks\_lo. 383*4882a593Smuzhiyun * - 0x2 384*4882a593Smuzhiyun - \_\_le16 385*4882a593Smuzhiyun - l\_i\_file\_acl\_high 386*4882a593Smuzhiyun - Upper 16-bits of the extended attribute block (historically, the file 387*4882a593Smuzhiyun ACL location). See the Extended Attributes section below. 388*4882a593Smuzhiyun * - 0x4 389*4882a593Smuzhiyun - \_\_le16 390*4882a593Smuzhiyun - l\_i\_uid\_high 391*4882a593Smuzhiyun - Upper 16-bits of the Owner UID. 392*4882a593Smuzhiyun * - 0x6 393*4882a593Smuzhiyun - \_\_le16 394*4882a593Smuzhiyun - l\_i\_gid\_high 395*4882a593Smuzhiyun - Upper 16-bits of the GID. 396*4882a593Smuzhiyun * - 0x8 397*4882a593Smuzhiyun - \_\_le16 398*4882a593Smuzhiyun - l\_i\_checksum\_lo 399*4882a593Smuzhiyun - Lower 16-bits of the inode checksum. 400*4882a593Smuzhiyun * - 0xA 401*4882a593Smuzhiyun - \_\_le16 402*4882a593Smuzhiyun - l\_i\_reserved 403*4882a593Smuzhiyun - Unused. 404*4882a593Smuzhiyun 405*4882a593SmuzhiyunHurd: 406*4882a593Smuzhiyun 407*4882a593Smuzhiyun.. list-table:: 408*4882a593Smuzhiyun :widths: 8 8 24 40 409*4882a593Smuzhiyun :header-rows: 1 410*4882a593Smuzhiyun 411*4882a593Smuzhiyun * - Offset 412*4882a593Smuzhiyun - Size 413*4882a593Smuzhiyun - Name 414*4882a593Smuzhiyun - Description 415*4882a593Smuzhiyun * - 0x0 416*4882a593Smuzhiyun - \_\_le16 417*4882a593Smuzhiyun - h\_i\_reserved1 418*4882a593Smuzhiyun - ?? 419*4882a593Smuzhiyun * - 0x2 420*4882a593Smuzhiyun - \_\_u16 421*4882a593Smuzhiyun - h\_i\_mode\_high 422*4882a593Smuzhiyun - Upper 16-bits of the file mode. 423*4882a593Smuzhiyun * - 0x4 424*4882a593Smuzhiyun - \_\_le16 425*4882a593Smuzhiyun - h\_i\_uid\_high 426*4882a593Smuzhiyun - Upper 16-bits of the Owner UID. 427*4882a593Smuzhiyun * - 0x6 428*4882a593Smuzhiyun - \_\_le16 429*4882a593Smuzhiyun - h\_i\_gid\_high 430*4882a593Smuzhiyun - Upper 16-bits of the GID. 431*4882a593Smuzhiyun * - 0x8 432*4882a593Smuzhiyun - \_\_u32 433*4882a593Smuzhiyun - h\_i\_author 434*4882a593Smuzhiyun - Author code? 435*4882a593Smuzhiyun 436*4882a593SmuzhiyunMasix: 437*4882a593Smuzhiyun 438*4882a593Smuzhiyun.. list-table:: 439*4882a593Smuzhiyun :widths: 8 8 24 40 440*4882a593Smuzhiyun :header-rows: 1 441*4882a593Smuzhiyun 442*4882a593Smuzhiyun * - Offset 443*4882a593Smuzhiyun - Size 444*4882a593Smuzhiyun - Name 445*4882a593Smuzhiyun - Description 446*4882a593Smuzhiyun * - 0x0 447*4882a593Smuzhiyun - \_\_le16 448*4882a593Smuzhiyun - h\_i\_reserved1 449*4882a593Smuzhiyun - ?? 450*4882a593Smuzhiyun * - 0x2 451*4882a593Smuzhiyun - \_\_u16 452*4882a593Smuzhiyun - m\_i\_file\_acl\_high 453*4882a593Smuzhiyun - Upper 16-bits of the extended attribute block (historically, the file 454*4882a593Smuzhiyun ACL location). 455*4882a593Smuzhiyun * - 0x4 456*4882a593Smuzhiyun - \_\_u32 457*4882a593Smuzhiyun - m\_i\_reserved2[2] 458*4882a593Smuzhiyun - ?? 459*4882a593Smuzhiyun 460*4882a593SmuzhiyunInode Size 461*4882a593Smuzhiyun~~~~~~~~~~ 462*4882a593Smuzhiyun 463*4882a593SmuzhiyunIn ext2 and ext3, the inode structure size was fixed at 128 bytes 464*4882a593Smuzhiyun(``EXT2_GOOD_OLD_INODE_SIZE``) and each inode had a disk record size of 465*4882a593Smuzhiyun128 bytes. Starting with ext4, it is possible to allocate a larger 466*4882a593Smuzhiyunon-disk inode at format time for all inodes in the filesystem to provide 467*4882a593Smuzhiyunspace beyond the end of the original ext2 inode. The on-disk inode 468*4882a593Smuzhiyunrecord size is recorded in the superblock as ``s_inode_size``. The 469*4882a593Smuzhiyunnumber of bytes actually used by struct ext4\_inode beyond the original 470*4882a593Smuzhiyun128-byte ext2 inode is recorded in the ``i_extra_isize`` field for each 471*4882a593Smuzhiyuninode, which allows struct ext4\_inode to grow for a new kernel without 472*4882a593Smuzhiyunhaving to upgrade all of the on-disk inodes. Access to fields beyond 473*4882a593SmuzhiyunEXT2\_GOOD\_OLD\_INODE\_SIZE should be verified to be within 474*4882a593Smuzhiyun``i_extra_isize``. By default, ext4 inode records are 256 bytes, and (as 475*4882a593Smuzhiyunof August 2019) the inode structure is 160 bytes 476*4882a593Smuzhiyun(``i_extra_isize = 32``). The extra space between the end of the inode 477*4882a593Smuzhiyunstructure and the end of the inode record can be used to store extended 478*4882a593Smuzhiyunattributes. Each inode record can be as large as the filesystem block 479*4882a593Smuzhiyunsize, though this is not terribly efficient. 480*4882a593Smuzhiyun 481*4882a593SmuzhiyunFinding an Inode 482*4882a593Smuzhiyun~~~~~~~~~~~~~~~~ 483*4882a593Smuzhiyun 484*4882a593SmuzhiyunEach block group contains ``sb->s_inodes_per_group`` inodes. Because 485*4882a593Smuzhiyuninode 0 is defined not to exist, this formula can be used to find the 486*4882a593Smuzhiyunblock group that an inode lives in: 487*4882a593Smuzhiyun``bg = (inode_num - 1) / sb->s_inodes_per_group``. The particular inode 488*4882a593Smuzhiyuncan be found within the block group's inode table at 489*4882a593Smuzhiyun``index = (inode_num - 1) % sb->s_inodes_per_group``. To get the byte 490*4882a593Smuzhiyunaddress within the inode table, use 491*4882a593Smuzhiyun``offset = index * sb->s_inode_size``. 492*4882a593Smuzhiyun 493*4882a593SmuzhiyunInode Timestamps 494*4882a593Smuzhiyun~~~~~~~~~~~~~~~~ 495*4882a593Smuzhiyun 496*4882a593SmuzhiyunFour timestamps are recorded in the lower 128 bytes of the inode 497*4882a593Smuzhiyunstructure -- inode change time (ctime), access time (atime), data 498*4882a593Smuzhiyunmodification time (mtime), and deletion time (dtime). The four fields 499*4882a593Smuzhiyunare 32-bit signed integers that represent seconds since the Unix epoch 500*4882a593Smuzhiyun(1970-01-01 00:00:00 GMT), which means that the fields will overflow in 501*4882a593SmuzhiyunJanuary 2038. For inodes that are not linked from any directory but are 502*4882a593Smuzhiyunstill open (orphan inodes), the dtime field is overloaded for use with 503*4882a593Smuzhiyunthe orphan list. The superblock field ``s_last_orphan`` points to the 504*4882a593Smuzhiyunfirst inode in the orphan list; dtime is then the number of the next 505*4882a593Smuzhiyunorphaned inode, or zero if there are no more orphans. 506*4882a593Smuzhiyun 507*4882a593SmuzhiyunIf the inode structure size ``sb->s_inode_size`` is larger than 128 508*4882a593Smuzhiyunbytes and the ``i_inode_extra`` field is large enough to encompass the 509*4882a593Smuzhiyunrespective ``i_[cma]time_extra`` field, the ctime, atime, and mtime 510*4882a593Smuzhiyuninode fields are widened to 64 bits. Within this “extra” 32-bit field, 511*4882a593Smuzhiyunthe lower two bits are used to extend the 32-bit seconds field to be 34 512*4882a593Smuzhiyunbit wide; the upper 30 bits are used to provide nanosecond timestamp 513*4882a593Smuzhiyunaccuracy. Therefore, timestamps should not overflow until May 2446. 514*4882a593Smuzhiyundtime was not widened. There is also a fifth timestamp to record inode 515*4882a593Smuzhiyuncreation time (crtime); this field is 64-bits wide and decoded in the 516*4882a593Smuzhiyunsame manner as 64-bit [cma]time. Neither crtime nor dtime are accessible 517*4882a593Smuzhiyunthrough the regular stat() interface, though debugfs will report them. 518*4882a593Smuzhiyun 519*4882a593SmuzhiyunWe use the 32-bit signed time value plus (2^32 \* (extra epoch bits)). 520*4882a593SmuzhiyunIn other words: 521*4882a593Smuzhiyun 522*4882a593Smuzhiyun.. list-table:: 523*4882a593Smuzhiyun :widths: 20 20 20 20 20 524*4882a593Smuzhiyun :header-rows: 1 525*4882a593Smuzhiyun 526*4882a593Smuzhiyun * - Extra epoch bits 527*4882a593Smuzhiyun - MSB of 32-bit time 528*4882a593Smuzhiyun - Adjustment for signed 32-bit to 64-bit tv\_sec 529*4882a593Smuzhiyun - Decoded 64-bit tv\_sec 530*4882a593Smuzhiyun - valid time range 531*4882a593Smuzhiyun * - 0 0 532*4882a593Smuzhiyun - 1 533*4882a593Smuzhiyun - 0 534*4882a593Smuzhiyun - ``-0x80000000 - -0x00000001`` 535*4882a593Smuzhiyun - 1901-12-13 to 1969-12-31 536*4882a593Smuzhiyun * - 0 0 537*4882a593Smuzhiyun - 0 538*4882a593Smuzhiyun - 0 539*4882a593Smuzhiyun - ``0x000000000 - 0x07fffffff`` 540*4882a593Smuzhiyun - 1970-01-01 to 2038-01-19 541*4882a593Smuzhiyun * - 0 1 542*4882a593Smuzhiyun - 1 543*4882a593Smuzhiyun - 0x100000000 544*4882a593Smuzhiyun - ``0x080000000 - 0x0ffffffff`` 545*4882a593Smuzhiyun - 2038-01-19 to 2106-02-07 546*4882a593Smuzhiyun * - 0 1 547*4882a593Smuzhiyun - 0 548*4882a593Smuzhiyun - 0x100000000 549*4882a593Smuzhiyun - ``0x100000000 - 0x17fffffff`` 550*4882a593Smuzhiyun - 2106-02-07 to 2174-02-25 551*4882a593Smuzhiyun * - 1 0 552*4882a593Smuzhiyun - 1 553*4882a593Smuzhiyun - 0x200000000 554*4882a593Smuzhiyun - ``0x180000000 - 0x1ffffffff`` 555*4882a593Smuzhiyun - 2174-02-25 to 2242-03-16 556*4882a593Smuzhiyun * - 1 0 557*4882a593Smuzhiyun - 0 558*4882a593Smuzhiyun - 0x200000000 559*4882a593Smuzhiyun - ``0x200000000 - 0x27fffffff`` 560*4882a593Smuzhiyun - 2242-03-16 to 2310-04-04 561*4882a593Smuzhiyun * - 1 1 562*4882a593Smuzhiyun - 1 563*4882a593Smuzhiyun - 0x300000000 564*4882a593Smuzhiyun - ``0x280000000 - 0x2ffffffff`` 565*4882a593Smuzhiyun - 2310-04-04 to 2378-04-22 566*4882a593Smuzhiyun * - 1 1 567*4882a593Smuzhiyun - 0 568*4882a593Smuzhiyun - 0x300000000 569*4882a593Smuzhiyun - ``0x300000000 - 0x37fffffff`` 570*4882a593Smuzhiyun - 2378-04-22 to 2446-05-10 571*4882a593Smuzhiyun 572*4882a593SmuzhiyunThis is a somewhat odd encoding since there are effectively seven times 573*4882a593Smuzhiyunas many positive values as negative values. There have also been 574*4882a593Smuzhiyunlong-standing bugs decoding and encoding dates beyond 2038, which don't 575*4882a593Smuzhiyunseem to be fixed as of kernel 3.12 and e2fsprogs 1.42.8. 64-bit kernels 576*4882a593Smuzhiyunincorrectly use the extra epoch bits 1,1 for dates between 1901 and 577*4882a593Smuzhiyun1970. At some point the kernel will be fixed and e2fsck will fix this 578*4882a593Smuzhiyunsituation, assuming that it is run before 2310. 579