Product SiteDocumentation Site

Chapter 4. On-disk Inode

4.1. Inode Core
4.2. Unlinked Pointer
4.3. Data Fork
4.3.1. Regular Files (S_IFREG)
4.3.2. Directories (S_IFDIR)
4.3.3. Symbolic Links (S_IFLNK)
4.3.4. Other File Types
4.4. Attribute Fork
4.4.1. Extended Attribute Versions
All files, directories and links are stored on disk with inodes and descend from the root inode with it's number defined in the superblock (Section 3.1, “Superblocks”). The previous section on AG Inode Management (Section 3.3, “AG Inode Management”) describes the allocation and management of inodes on disk. This section describes the contents of inodes themselves.
An inode is divided into 3 parts:


Note: The above two unions are rarely used in the XFS code, but the structures within the union are directly cast depending on the di_mode/di_format and di_aformat values. They are referenced in this document to make it easier to explain the various structures in use within the inode.
The remaining space in the inode after di_next_unlinked where the two forks are located is called the inode's "literal area". This starts at offset 100 (0x64) in the inode.
The space for each of the two forks in the literal area is determined by the inode size, and di_core.di_forkoff. The data fork is located between the start of the literal area and di_forkoff. The attribute fork is located between di_forkoff and the end of the inode.

4.1. Inode Core

The inode's core is 96 bytes in size and contains information about the file itself including most stat data information about data and attribute forks after the core within the inode. It uses the following structure:
typedef struct xfs_dinode_core {
     __uint16_t                di_magic;
     __uint16_t                di_mode;
     __int8_t                  di_version;
     __int8_t                  di_format;
     __uint16_t                di_onlink;
     __uint32_t                di_uid;
     __uint32_t                di_gid;
     __uint32_t                di_nlink;
     __uint16_t                di_projid;
     __uint8_t                 di_pad[8];
     __uint16_t                di_flushiter;
     xfs_timestamp_t           di_atime;
     xfs_timestamp_t           di_mtime;
     xfs_timestamp_t           di_ctime;
     xfs_fsize_t               di_size;
     xfs_drfsbno_t             di_nblocks;
     xfs_extlen_t              di_extsize;
     xfs_extnum_t              di_nextents;
     xfs_aextnum_t             di_anextents;
     __uint8_t                 di_forkoff;
     __int8_t                  di_aformat;
     __uint32_t                di_dmevmask;
     __uint16_t                di_dmstate;
     __uint16_t                di_flags;
     __uint32_t                di_gen;
} xfs_dinode_core_t;
The inode signature where these two bytes are 0x494e, or "IN" in ASCII.
Specifies the mode access bits and type of file using the standard S_Ixxx values defined in stat.h.
Specifies the inode version which currently can only be 1 or 2. The inode version specifies the usage of the di_onlink, di_nlink and di_projid values in the inode core. Initially, inodes are created as v1 but can be converted on the fly to v2 when required.
Specifies the format of the data fork in conjunction with the di_mode type. This can be one of several values. For directories and links, it can be "local" where all metadata associated with the file is within the inode, "extents" where the inode contains an array of extents to other filesystem blocks which contain the associated metadata or data or "btree" where the inode contains a B+tree root node which points to filesystem blocks containing the metadata or data. Migration between the formats depends on the amount of metadata associated with the inode. "dev" is used for character and block devices while "uuid" is currently not used.
typedef enum xfs_dinode_fmt {
} xfs_dinode_fmt_t;
In v1 inodes, this specifies the number of links to the inode from directories. When the number exceeds 65535, the inode is converted to v2 and the link count is stored in di_nlink.
Specifies the owner's UID of the inode.
Specifies the owner's GID of the inode.
Specifies the number of links to the inode from directories. This is maintained for both inode versions for current versions of XFS. Old versions of XFS did not support v2 inodes, and therefore this value was never updated and was classed as reserved space (part of di_pad).
Specifies the owner's project ID in v2 inodes. An inode is converted to v2 if the project ID is set. This value must be zero for v1 inodes.
Reserved, must be zero.
Incremented on flush.
Specifies the last access time of the files using UNIX time conventions the following structure. This value maybe undefined if the filesystem is mounted with the "noatime" option.
typedef struct xfs_timestamp {
     __int32_t                 t_sec;
     __int32_t                 t_nsec;
} xfs_timestamp_t;
Specifies the last time the file was modified.
Specifies when the inode's status was last changed.
Specifies the EOF of the inode in bytes. This can be larger or smaller than the extent space (therefore actual disk space) used for the inode. For regular files, this is the filesize in bytes, directories, the space taken by directory entries and for links, the length of the symlink.
Specifies the number of filesystem blocks used to store the inode's data including relevant metadata like B+trees. This does not include blocks used for extended attributes.
Specifies the extent size for filesystems with real-time devices and an extent size hint for standard filesystems. For normal filesystems, and with directories, the XFS_DIFLAG_EXTSZINHERIT flag must be set in di_flags if this field is used. Inodes created in these directories will inherit the di_extsize value and have XFS_DIFLAG_EXTSIZE set in their di_flags. When a file is written to beyond allocated space, XFS will attempt to allocate additional disk space based on this value.
Specifies the number of data extents associated with this inode.
Specifies the number of extended attribute extents associated with this inode.
Specifies the offset into the inode's literal area where the extended attribute fork starts. This is an 8-bit value that is multiplied by 8 to determine the actual offset in bytes (ie. attribute data is 64-bit aligned). This also limits the maximum size of the inode to 2048 bytes. This value is initially zero until an extended attribute is created. When in attribute is added, the nature of di_forkoff depends on the XFS_SB_VERSION2_ATTR2BIT flag in the superblock. Refer to the Extended Attribute Versions section (Section 4.4.1, “Extended Attribute Versions”) for more details.
Specifies the format of the attribute fork. This uses the same values as di_format, but restricted to "local", "extents" and "btree" formats for extended attribute data.
DMAPI event mask.
DMAPI state.
Specifies flags associated with the inode. This can be a combination of the following values:
The inode's data is located on the real-time device.
The inode's extents have been preallocated.
Specifies the sb_rbmino uses the new real-time bitmap format
Specifies the inode cannot be modified.
The inode is in append only mode.
The inode is written synchronously.
The inode's di_atime is not updated.
Specifies the inode is to be ignored by xfsdump.
For directory inodes, new inodes inherit the XFS_DIFLAG_REALTIME bit.
For directory inodes, new inodes inherit the di_projid value.
For directory inodes, symlinks cannot be created.
Specifies the extent size for real-time files or a and extent size hint for regular files.
For directory inodes, new inodes inherit the di_extsize value.
Specifies the inode is to be ignored when defragmenting the filesystem.
A generation number used for inode identification. This is used by tools that do inode scanning such as backup tools and xfsdump. An inode's generation number can change by unlinking and creating a new file that reuses the inode.