Working with JFS2 i-nodes

Files in JFS2 are represented internally as index nodes (i-nodes).

JFS2 disk i-nodes exist in a static form on the disk and contain access information for the files, as well as pointers to the real disk addresses of the file's data blocks. The i-nodes are allocated dynamically by JFS2. Disk-inodes are defined in the /usr/include/j2/j2_dinode.h file.

When a file is opened, an in-core i-node is created by the operating system. The in-core i-node contains a copy of all the fields defined in the disk i-node, plus additional fields for tracking the in-core i-node. In-core i-nodes are defined in the /usr/include/j2/j2_inode.h file.

Disk i-node structure for JFS2

Each disk i-node in JFS2 is a 512-byte structure. The index of a particular i-node allocation map of the file system produces the unique number (i-number) by which the operating system identifies the i-node. The i-node allocation map tracks the location of the i-nodes on the disk, as well as their availability.

Disk i-nodes include the following information:
Field Contents
di_mode Type of file and access permission mode bits
di_size Size of file in bytes
di_uid Access permissions for the user ID
di_gid Access permissions for the group ID
di_nblocks Number of blocks allocated to the file
di_mtime Last time the file was modified
di_atime Last time the file was accessed
di_ctime Last time the i-node was modified
di_nlink Number of hard links to the file
di_btroot Root of B+ tree describing the disk addresses of the data

You cannot change the file data without changing the i-node, but it is possible to change the i-node without changing the contents of the file. For example, when permission is changed, the information within the i-node (di_mode) is modified, but the data in the file remains the same.

The di_btroot describes the root of the B+ tree. It describes the data for the i-node. di_btroot has a field indicating how many of its entries in the i-node are being used and another field describing whether they are leaf nodes or internal nodes for the B+ tree.

Disk i-nodes do not contain file or path name information. Directory entries are used to link file names to i-nodes. Any i-node can be linked to many file names by creating additional directory entries with the link or symlink subroutine. To determine the i-node number assigned to a file, use the ls -i command.

The i-nodes that represent files that define devices contain slightly different information from i-nodes for regular files. Files associated with devices are called special files. There are no data block addresses in special device files, but the major and minor device numbers are included in the di_rdev field.

A disk i-node is released when the link count (di_nlink) to the i-node equals 0. Links represent the file names associated with the i-node. When the link count to the disk i-node is 0, all the data blocks associated with the i-node are released to the bitmap of free data blocks for the file system. The i-node is then placed on the free i-node map.

JFS2 in-core i-node structure

When a file is opened, the information in the disk i-node is copied into an in-core i-node for easier access. The in-core i-node structure contains additional fields that manage access to the disk i-node's valuable data. The fields of the in-core i-node are defined in the j2_inode.h file. Some of the additional information tracked by the in-core i-node is as follows:
  • Status of the in-core i-node, including flags that indicate:
    • An i-node lock
    • A process waiting for the i-node to unlock
    • Changes to the file's i-node information
    • Changes to the file's data
  • Logical device number of the file system that contains the file
  • i-number used to identify the i-node
  • Reference count. When the reference count field equals 0, the in-core i-node is released.

When an in-core i-node is released (for example, with the close subroutine), the in-core i-node reference count is reduced by 1. If this reduction results in the reference count to the in-core i-node becoming 0, the i-node is released from the in-core i-node table, and the contents of the in-core i-node are written to the disk copy of the i-node (if the two versions differ).