Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Linux file structures and inode structures


May 30, 2021 Article blog



In device drivers, there are two structures to be concerned about: file and inode.

1. file structure

The file structure represents an open file, and each open file in the system has an associated struct file in the kernel space.

It is created by the kernel when the file is opened and passed to any function that operates on the file. After all instances of the file are closed, the kernel releases this data structure.

Note: In the kernel and drive source code, the pointer to the struct file is usually named file or file pointer.

struct file {
        union {
           struct llist_node         fu_llist;
           struct rcu_head          fu_rcuhead;
        } 
        f_u;
        struct path               f_path;
        struct inode              *f_inode;/* cached value */
        const struct file_operations      *f_op;/* 和文件关联的操作 */
        /*
         * Protects f_ep_links, f_flags.
         * Must not be taken from IRQ context.
         */
        spinlock_t                f_lock;
        enum rw_hint              f_write_hint;
        atomic_long_t              f_count;
        unsigned int              f_flags;/* 文件标志,如O_RDONLY、O_NONBLOCK、O_SYNC */
        fmode_t                 f_mode;/* 文件读/写模式,FMODE_READ、FMODE_WRITE */
        struct mutex              f_pos_lock;
        loff_t                  f_pos;/* 当前读写位置 */
        struct fown_struct        f_owner;
        const struct cred        *f_cred;
        struct file_ra_state        f_ra;
        u64                f_version;

        #ifdef CONFIG_SECURITY
        void *f_security;
        #endif
        /* needed for tty driver, and maybe others */
        void *private_data; /* 文件私有数据 */
        #ifdef CONFIG_EPOLL
        /* Used by fs/eventpoll.c to link all the hooks to this file */
        struct list_head f_ep_links;
        struct list_head f_tfile_llink;
        #endif /* #ifdef CONFIG_EPOLL */
        struct address_space *f_mapping;
        errseq_t f_wb_err;
    }
    __randomize_layout
  __attribute__((aligned(4)));/* lest something weird decides that 2 is OK */
  
    struct file_handle {
      __u32 handle_bytes;
      int handle_type;
      /* file identifier */
      unsigned char f_handle[0];
    };


File read/write mode, flag, f_flags are all device-driven concerns, while private data pointers private_data are widely used in device drivers, mostly pointing to device-driven customizations to describe the structure of the device.


2. Inode structure

VFS inode contains information such as file access, ownership, group, size, build time, access time, and final modification events. It is the basic unit of Linux's management file system and the bridge to any subdirectories or files connected to the file system, as defined by the inode structure as follows:


struct inode {

        umode_t                        i_mode;

/* inode的权限 */

        unsigned short                i_opflags;

        kuid_t                        i_uid;

/* inode拥有者的id */

        kgid_t                        i_gid;

/* inode所属的群组id */

        unsigned int                i_flags;

#ifdef CONFIG_FS_POSIX_ACL

        struct posix_acl        *i_acl;

        struct posix_acl        *i_default_acl;

#endif

        const struct inode_operations        *i_op;

        struct super_block        *i_sb;

        struct address_space        *i_mapping;

#ifdef CONFIG_SECURITY

        void                        *i_security;

#endif

        /* Stat data, not accessed from path walking */

        unsigned long                i_ino;

        /*

         * Filesystems may only read i_nlink directly.  They shall use the

         * following functions for modification:

         *

         *    (set|clear|inc|drop)_nlink

         *    inode_(inc|dec)_link_count

         */

        union {

                const unsigned int i_nlink;

                unsigned int __i_nlink;

        };

        dev_t                        i_rdev;

/* 若是设备文件,此字段将记录设备的设备号 */

        loff_t                        i_size;

/* inode所代表的文件大小 */

        struct timespec                i_atime;

/* inode最近一次的存取时间 */

        struct timespec                i_mtime;

/* inode最近一次的修改时间 */

        struct timespec                i_ctime;

/* inode的产生时间 */

        spinlock_t                i_lock;

/* i_blocks, i_bytes, maybe i_size */

        unsigned short          i_bytes;

        unsigned int                i_blkbits;

        enum rw_hint                i_write_hint;

        blkcnt_t                i_blocks;

/* inode所使用的block数,一个block为512字节 */

#ifdef __NEED_I_SIZE_ORDERED

        seqcount_t                i_size_seqcount;

#endif

        /* Misc */

        unsigned long                i_state;

        struct rw_semaphore        i_rwsem;

        unsigned long                dirtied_when;

/* jiffies of first dirtying */

        unsigned long                dirtied_time_when;

        struct hlist_node        i_hash;

        struct list_head        i_io_list;

/* backing dev IO list */

#ifdef CONFIG_CGROUP_WRITEBACK

        struct bdi_writeback        *i_wb;

/* the associated cgroup wb */

        /* foreign inode detection, see wbc_detach_inode() */

        int                        i_wb_frn_winner;

        u16                        i_wb_frn_avg_time;

        u16                        i_wb_frn_history;

#endif

        struct list_head        i_lru;

/* inode LRU list */

        struct list_head        i_sb_list;

        struct list_head        i_wb_list; 

/* backing dev writeback list */

        union {

                struct hlist_head        i_dentry;

                struct rcu_head                i_rcu;

        };

        u64                        i_version;

        atomic_t                i_count;

        atomic_t                i_dio_count;

        atomic_t                i_writecount;

#ifdef CONFIG_IMA

        atomic_t                i_readcount;

/* struct files open RO */

#endif

        const struct file_operations        *i_fop;

/* former ->i_op->default_file_ops */

        struct file_lock_context        *i_flctx;

        struct address_space        i_data;

        struct list_head        i_devices;

        union {

                struct pipe_inode_info        *i_pipe;

                struct block_device        *i_bdev;

/* 若是块设备,为其对应的block_device结构体指针 */

                struct cdev                *i_cdev;

/* 若是字符设备,为其对应的cdev结构体指针 */

                char                        *i_link;

                unsigned                i_dir_seq;

        };

        __u32                        i_generation;

#ifdef CONFIG_FSNOTIFY

        __u32                        i_fsnotify_mask;

/* all events this inode cares about */

        struct fsnotify_mark_connector __rcu        *i_fsnotify_marks;

#endif

#if IS_ENABLED(CONFIG_FS_ENCRYPTION)

        struct fscrypt_info        *i_crypt_info;

#endif

        void                        *i_private;

/* fs or device private pointer */

__randomize_layout;