Linux内核之最核心数据结构之一:struct file(三十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:Linux内核之最核心数据结构:struct file解析

2.介绍

  • struct file是Linux内核中一个非常重要的结构体,它在文件系统中扮演着桥梁的角色,连接用户空间的应用程序和内核的文件操作。每当用户空间进程打开一个文件时,内核就会创建一个struct file实例来跟踪对该文件的所有操作。
  • struct file的作用主要体现在以下几个方面:
  1. 跟踪文件访问模式struct file中的f_mode字段用来存储文件的用户访问模式,如只读(O_RDONLY)、只写(O_WRONLY)或读写(O_RDWR)。这告诉内核该文件应该以何种方式被访问,以便内核可以进行相应的权限检查和文件状态管理。
  2. 实现随机访问:通过f_pos字段,struct file记录了当前文件的位置,使得进程可以进行随机读写。每次文件操作后,内核会更新这个位置,以便下一次操作可以从这个位置继续。
  3. 版本控制f_version字段用于标识文件的版本,这在多线程环境中非常重要,可以确保一个文件的并发读写操作不会因为不同进程的读写而产生数据不一致的问题。
  4. 存储文件操作f_op字段是一个指向struct file_operations的指针,这个结构体定义了文件的各个操作函数,如读(read)、写(write)、定位(lseek)等。当用户空间进程请求进行文件操作时,内核会调用这些函数来执行具体的操作。
  5. 维护文件引用计数f_count字段用于维护文件描述符的使用计数。每当进程打开一个文件时,计数会增加;当文件被关闭时,计数会减少。这个计数对于确保文件在多个进程间正确共享非常重要。
  6. 进程间通信f_owner字段包含了拥有该文件描述符的进程的PID,这有助于内核确定文件操作的权限,例如,只有拥有者进程才能执行某些特定的文件操作。
  7. 路径名和Dentryf_name字段通常存储文件路径名,而f_dentry字段则指向一个struct dentry,它代表了文件系统中的一个目录项。通过这个目录项,内核可以访问到文件的详细信息,如文件类型、大小、权限等。
  8. 文件锁和同步f_flags字段包含了文件的各种标志,如是否被锁定(FILE_LOCKED)等。这些标志可以帮助内核管理文件的并发访问,确保数据的一致性和完整性。
  9. 私有数据private_data字段允许struct file的实现者存储与特定文件类型相关的私有数据。这为文件操作提供了极大的灵活性,使得内核开发者可以根据不同类型的文件实现特定的行为。
  • 总结来说,struct file结构体是Linux内核文件系统的一个核心组件,它不仅为用户空间进程提供了一个与文件交互的接口,还内核提供了一种方式来跟踪和管理这些交互。通过struct file,内核能够高效地处理文件访问、同步和权限控制等复杂任务,确保了文件系统的稳定性和可靠性。

3.代码实例

<1>.struct file结构体

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;
	spinlock_t		f_lock;
	enum rw_hint		f_write_hint;
	atomic_long_t		f_count;
	unsigned int 		f_flags;
	fmode_t			f_mode;
	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
	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;
} 

<2>.struct file结构体每个字段注释

1.f_u:
一个联合体,用于表示文件使用的数据结构。可以根据不同的使用方式选择存储在 fu_llist 中或者 fu_rcuhead 中。

2.fu_llist:
用于将文件链接到文件系统的文件使用链表中。

3.fu_rcuhead:
用于在文件引用计数为零时释放文件资源。

4.f_path:
表示文件的路径信息,包括目录项和 dentry 项。

5.f_inode:
指向文件的 inode 结构体,用于表示文件在文件系统中的详细信息。这是一个缓存值,可以用于快速访问文件的 inode。

6.f_op:
指向文件的操作函数表,包含了文件操作的函数指针。

7.f_lock:
自旋锁,用于保护与文件相关的链接列表和标志位。在非中断上下文中使用。

8.f_write_hint:
用于存储对文件的写入操作的提示,用于优化写入操作。

9.f_count:
原子长整型,表示文件的引用计数。

10.f_flags:
存储文件的标志位,用于表示文件的打开模式和属性。

11.f_mode:
存储文件的打开模式,用于表示文件的访问权限。

