Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
聊聊文件系统的原理_创想鸟

聊聊文件系统的原理

文件系统在操作系统中扮演着关键角色,为用户和应用程序提供了对文件进行操作的基础能力。聊聊文件系统的原理linux内核中,进程管理、内存管理、网络协议栈、文件系统被视为内核的四大核心模块。文件系统在内核中分为vfs(虚拟文件系统)和实际文件系统(如ext4)。vfs作为一种工厂设计模式的抽象层,向外提供标准的posix语义层;而实际文件系统则实现了特定文件功能的磁盘文件系统。具体结构如下图所示:聊聊文件系统的原理

文件系统的IO协议栈中,应用程序如果以dio方式读写文件,请求首先经过内核的vfs,然后到达实际文件系统的处理函数,接着请求进入设备映射,最后传递到块设备的IO层。在这里,调度算法和IO优化也会进行处理。块设备IO层处理完毕后,请求直接到达磁盘的驱动层,这一层通过调用IO命令对磁盘进行读写操作。聊聊文件系统的原理

在Linux中,设计理念是“一切皆文件”,这种理念在文件系统设计中得到了充分体现。内核将目录视为文件来处理。文件的inode中存储的是文件对应的数据块索引和数据,而目录的inode则存储该目录下的文件的inode和文件名称,虽然都是inode,但存储的数据不同。文件系统中的所有目录名称和文件名称存在于vfs层(仅为内存结构展示),这个结构以struct dentry表示,而文件或目录以struct inode表示。聊聊文件系统的原理

每个打开的文件在内核进程中以文件描述符存在,每个进程维护一个数组,这个数组的下标就是返回给应用的文件描述符,数组中的每个元素对应的是struct filestruct file中保存了struct dentry,而struct dentry中包含文件的inode信息。具体关系如下:聊聊文件系统的原理

vfs层提供标准文件操作的函数接口,具体的文件操作函数由实际文件系统提供。针对应用程序访问文件系统,比如执行echo "aaa" > 1.txt命令,cat命令会先根据服务目录查找文件,然后读取1.txt的文件数据,这涉及到部分POSIX函数。整个echo命令在文件系统层面(vfs和实际文件系统)会经历lookup->open->write->close的过程。接下来将重点分析write语义的函数,以内核4.18为例进行分析。

实际文件系统会定义针对文件或目录的相关操作函数,每个inode会有const struct inode_operations *i_opconst struct file_operations *i_fop,实际文件系统的相关操作函数会在__ext4_iget中为对应的inode进行赋值。以下是针对ext4本地文件系统的示例代码:

文心一言 文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

文心一言 1008 查看详情 文心一言

// 这里是以 ext4本地文件系统为例const struct inode_operations ext4_dir_inode_operations = {    // 文件创建函数    .create = ext4_create,    // 查找函数    .lookup = ext4_lookup,    /****** 省略其他的定义的函数*****/};

const struct file_operations ext4_file_operations = {.llseek = ext4_llseek,// 读函数.read_iter = ext4_file_read_iter,// 写函数.write_iter = ext4_file_write_iter,.unlocked_ioctl = ext4_ioctl,

ifdef CONFIG_COMPAT

.compat_ioctl = ext4_compat_ioctl,#endif.mmap = ext4_file_mmap,.mmap_supported_flags = MAP_SYNC,// open函数对应实际文件系统的函数.open = ext4_file_open,.release = ext4_release_file,.fsync = ext4_sync_file,.get_unmapped_area = thp_get_unmapped_area,.splice_read = generic_file_splice_read,.splice_write = iter_file_splice_write,.fallocate = ext4_fallocate,

};

当用户程序发起write的POSIX语义时,请求会进入内核的ksys_write->vfs_write->ext4_file_write_iter来完成这个write操作。整体流程如下:聊聊文件系统的原理

以下是ksys_writevfs_writevfs_write的示例代码:

// write函数进入内核态的ksys_write// fd是已经打开的文件描述符,buf是需要写入的数据,count是写入的长度ssize_t ksys_write(unsigned int fd, const char user *buf, size_t count) {// f 代表打开的文件和打开文件的flagstruct fd f = fdget_pos(fd);ssize_t ret = -EBADF;// 如果打开的文件为空,则退出if (f.file) {// 获取文件读写的位置loff_t pos = file_pos_read(f.file);// 进入vfs_write的函数,接着处理文件写操作ret = vfs_write(f.file, buf, count, &pos);if (ret >= 0)file_pos_write(f.file, pos);fdput_pos(f);}return ret;}

// vfs_write包装了ext4_file_write_iter 函数ssize_t vfs_write(struct file file, const char __user buf, size_t count, loff_t *pos) {ssize_t ret;// 判断文件是否写入,如果不能则返回错误码if (!(file->f_mode & FMODE_WRITE))return -EBADF;if (!(file->f_mode & FMODE_CAN_WRITE))return -EINVAL;if (unlikely(!access_ok(VERIFY_READ, buf, count)))return -EFAULT;// 检查文件系统可写区域以及锁检查ret = rw_verify_area(WRITE, file, pos, count);if (!ret) {if (count > MAX_RW_COUNT)count = MAX_RW_COUNT;file_start_write(file);// 调用ext4_file_write_iter 开始写数据ret = __vfs_write(file, buf, count, pos);if (ret > 0) {fsnotify_modify(file);add_wchar(current, ret);}inc_syscw(current);file_end_write(file);}return ret;}

// vfs_write是包装函数ssize_t vfs_write(struct file file, const char __user p, size_t count, loff_t *pos) {if (file->f_op->write)return file->f_op->write(file, p, count, pos);else if (file->f_op->write_iter)return new_sync_write(file, p, count, pos);elsereturn -EINVAL;}

// 把用户需要写入的数据封装为struct iovec,然后把这个iovec和fd对应的struct file,传递给时间文件系统的函数,进行文件写入。static ssize_t new_sync_write(struct file filp, const char __user buf, size_t len, loff_t ppos) {struct iovec iov = { .iov_base = (void __user )buf, .iov_len = len };struct kiocb kiocb;struct iov_iter iter;ssize_t ret;

init_sync_kiocb(&kiocb, filp);kiocb.ki_pos = *ppos;iov_iter_init(&iter, WRITE, &iov, 1, len);ret = call_write_iter(filp, &kiocb, &iter);BUG_ON(ret == -EIOCBQUEUED);if (ret > 0)    *ppos = kiocb.ki_pos;return ret;

}

// call_write_iter是直接调用f_op->write_iter函数,这里对应的是 ext4_file_write_iter,到了这里虚拟文件系统层基本已经结束,进入实际文件系统的调用过程。static inline ssize_t call_write_iter(struct file file, struct kiocb kio, struct iov_iter *iter) {return file->f_op->write_iter(kio, iter);}

以上就是聊聊文件系统的原理的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/466000.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
VSCode精简配置Vue:Vetur插件、中文提示、热重载
上一篇 2025年11月8日 05:27:31
显卡驱动更新后电脑显示器屏幕花屏的解决方法
下一篇 2025年11月8日 05:27:37

