May 30, 2021 Article blog
In device drivers, there are two structures to be concerned about: file and inode.
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.
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;