12.f_pos_lock:
互斥锁,用于保护文件的位置信息。

13.f_pos:
文件的当前读/写位置。

14.f_owner:
用于存储文件的所有者信息。

15.f_cred:
指向与文件关联的安全凭证信息。

16.f_ra:
与文件相关的读取加速信息。

17.f_version:
文件的版本号。

18.f_security:
与文件相关的安全信息,若配置了安全模块则存在,否则为空。

19.private_data:
用于存储文件的私有数据,由文件操作函数使用。

20.f_ep_links:
用于在 epoll 事件轮询机制中链接所有与此文件相关的 hooks。

21.f_tfile_llink:
用于链接到 tracefs 文件系统的跟踪文件。

22.f_mapping:

23.指向文件的地址空间对象,表示文件的数据存储方式。

24f_wb_err:
文件的写入错误信息。

25. __randomize_layout 和 __attribute__((aligned(4))) 
是对结构体布局和对齐的优化选项。

<3>.struct rcu_head结构体定义:用于在文件引用计数为零时释放文件资源。

struct callback_head {
	struct callback_head *next;
	void (*func)(struct callback_head *head);
} __attribute__((aligned(sizeof(void *))));

#define rcu_head callback_head

定义回调函数

<4>.struct path结构体定义:表示文件的路径信息,包括目录项和 dentry 项。

private/msm-google/include/linux/path.h

struct path {
	struct vfsmount *mnt;
	struct dentry *dentry;
} __randomize_layout;

struct vfsmount结构体

struct vfsmount {
	struct dentry *mnt_root;	/* root of the mounted tree */
	struct super_block *mnt_sb;	/* pointer to superblock */
	int mnt_flags;
	ANDROID_KABI_RESERVE(1);
	ANDROID_KABI_RESERVE(2);
	ANDROID_KABI_RESERVE(3);
	ANDROID_KABI_RESERVE(4);
	void *data;
} __randomize_layout;

struct dentry结构体

struct dentry {
	/* RCU lookup touched fields */
	unsigned int d_flags;		/* protected by d_lock */
	seqcount_t d_seq;		/* per dentry seqlock */
	struct hlist_bl_node d_hash;	/* lookup hash list */
	struct dentry *d_parent;	/* parent directory */
	struct qstr d_name;
	struct inode *d_inode;		/* Where the name belongs to - NULL is
					 * negative */
	unsigned char d_iname[DNAME_INLINE_LEN];	/* small names */

	/* Ref lookup also touches following */
	struct lockref d_lockref;	/* per-dentry lock and refcount */
	const struct dentry_operations *d_op;
	struct super_block *d_sb;	/* The root of the dentry tree */
	unsigned long d_time;		/* used by d_revalidate */
	void *d_fsdata;			/* fs-specific data */

	union {
		struct list_head d_lru;		/* LRU list */
		wait_queue_head_t *d_wait;	/* in-lookup ones only */
	};
	struct list_head d_child;	/* child of parent list */
	struct list_head d_subdirs;	/* our children */
	/*
	 * d_alias and d_rcu can share memory
	 */
	union {
		struct hlist_node d_alias;	/* inode alias list */
		struct hlist_bl_node d_in_lookup_hash;	/* only for in-lookup ones */
	 	struct rcu_head d_rcu;
	} d_u;

	ANDROID_KABI_RESERVE(1);
	ANDROID_KABI_RESERVE(2);
} __randomize_layout;

<5>.const struct file_operations结构体定义:指向文件的操作函数表,包含了文件操作的函数指针。