相关推荐

  • Via浏览器在鸿蒙系统上运行会闪退怎么办_Via浏览器鸿蒙系统闪退的解决方法

    Via浏览器闪退可依次尝试清除缓存数据、更新或重装应用、检查系统更新与存储空间、禁用硬件加速功能,必要时通过开发者模式启用USB调试并使用DevEco Studio捕获日志定位问题。 如果您在使用Via浏览器访问网页时,应用突然关闭或无法正常启动,则可能是由于软件兼容性或系统资源问题导致。以下是解决…

    2026年9月21日
    300
  • Linux目录结构学习常见问题汇总

    Linux目录结构学习常见问题汇总Linux目录结构学习常见问题汇总Linux目录结构学习常见问题汇总Linux目录结构学习常见问题汇总

    Linux只有一个根目录,所有设备挂载于此,形成统一树状结构。根目录下各路径分工明确:/bin和/sbin分别存放用户与管理员命令;/etc集中配置文件;/home为用户家目录;/var存储日志等动态数据;/tmp用于临时文件;/usr存放系统程序,/usr/local供手动安装软件;/dev包含设…

    2026年9月21日 用户投稿
    000
  • 计费集群部署方案

    计费集群部署方案计费集群部署方案计费集群部署方案计费集群部署方案

    1、 结合实际业务规模与历史经验数据,从CPU、内存、存储空间及网络带宽四个方面开展资源容量的预测与评估工作。 2、 根据各组件或节点的资源消耗特点,科学规划并分配适配类型的服务器资源,保障系统整体运行效率。 3、 分布式消息中间件集群对磁盘IO和网络吞吐能力要求较高,建议部署在物理机环境;而批价处…

    2026年9月21日 用户投稿
    100
  • 如何备份VSCode的全部设置和扩展?

    备份VSCode全部设置和扩展需保存配置文件与扩展目录;2. 配置文件位于各系统指定路径的User文件夹内,包含settings.json和keybindings.json;3. 通过code –list-extensions导出扩展列表并用xargs批量重装可恢复扩展;4. 推荐直接复…

    2026年9月21日
    000
  • 有趣的操作系统:文件IO和网络IO

    一、从i/o开始 在学习和使用计算机的过程中,i/o(输入/输出)是不可避免的一个概念,指的是操作、程序或设备与计算机之间发生的数据传输过程。 对于计算机来说,I/O操作和计算处理是其两大核心任务,其中大部分时间都用于执行I/O操作。I/O操作包括硬件和软件两部分,即I/O设备和I/O子系统。 I/…

    2026年9月21日
    000
  • Linux中如何查看进程状态_Linux进程状态查看的详细方法

    掌握Linux进程查看方法可高效管理程序,常用ps aux或ps -ef查看进程快照,top和htop实时监控,/proc/PID/目录下获取详细状态,pgrep和pidof快速定位PID。 在Linux系统中,查看进程状态是系统管理和故障排查中的基本操作。掌握多种方法可以更高效地监控和管理运行中的…

    2026年9月21日
    1200
  • 控制台命令(Console Command)开发

    控制台命令是程序员日常工作中不可或缺的工具,它提高了开发效率并帮助理解和控制程序运行。1) 通过简单的文本输入,完成复杂任务,如文件管理和系统监控。2) 控制台命令可用于快速调试、测试代码和自动化重复工作。3) 开发控制台命令时需注意安全性和兼容性问题。4) 控制台命令可实现有趣功能,如监控服务器资…

    2026年9月21日
    100
  • Linux如何恢复被删除的用户数据

    恢复Linux被删数据需立即停用磁盘并使用photorec或extundelete等工具,结合快照或备份可提高恢复成功率。 恢复Linux中被删除的用户数据,并非易事,但并非完全不可能。可能性取决于数据被删除的方式、删除后系统是否被继续使用,以及是否采取了合适的预防措施。核心在于理解数据删除的机制,…

    2026年9月21日
    200
  • Maingear电脑黑屏问题如何修复?专业级主机BIOS设置方法详尽

    Maingear电脑黑屏问题通常由BIOS设置、硬件接触不良或显示输出配置引起。首先应尝试进入BIOS,检查并调整显卡输出模式为PCIe/PEG,确保未误设为集成显卡;排查PCIe插槽模式兼容性,必要时切换为Gen3或Auto;若启动异常,可尝试切换UEFI/Legacy模式或恢复BIOS默认设置(…

    2026年9月21日
    000
  • mysql安装后如何优化配置文件

    答案:优化MySQL配置需先定位配置文件,再根据硬件和业务调整内存、InnoDB、连接等核心参数。具体包括设置innodb_buffer_pool_size为物理内存50%~70%,合理配置日志参数与连接数,启用慢查询日志,并使用工具辅助调优,避免过度配置,确保稳定高效。 MySQL 安装后,优化配…

    2026年9月21日
    000
  • Linux怎么列出系统中已安装的deb包

    使用dpkg -l或apt list –installed可列出已安装的.deb包,前者结合grep ^ii过滤已安装项,后者输出更清晰,两者均支持重定向保存到文件。 在Linux系统中,特别是基于Debian的发行版(如Ubuntu),可以使用命令行工具列出已安装的.deb包。最常用的…

    2026年9月21日
    000
  • VSCode的括号匹配功能如何自定义?

    可通过 settings.json 自定义括号高亮的边框和背景色;2. 用 editor.matchBrackets 控制是否启用高亮;3. 启用 bracketPairColorization 可为嵌套括号着色;4. 使用 Ctrl/Cmd + Shift + 快速跳转配对括号。 VSCode 的…

    2026年9月21日
    000
  • Linux如何使用dnf安装软件包

    dnf是Fedora、CentOS Stream和RHEL 8+的默认包管理工具,用于安装、更新、删除软件包。1. 安装单个包:sudo dnf install package_name,如htop;2. 安装多个包:sudo dnf install vim curl;3. 从本地.rpm文件安装:…

    2026年9月21日
    000
  • 在Java中如何实现线程优先级控制

    Java中线程优先级通过Thread类实现,取值范围1-10,分别对应MIN_PRIORITY、NORM_PRIORITY和MAX_PRIORITY;新线程继承父线程优先级,可通过setPriority()设置;尽管高优先级线程更可能被调度,但执行顺序不保证,因受操作系统影响;应避免依赖优先级控制关…

    2026年9月21日
    000
  • Windows11的Hyper-V虚拟机无法启动怎么解决_Windows11Hyper-V虚拟机无法启动修复方法

    首先检查BIOS中是否启用虚拟化技术,再确认Hyper-V服务运行状态,接着修复虚拟硬盘权限,尝试关闭内存完整性,检查虚拟机引导记录,最后可重装Hyper-V功能解决启动失败问题。 如果您尝试在Windows 11系统中启动Hyper-V虚拟机时遇到失败,可能是由于服务配置、权限问题或硬件兼容性导致…

    2026年9月21日
    000
  • Linux文件和目录管理常见命令

    Linux文件和目录管理依赖于ls、cd、mkdir、rm、cp、mv等核心命令,用于浏览、创建、删除、复制和移动文件与目录;通过find、du、grep等命令可查找文件、定位大文件并清理磁盘空间;使用rename、mmv或脚本可实现批量重命名;为安全起见,应谨慎使用rm命令,推荐结合-i选项或使用…

    2026年9月21日
    000
  • windows怎么禁用sticky keys粘滞键_Windows粘滞键关闭方法

    粘滞键被误触后可通过快捷键、控制面板、注册表或组策略关闭。首先连续按Shift键五次,在弹出窗口中选择关闭;其次通过控制面板的“轻松使用”设置取消勾选启用粘滞键;若需彻底禁用,可修改注册表中StickyKeys项的Flags值为506;专业版用户还可通过组策略编辑器将“启用粘滞键”设为已禁用,防止再…

    2026年9月21日
    1000
  • VSCode的代码格式化快捷键是什么?

    VSCode代码格式化快捷键为Shift+Alt+F(Windows/Linux)或Shift+Option+F(macOS),需安装对应语言的格式化工具;若无效,可能是未安装扩展、文件类型不支持或快捷键冲突;可右键选择“格式化文档”或通过命令面板执行,也可在键盘快捷方式中自定义。 VSCode的代…

    2026年9月21日
    000
  • Linux怎么踢出指定的登录用户

    要踢出指定登录用户,首先使用w或who命令识别其TTY或会话ID,再通过pkill -KILL -t 强制终止会话,或用loginctl terminate-session 优雅结束;若需防止重新登录,可临时锁定账户(passwd -l)或将用户shell改为/sbin/nologin。 在Linu…

    2026年9月21日
    000
  • 如何配置mysql初始用户和密码

    答案:MySQL安装后默认用户为root,密码为空或自动生成。需先确认服务运行,再登录并设置密码;若为空密码则直接登录后用ALTER USER修改,若为临时密码需从日志获取并强制修改;可创建远程用户并授权;推荐运行mysql_secure_installation进行安全加固,包括设密码、删匿名用户…

    2026年9月21日
    000

发表回复

登录后才能评论
关注微信