Linux中文件描述符 fd 与 flie 结构体
文件描述符
文件描述符(file descriptor)是内核为了高效管理已被打开的文件创建的索引。文件描述符的操作返回的是一个文件描述符,内核会在每个进程空间中维护一个文件描述表,所有打开的文件都将通过此表中的文件描述符来引用。(在前面的 系统 I/O中有画图解释)
文件描述符 fd 与 FILE 结构体
fd 是一个非负整数,在调用 open 时产生(每当打开一个文件时,默认打开 0,1,2),fd 起到一个索引作用,进程通过 PCB 中的文件描述符表找到该文件描述符的文件指针。文件描述符操作(open)会返回一个 fd ,内核会在每个进程中维护一个文件描述符表,所有打开的文件都将通过此表中的文件描述符来引用。
流操作(fopen)会返回一个 FLIE 结构指针,FILE 结构体中包含文件描述符,FILE 结构体可以看作是对文件描述符 fd 的一层封装,并且带有 I/O 缓存。
FILE 结构体
struct file {
/*
* fu_list becomes invalid after file_free is called and queued via
* fu_rcuhead for RCU freeing
*/
union {
struct list_head fu_list; // 文件对象链表指针
struct rcu_head fu_rcuhead; // linux 2.6内核中新的锁机制
} f_u;
struct path f_path; // 包含 dentry 和 mnt 用于确认文件路径
#define f_dentry f_path.dentry //当前文件的dentry 结构体
#define f_vfsmnt f_path.mnt // 当前文件所在的文件系统的挂载根目录
const struct file_operations *f_op; // 文件操作函数
atomic_t f_count; // 文件的引用计数(有多少进程打开该文件)
unsigned int f_flags; // 对应于 open 的 int flag 参数。
mode_t f_mode; // 读写模式
loff_t f_pos; // 文件在当前进程中的文件偏移量
struct fown_struct f_owner; // 通过信号进行 I/O 时间通知的数据。
unsigned int f_uid, f_gid; //文件所有者id,所有组 id
struct file_ra_state f_ra; // 文件预读相关
unsigned long f_version; //文件的版本号,每次使用后都自动递增
#ifdef CONFIG_SECURITY
void *f_security; // 安全措施,安全信息。
#endif
/* needed for tty driver, and maybe others */
void *private_data; // 系统在调用 open 前将这个指针置空,
#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct list_head f_ep_links; //文件的事件轮询等待者链表的头
spinlock_t f_ep_lock; // 保护 ep_links 链表的自旋锁
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping; // 指向文件空间地址的指针。
};
一个 FILE 结构体代表一个被打开的文件。系统中的每个打开的文件在内核空间都有一个关联的struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。