struct file_operations {
	struct module *owner;
	loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
	ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
	ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
	int (*iterate) (struct file *, struct dir_context *);
	int (*iterate_shared) (struct file *, struct dir_context *);
	__poll_t (*poll) (struct file *, struct poll_table_struct *);
	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 *);
	unsigned long mmap_supported_flags;
	int (*open) (struct inode *, struct file *);
	int (*flush) (struct file *, fl_owner_t id);
	int (*release) (struct inode *, struct file *);
	int (*fsync) (struct file *, loff_t, loff_t, int datasync);
	int (*fasync) (int, struct file *, int);
	int (*lock) (struct file *, int, struct file_lock *);
	ssize_t (*sendpage) (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 (*setlease)(struct file *, long, struct file_lock **, void **);
	long (*fallocate)(struct file *file, int mode, loff_t offset,
			  loff_t len);
	void (*show_fdinfo)(struct seq_file *m, struct file *f);
#ifndef CONFIG_MMU
	unsigned (*mmap_capabilities)(struct file *);
#endif
	ssize_t (*copy_file_range)(struct file *, loff_t, struct file *,
			loff_t, size_t, unsigned int);
	int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t,
			u64);
	int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t,
			u64);
	int (*fadvise)(struct file *, loff_t, loff_t, int);

	ANDROID_KABI_RESERVE(1);
	ANDROID_KABI_RESERVE(2);
	ANDROID_KABI_RESERVE(3);
	ANDROID_KABI_RESERVE(4);
} __randomize_layout;

文件操作的回调函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/498906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

国外的Java面试题和国内的相比谁更卷

前言 有很多朋友很好奇国外的Java面试题长啥样&#xff0c;今天我们就去找5道国外的面试来和国内的对比一下看看谁难一些&#xff01; 面试题分享 1. Is Java Platform Independent if then how?&#xff08; Java平台是独立的吗&#xff1f;&#xff09; Yes, Java is a…

三思多功能智慧综合杆助推上海杨浦区数智化升级

旧貌换新颜。上海三思为上海杨浦区政和路、政悦路、殷高东路等城市道路建成多功能综合智慧杆200余杆&#xff0c;让城市面貌焕然一新&#xff0c;智慧杨浦再上新台阶。 本项目通过集约化建设手段&#xff0c;有力地推动管理部门从粗放式管理向精细化管理转型。项目的实施促进道…

机器学习算法的另一个分支-贝叶斯算法原理(贝叶斯要解决什么问题)

目录 一、贝叶斯简介 二、贝叶斯要解决的问题 三、例子&#xff08;公式推导&#xff09; 四、实例 1. 拼写纠正实例 2. 垃圾邮件过滤实例 一、贝叶斯简介 1. 贝叶斯&#xff1a;英国数学家。1702年出生于伦敦&#xff0c;做过神甫。贝叶斯在数学方面主要研究概率论.对于…

Request对象

目录 1、GET方法 2、POST方法 引出问题&#xff1a;我们前面在赋值的时候&#xff0c;都是在一个页面进行赋值&#xff0c;那么怎么样将web1的数据传送到web2中呢&#xff0c;这时候&#xff0c;就要用到request方法了。 作用&#xff1a;Request对象主要是让服务器取得客户…

蓝桥杯算法题练习

1、20世纪有多少个星期一 &#xff08;1901、1、1——2000、12、31&#xff09; 方法一&#xff1a;python代码 方法二&#xff1a;excel工具(设置单元格格式&#xff0c;把日期换成周几的形式) 2、100个数相乘&#xff0c;结果有几个0 3、切面条 找规律:对折次数n 弯2^n-1 面…

公众号 服务号 代码创建菜单方法 公众号跳转小程序功能 40027错误的解决

需求 通过代码实现微信公众号的自定义菜单&#xff0c;新增、同步菜单。 分析 其实对一个公众号而言&#xff0c;菜单只要创建一次就可以了&#xff0c;如果你不是服务商&#xff0c;可以直接使用微信提供的代码调试工具&#xff0c;直接发送json字符串&#xff0c;为自己的…

系统开发实训小组作业week5 —— 用例描述与分析

目录 4.3 UC003电影浏览与查询 4.3.1 用例描述 4.3.2 活动图 4.3.3 界面元素 4.3.4 功能 4.4 UC004在线订票 4.4.1 用例描述 4.4.2 活动图 4.4.3 界面元素 4.4.4 功能 4.3 UC003电影浏览与查询 4.3.1 用例描述 用例号 UC003-01 用例名称 电影浏览与查询 用例描述…

App 测试必备 - 建议所有测试人收藏

移动端App性能测试需要关注多个方面&#xff0c;包括响应时间、稳定性、内存使用、CPU使用率、网络性能、电池消耗以及设备兼容性等。通过综合考虑这些方面&#xff0c;并在不同条件下进行全面的测试&#xff0c;可以确保应用程序在各种情况下都能够提供优质的用户体验&#xf…

