Fundamentals 13 min read

Understanding Linux Inodes: Structure, Operations, and Link Behavior

This article explains how Linux stores file metadata in inodes, demonstrates the differences between hard and soft links through practical experiments, and provides a detailed walkthrough of the inode structure and its associated VFS operation functions.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Understanding Linux Inodes: Structure, Operations, and Link Behavior

When a question arose in a chat group about where a file’s creation time is stored, an experiment was performed to compare hard and soft links and to illustrate how the Linux kernel manages file metadata.

Link Experiment

Create a regular file test.txt and write some content.

Create a hard link to test.txt and observe its behavior.

Create a symbolic (soft) link to test.txt and test it.

Use ls -l to view inode numbers and other file information.

The hard‑link file test_hardlink shares the same inode number as test.txt, while the soft‑link test_softlink has a different inode number. This demonstrates that a hard link is merely another directory entry pointing to the same inode, whereas a symbolic link is a separate file with its own inode that stores the path to the target.

What Is an Inode?

An inode is the core VFS (Virtual File System) object that holds all metadata required by the kernel to manage a file or directory. Two kinds exist: the in‑memory VFS inode and the on‑disk filesystem‑specific inode. When a file is accessed, the on‑disk inode is read into memory, and any modifications to the VFS inode are eventually written back.

Key Inode Fields (excerpt of struct inode )

struct inode {
    umode_t          i_mode;      // permission bits (e.g., rwxrwxrwx)
    unsigned short   i_opflags;
    kuid_t           i_uid;       // owner UID
    kgid_t           i_gid;       // owner GID
    unsigned int     i_flags;     // flags like S_SYNC, S_NOATIME
    const struct inode_operations *i_op;   // pointer to operations
    struct super_block *i_sb;    // super‑block reference
    unsigned long    i_ino;       // inode number
    union { unsigned int i_nlink; unsigned int __i_nlink; }; // hard‑link count
    dev_t            i_rdev;      // device number if special file
    loff_t           i_size;      // file size
    struct timespec  i_atime;     // last access time
    struct timespec  i_mtime;     // last modification time
    struct timespec  i_ctime;     // last inode change time
    spinlock_t       i_lock;
    unsigned short   i_bytes;    // bytes in the last block
    unsigned int     i_blkbits;   // block size in bits
    blkcnt_t         i_blocks;    // number of blocks used
    unsigned long    i_state;     // state flags (I_NEW, I_LOCK, ...)
    struct mutex     i_mutex;    // inode mutex
    void            *i_private;   // filesystem‑specific private data
    /* ... many other fields omitted for brevity ... */
};

The inode stores metadata such as permissions, ownership, timestamps, size, block allocation, and links to operation tables. It does not contain the file’s actual data; that resides in separate data blocks referenced by the inode.

Inode Operations (excerpt of struct inode_operations )

struct inode_operations {
    struct dentry *(*lookup)(struct inode *, struct dentry *, unsigned int);
    void *(*follow_link)(struct dentry *, struct nameidata *);
    int (*permission)(struct inode *, int);
    struct posix_acl *(*get_acl)(struct inode *, int);
    int (*readlink)(struct dentry *, char __user *, int);
    void (*put_link)(struct dentry *, struct nameidata *, void *);
    int (*create)(struct inode *, struct dentry *, umode_t, bool);
    int (*link)(struct dentry *, struct inode *, struct dentry *);
    int (*unlink)(struct inode *, struct dentry *);
    int (*symlink)(struct inode *, struct dentry *, const char *);
    int (*mkdir)(struct inode *, struct dentry *, umode_t);
    int (*rmdir)(struct inode *, struct dentry *);
    int (*mknod)(struct inode *, struct dentry *, umode_t, dev_t);
    int (*rename)(struct inode *, struct dentry *, struct inode *, struct dentry *);
    int (*setattr)(struct dentry *, struct iattr *);
    int (*getattr)(struct vfsmount *, struct dentry *, struct kstat *);
    /* many more operations omitted */
};

These function pointers are invoked by the VFS layer to perform actions such as creating files, linking, unlinking, reading symbolic links, and managing attributes. Specific filesystems may provide their own implementations.

Common VFS Function Signatures

struct dentry *(*lookup)(struct inode *dir, struct dentry *dentry, unsigned int)
int (*create)(struct inode *dir, struct dentry *dentry, umode_t mode, bool)
int (*link)(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
int (*unlink)(struct inode *dir, struct dentry *dentry)
int (*symlink)(struct inode *dir, struct dentry *dentry, const char *symname)
int (*mkdir)(struct inode *dir, struct dentry *dentry, umode_t mode)
int (*rmdir)(struct inode *dir, struct dentry *dentry)
int (*mknod)(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
int (*rename)(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)

These interfaces are called by system calls such as create(), link(), unlink(), symlink(), mkdir(), rmdir(), mknod(), and rename() to manipulate inodes on behalf of user programs.

In summary, the inode is the kernel’s central representation of a file, containing all essential metadata while delegating actual data storage to separate blocks. Understanding its fields and the associated operation vectors is crucial for kernel developers and anyone working on Linux filesystems.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

LinuxinodevfsHard Linksoft link
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.