关于文件描述符(file_struct)

更新时间:2023-06-04 18:46:25 阅读: 评论:0

关于⽂件描述符(file_struct)
版权声明:本⽂为博主原创⽂章,遵循版权协议,转载请附上原⽂出处链接和本声明。
本⽂链接:
什么是⽂件描述符
⽂件描述符(file_struct)是⼀个⾮负整数,对于Linux内核⽽⾔,为了⾼效管理已经被打开的⽂件所创建的索引,操作系统在每个进程描述符中都提供了⽂件描述符表,⽂件描述符表中每个表项都有⼀个指向已经打开⽂件的指针;⽽已经打开的⽂件在内核中⽤file结构体表⽰,⽂件描述符中的指针指向file结构体;下⾯,我们⾸先来介绍⼀下file结构体:
什么是file结构体
file结构体定义在linux系统中的(/kernels/include/linus/fs.h)⽂件中,它的源代码如下:
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;
} f_u;
struct path    f_path;
#define f_dentry    f_path.dentry
#define f_vfsmnt   
const struct file_operations    *f_op;
spinlock_t      f_lock;  /* f_ep_links, f_flags, no IRQ */
atomic_long_t      f_count;
unsigned int        f_flags;
fmode_t        f_mode;
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_curity;
#endif
/* needed for tty driver, and maybe others */
void            *private_data;
#ifdef CONFIG_EPOLL
/* Ud by fs/eventpoll.c to link all the hooks to this file */
struct list_head    f_ep_links;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space    *f_mapping;
#ifdef CONFIG_DEBUG_WRITECOUNT
unsigned long f_mnt_write_state;
#endif
};
其中重要参数参数介绍如下:
什么是中元节f_flags:表⽰打开⽂件的权限
f_pos:表⽰当前读写⽂件的位置
f_count:这个是⼀个相对来说⽐较重要的参数,表⽰打开⽂件的引⽤计数,如果有多个⽂件指针指向它,就会增加f_count的值。
f_mode:设置对⽂件的访问模式,例如:只读,只写等。
file_operations
桥的教学反思当我们打开⼀个⽂件时,操作系统为了管理所打开的⽂件,都会为这个⽂件创建⼀个file结构体,⽽file结构体中的f_op指针⼜指向
file_operations结构体,这个结构体中的成员除了struct module* owner 其余都是函数指针,file_oper
ation就是把系统调⽤和驱动程序关联起来的关键数据结构。这个结构的每⼀个成员都对应着⼀个系统调⽤。读取file_operation中相应的函数指针,接着把控制权转交给函数,从⽽完成了Linux设备驱动程序的⼯作。
我们先来看看file_operations结构体的实现和相关成员的介绍:
struct file_operations {
struct module *owner;
小宝宝生日祝福语//指向拥有该模块的指针;
loff_t (*llek) (struct file *, loff_t, int);
//llek ⽅法⽤作改变⽂件中的当前读/写位置, 并且新位置作为(正的)返回值.
ssize_t (*read) (struct file *, char __ur *, size_t, loff_t *);
//⽤来从设备中获取数据. 在这个位置的⼀个空指针导致 read 系统调⽤以 -EINVAL("Invalid argument") 失败. ⼀个⾮负返回值代表了成功读取的字节数( 返回值是⼀个 "signed size" 类型, 常常是⽬标平台本地的整数类型).
王昭君简介
ssize_t (*write) (struct file *, const char __ur *, size_t, loff_t *);
//发送数据给设备. 如果 NULL, -EINVAL 返回给调⽤ write 系统调⽤的程序. 如果⾮负, 返回值代表成功写的字节数.
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
//初始化⼀个异步读 -- 可能在函数返回前不结束的读操作.
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
//初始化设备上的⼀个异步写.
int (*readdir) (struct file *, void *, filldir_t);
//对于设备⽂件这个成员应当为 NULL; 它⽤来读取⽬录, 并且仅对**⽂件系统**有⽤.
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
//mmap ⽤来请求将设备内存映射到进程的地址空间. 如果这个⽅法是 NULL, mmap 系统调⽤返回 -ENODEV.
int (*open) (struct inode *, struct file *);
//打开⼀个⽂件
int (*flush) (struct file *, fl_owner_t id);
//flush 操作在进程关闭它的设备⽂件描述符的拷贝时调⽤;
口角生疮int (*relea) (struct inode *, struct file *);
//在⽂件结构被释放时引⽤这个操作. 如同 open, relea 可以为 NULL.
头发少怎么办int (*fsync) (struct file *, struct dentry *, int datasync);
//⽤户调⽤来刷新任何挂着的数据.
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
//lock ⽅法⽤来实现⽂件加锁; 加锁对常规⽂件是必不可少的特性, 但是设备驱动⼏乎从不实现它.
ssize_t (*ndpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
深层搅拌桩int (*check_flags)(int);
int (*flock) (struct file *, int, struct file_lock *);
虎穴龙潭ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*tlea)(struct file *, long, struct file_lock **);
};
好了,上⾯我们介绍了file和file_operations结构体,下⾯我们来画⼀幅图,理清⼀下⽂件描述符和这两种结构体之间的关系:
关于⽂件描述符的相关应⽤
⾸先我们来看看Linux系统中所定义的三个标准⽂件描述符:
前⾯我们知道,当我们打开⼀个⽂件或者创建⼀个⽂件,操作系统就会给指向这个⽂件的指针关联⼀个⽂件描述符,并添加到当前进程下的⽂件描述符表中;那么操作系统每次会怎样分配⽂件描述符呢是这样做了,操作系统所分配的⽂件描述符是当前可分配的⽂件描述符的最⼩值!我们写⼀段代码来验证⼀下:
还要注意的⽂件描述符的分配数量是有限制的,它的可分配范围为:0~ OPEN_MAX-1;
总结
⽂件描述符(file_struct)是操作系统⽤来管理⽂件的数据结构,当我们创建⼀个进程时,会创建⽂件描述符表,进程控制块PCB中的fs指针指向⽂件描述符表,当我们创建⽂件时,会为指向该⽂件的指针FILE*关联⼀个⽂件描述符并添加在⽂件描述符表中。在⽂件描述符表中fd相当于数组的索引,FILE*相当于数组的内容吗,指向⼀个⽂件结构体。

本文发布于:2023-06-04 18:46:25,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/987739.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:描述符   结构   进程   设备
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图