AI人像写真解决方案,满足企业多样化视觉需求

美摄科技&#xff0c;作为一家专注于人工智能技术研发与应用的高新企业&#xff0c;深知企业对于高质量、高效率视觉内容的需求&#xff0c;特推出AI人像写真解决方案&#xff0c;为企业打开全新的视觉营销通道。 我们的AI人像写真解决方案&#xff0c;基于深度学习和计算机视…

解密EMC与EMI:电磁兼容性与电磁干扰?|深圳比创达电子

在现代电子设备愈发普及的时代&#xff0c;EMC&#xff08;Electromagnetic Compatibility&#xff09;和EMI&#xff08;Electromagnetic Interference&#xff09;成为了不容忽视的重要议题。本文将从根本概念出发&#xff0c;逐步深入探讨这两个关键领域&#xff0c;带领各位…

【信贷后台管理之登录(一)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录结构一、项目搭建二、登录页面1.引入Element-ui2.LoginView.vue组件3.router文件的index.js引入组件 gitee仓库地址 目录结构 一、项目搭建 找到存放项目的文件…

解析旅游者心声:用PySpark和SnowNLP揭秘景区评论的情感秘密

简介: 在本篇博客中,我们将探讨如何利用PySpark和SnowNLP这两个强大的工具来分析大规模的旅游评论数据。通过结合携程和去哪儿的数据作为示例,我们将探索如何从海量的评论中提取有价值的情感信息和洞察。PySpark作为一种分布式计算框架,能够处理大规模的数据集,为我们提供…

Java服务运行在Linux----维护常用命令

想起来哪些再添加上去 查看Java程序进程 jps -l 查出进程后根据pid 查询程序所在目录 pwdx 31313 根据端口查找PID 根据pid杀死程序 kill -p 31313 查看目录下所有包含9527的文件 grep -rn 9527 查看磁盘空间 查找文件名"nginx"文件或模糊查找"*nginx*&quo…

Mysql中如何显示第几周

在数据分析中&#xff0c;经常需要对日期和时间进行格式化处理&#xff0c;以便更直观地展示和理解数据。 MySQL 5.7提供了强大的DATE_FORMAT函数&#xff0c;允许用户根据特定的格式字符串来显示日期和时间。 Week函数 最直接的是使用YEAR、WEEK函数 SELECTYEAR(NOW()) AS C…

健身运动耳机哪个牌子好?力荐五大品质翘楚的精品

健身已经成为许多人追求健康与活力的重要方式&#xff0c;而在健身的过程中&#xff0c;一款优质的耳机不仅能让你沉浸于音乐的世界&#xff0c;更能提升运动体验&#xff0c;激发无限潜能&#xff0c;那么如何选择一款既适合运动又品质卓越的耳机呢&#xff1f;今天我这个健身…

【热门话题】Yarn:新一代JavaScript包管理器的安装与使用

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Yarn&#xff1a;新一代JavaScript包管理器的安装与使用引言一、Yarn的安装1. 系…

element-ui inputNumber 组件源码分享

今日简单分享 inputNumber 组件的实现原理&#xff0c;主要从以下四个方面来分享&#xff1a; 1、inputNumber 组件的页面结构 2、inputNumber 组件的属性 3、inputNumber 组件的事件 4、inputNumber 组件的方法 一、inputNumber 组件的页面结构。 二、inputNumber 组件的…

linux安装Zookeeper的详细步骤

1.Java环境确认 确保已经安装了Java环境&#xff0c;没有的自行安装 2.官网下载包 Apache ZooKeeper 3.安装 3.1上传到linux&#xff0c;解压 我的目录为/root/apache-zookeeper-3.8.4-bin 进入到/root/apache-zookeeper-3.8.4-bin/conf目录下&#xff0c;执行命令复制zoo…

由浅到深认识Java语言(44):Junit单元测试

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

硬件12、PCB模块化布局

模块画布局其实就是根据原理图中绘制的小模块&#xff0c;比如3.3V芯片及其外围电路部分的元器件在PCB中放在一起进行布线&#xff0c;会方便很多 1、最好打开分屏&#xff0c;一边在原理图中选中模块&#xff0c;一边在PCB中绘制 2、选中原理图中的模块的所有元件&#xff0…