在設(shè)備驅(qū)動程序中,一般需要關(guān)心兩個結(jié)構(gòu)體:file 和 inode。
1. file 結(jié)構(gòu)體
file 結(jié)構(gòu)體代表一個打開的文件,系統(tǒng)中每個打開的文件在內(nèi)核空間都有一個關(guān)聯(lián)的 struct file。
它由內(nèi)核在打開文件時創(chuàng)建,并傳遞給在文件上進(jìn)行操作的任何函數(shù)。在文件的所有實(shí)例都關(guān)閉后,內(nèi)核釋放這個數(shù)據(jù)結(jié)構(gòu)。
注:在內(nèi)核和驅(qū)動源代碼中,struct file 的指針通常被命名為 file 或 filp(即 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;/* 和文件關(guān)聯(lián)的操作 */
/*
* 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;/* 文件標(biāo)志,如O_RDONLY、O_NONBLOCK、O_SYNC */
fmode_t f_mode;/* 文件讀/寫模式,F(xiàn)MODE_READ、FMODE_WRITE */
struct mutex f_pos_lock;
loff_t f_pos;/* 當(dāng)前讀寫位置 */
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; /* 文件私有數(shù)據(jù) */
#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];
};
文件讀/寫模式 mode、標(biāo)志 f_flags 都是設(shè)備驅(qū)動關(guān)心的內(nèi)容,而私有數(shù)據(jù)指針 private_data 在設(shè)備驅(qū)動中被廣泛應(yīng)用,大多被指向設(shè)備驅(qū)動自定義以用于描述設(shè)備的結(jié)構(gòu)體。
2. inode 結(jié)構(gòu)體
VFS inode 包含文件訪問權(quán)限、屬主、組、大小、生成時間、訪問時間、最后修改事件等信息。它是 Linux 管理文件系統(tǒng)的基本單位,也是文件系統(tǒng)連接任何子目錄、文件的橋梁,inode 結(jié)構(gòu)體的定義如下:
struct inode {
umode_t i_mode;
/* inode的權(quán)限 */
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;
/* 若是設(shè)備文件,此字段將記錄設(shè)備的設(shè)備號 */
loff_t i_size;
/* inode所代表的文件大小 */
struct timespec i_atime;
/* inode最近一次的存取時間 */
struct timespec i_mtime;
/* inode最近一次的修改時間 */
struct timespec i_ctime;
/* inode的產(chǎn)生時間 */
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數(shù),一個block為512字節(jié) */
#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;
/* 若是塊設(shè)備,為其對應(yīng)的block_device結(jié)構(gòu)體指針 */
struct cdev *i_cdev;
/* 若是字符設(shè)備,為其對應(yīng)的cdev結(jié)構(gòu)體指針 */
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;