首页 文章 精选 留言 我的

精选列表

搜索[SpringBoot4],共10000篇文章
优秀的个人博客,低调大师

文件系统考古4:如何支持多个文件系统

Steve Kleiman 在 1986 年撰写了《Vnodes: An Architecture for Multiple File System Types in Sun UNIX》一文。这篇论文幅较短,大部分内容是数据结构的列举,以及 C 语言结构之间相互指向的图表。 Steve Kleiman是分布式文件系统领域的专家,在 Sun Microsystem 工作了多年,曾参与开发 Sun Network File System(NFS)等项目,为分布式文件系统领域做出了重要贡献。 Kleiman 希望在 Unix 中能够拥有多个文件系统,并希望这些文件系统能够共享接口和内存。具体而言,他希望设计一个能够提供以下功能的架构: 一个可以支持多个实现的通用接口; 支持 BSD FFS,以及两个远程文件系统 NFS 和 RFS,还有特定的非 Unix 文件系统,如MS-DOS; 接口定义的操作需要是原子性的。 并且,能够在不影响性能的情况下动态地处理内存和数据结构,支持重入(reentrant) 和多核,并且具有一定面向对象进行编程的特性。 重入(reentrant) 是指程序或子程序在尚未完成上一次调用之前,可以再次被调用且不会出错或发生冲突。 两个抽象概念 Steven 研究了文件系统的各种操作,决定将他们抽象为两个概念: vfs,虚拟文件系统,代表文件系统 vnode,虚拟 inode,代表文件 vfs,虚拟文件系统,它提供统一的接口,使操作系统可以以一致的方式访问不同的文件系统,无论是本地文件系统还是网络文件系统。 vnode,虚拟 inode, 表示一个文件,每个文件都有一个相关联的索引节点,其中包含了文件的元数据(如文件权限、所有者、大小等)以及指向文件数据存储位置的指针。 采用了 C++风格(实际使用 C 语言),每一个类型会匹配一个虚函数表,通过虚函数表,系统在运行时根据对象的实际类型来调用适当的虚函数,实现动态绑定: 对于 vfs 类型,其虚函数表 struct vfsops,包含了一系列的函数指针,用来执行诸如 mount、unmount、sync 和 vget 等操作。在论文的后面,会解释这些函数的原型和功能; 对于 vnode 类型也是类似的,其虚函数表 struct vnodeops,包含 open、rdwr 和 close 等函数,还有create、unlink 和 rename 等函数。一些函数是针对特定的文件类型的,比如 readlink、mkdir、readdir 和 rmdir。 通过 vfs 对象来进行跟踪实际的挂载,其虚函数表 struct vfsops 指向适用于该特定子树的文件系统操作。 类似地,vnode 实例用来进行跟踪打开的文件。它包含 struct *vnodeops 指针,作为 vfs 的一部分,有指针 struct *vfs 指向文件系统实例。 vfs 和 vnode 这两个结构体都需要一些用于存储特定实现数据的字段(如“子类私有字段”)。他们都以 caddr_t ...data 指针结尾。这些私有数据并不是 vfs 和 vnode 的一部分,而是位于其他位置,并通过指针进行引用。 Vnodes 实操 在论文中,有一整页的内容专门用于展示各种相互指向的结构。乍一看可能会感到困惑,但一旦追踪下来,就会发现它非常直观和优雅。 Kleiman 详细解释了如何使用 lookuppn() 函数来解释事物的工作原理,该函数替代了传统 Unix 中的 namei() 函数。类似于 namei() ,这个函数接受一个路径,并返回表示该路径所代表的 vnode 的 struct vnode 指针。 路径遍历始于根 vnode 或当前进程的当前目录 vnode,具体取决于路径的第一个字符是否为/。 然后,这个函数会依次取出路径的每一个子项,并调用当前 vnode 的 lookup 函数,它接受一个路径子项和一个假设是目录的当前 vnode,并返回代表那个子项的 vnode。 当一个目录是个挂载点,它的 vfsmountedhere 会被设置为一个指向 struct vfs 的指针。lookuppn 函数会跟随这个指针,并调用 vfs 的根函数,以获取该文件系统的根 vnode,替换当前正在处理的 vnode。 反过来也是可能的:当解析父目录(".. ")时,如果当前 vnode 的 "flags" 字段中设置了根标志,我们会跟随 vfsmountedhere 指针从当前 vnode 到 vfs。然后,我们可以使用该 vfs 中的 vnodecovered 字段来获取上层文件系统的 vnode。 无论如何,在成功完成后,会返回一个 struct vnode 指针,即所使用的路径。 新增的系统调用 为了使系统高效地运行,需要添加一些新的系统调用来完善接口。 在 Unix 的历史中,我们看到引入了 statsfs 和 fstatsfs ,通过这两个函数可以获得与用户空间中的文件系统进行交互的接口。getdirentries 函数可以让用户一次性获取多个目录条目(取决于提供的缓冲区大小),这大大加快了远程文件系统的目录读取速度。 在 Linux 系统中 通过查看 Linux 内核源代码,我们可以找到 Kleiman 设计的总体结构,尽管 Linux 内核的复杂性和丰富性掩盖了其中大部分内容。Linux 内核拥有丰富的文件系统类型,并且还添加了许多在 40 年前的 BSD 中不存在的功能。因此,我们可以找到更多的数据结构和系统调用,它们被用于实现命名空间、配额、属性、只读模式、目录名称缓存等功能。 文件 如果你仔细观察,原始的结构仍然可以找到:Linux 内存中的文件相关结构分为两部分,一个是已打开的文件,它是一个带有当前位置的 inode;另一个是 inode,它代表整个文件。 我们可以在此处找到[文件对象](](https://github.com/torvalds/linux/blob/v6.3/include/linux/fs.h#L942C3-L981),struct file 的实例。在文件的所有其他内容中,最值得注意的是一个字段 loff_t f_pos,它表示文件当前位置距离文件起始位置的偏移量(以字节为单位)。 文件的类是通过一个虚函数表来定义。我们可以找到一个指针 struct file_operations *f_op 。它展示了文件可以执行的所有操作,其中最常见的是打开(open)、关闭(close)、定位(lseek)、读取(read)和写入(write)。 文件还包含指向 inode 的指针,即 struct inode *f_inode。 索引节点 对于不需要偏移量的文件操作,它们是针对整个文件进行的,定义为 struct inode *。 查看此处的定义。我们可以看到这里还有其他的定义,40 年前的 BSD 中没有类似的定义,比如 ACL(访问控制列表)和属性(attributes)。 我们发现 inode 的类通过虚函数表来定义,即 struct inode_operations *i_op。同样的,这其中很多函数涉及新特性,比如 ACL(访问控制列表)和扩展属性,但我们也会找到我们期望的功能,比如链接(link)、删除(unlink)、重命名(rename)等。 Inode 还包含一个指向文件系统的指针,即 struct super_block *i_sb。 超级块 挂载点用 struct super_block 来表示,在此处查看其定义。同样地,它有 struct super_operations *s_op 定义的各个操作,在此处查看其定义。 支持的文件系统不再有限,可以通过内核模块动态地添加新的文件系统,通过数据结构 struct file_system_type 来表示,它只有一个用于创建 superblock 的工厂函数 mount。 小结 Unix 发生了变化。它的运行时变得更加复杂,增加了许多新的功能,并增加了系统调用。系统变得更有结构。 但是,由 Steve Kleiman 和 Bill Joy(BSD 操作系统的共同创始人之一) 构思的原始设计和数据结构仍然存在,在当前的 Linux 系统中仍然可以找到,虽然已经过去了40年。 回顾 文件系统考古1 :1974-Unix V7 File System 文件系统考古2:1984 - BSD Fast Filing System 文件系统考古 3:1994 - The SGI XFS Filesystem

优秀的个人博客,低调大师

CANN开发实践:4个DVPP内存问题的典型案例解读

摘要:由于DVPP媒体数据处理功能对存放输入、输出数据的内存有更高的要求(例如,内存首地址128字节对齐),因此需调用专用的内存申请接口,那么本期就分享几个关于DVPP内存问题的典型案例,并给出原因分析及解决方法。 本文分享自华为云社区《FAQ_DVPP内存问题案例》,作者:昇腾CANN。 DVPP是昇腾AI处理器内置的图像处理单元,通过AscendCL媒体数据处理接口提供强大的媒体处理硬加速能力,主要功能包括图像编解码、视频编解码、图像抠图缩放等。 由于媒体数据处理功能对存放输入、输出数据的内存有更高的要求(例如,内存首地址128字节对齐),因此需调用专用的内存申请接口,那么本期就分享几个关于DVPP内存问题的典型案例,并给出原因分析及解决方法: 使用错误的DVPP内存申请接口,导致应用程序报错并退出 内存大小不符合DVPP的要求,导致应用程序报错并退出 DVPP内存被提前释放,导致视频流解码输出的图像异常 DVPP读/写内存地址无效,导致应用程序异常中断 01 使用错误的DVPP内存申请接口,导致应用程序报错并退出 现象描述 从日志存放路径(默认为“$HOME/ascend/log”)下获取运行应用程序的日志,日志中的报错示例如下: device:0 chn 0, input buffer is invalid, make sure it has been allocated with hi_mpi_dvpp_malloc or acldvppMalloc. device:0 chn 0, output buffer is invalid, make sure it has been allocated with hi_mpi_dvpp_malloc or acldvppMalloc. 可能原因 根据日志提示,是因为没有使用指定的接口申请内存,导致内存地址校验出错。 由于DVPP媒体数据处理功能对存放输入、输出数据的内存有更高的要求(例如,内存首地址128字节对齐),因此需调用专用的内存申请接口,如下: 调用媒体数据处理V1版本的接口对图片进行抠图、缩放等操作时,调用acldvppMalloc接口申请内存。 调用媒体数据处理V2版本的接口对图片进行抠图、缩放等操作时,调用hi_mpi_dvpp_malloc接口申请内存。 处理步骤 检查代码,确认在DVPP媒体数据处理的各功能中,是否使用acldvppMalloc接口/ hi_mpi_dvpp_malloc接口申请存放输入或输出数据的Device内存。 但需注意: 可将DVPP媒体数据处理的输出作为模型推理的输入,从性能角度,减少拷贝,实现内存复用。 由于DVPP媒体数据处理访问的专用地址空间有限,为确保媒体数据处理时内存足够,除媒体数据处理功能外,其它使用Device内存的功能,建议调用aclrtMalloc接口申请内存。 02 内存大小不符合DVPP的要求,导致应用程序报错并退出 现象描述 从日志存放路径(默认为“$HOME/ascend/log”)下获取运行应用程序的日志,日志中的报错示例如下: buffer size(3110400) is smaller than need buffer size(4147200) when format is 3. device 0, vpc end address is illegal, check allocated buffer size: configured buffer size: 3110400, current pic: format 3 width_stride 1920 height_stride 1080. 可能原因 虽然使用了正确的DVPP内存申请接口,但: 代码中申请的内存大小小于该格式所需的输入或输出内存大小; 或者传入接口的内存大小正常,与输入格式也匹配,但是超出了实际申请的内存大小,所以校验出来结束地址非法。 处理步骤 1. 进入昇腾文档中心(https://www.hiascend.com/zh/document),拖动到“推理”区域,通过API参考进入最新版本的文档(或者可以在左上方选择需要的版本),在媒体数据处理章节,根据DVPP各功能对内存大小的要求,检查代码中对应格式的内存大小是否正确; 2. 在代码中增加打印内存长度的日志,检查传入接口的内存大小是否与实际申请的内存大小一致。 03 DVPP内存被提前释放,导致视频流解码输出的图像异常 现象描述 原始H264/H265每一帧视频流正常,解码过程无异常(无异常日志),仅输出图片有异常。 可能原因 解码过程无异常,说明送入的视频码流不是异常码流,仅输出被破坏,可能由于: 输出内存被复用、被踩或者被提前释放; 解码需要的输出内存比实际申请的内存大。 处理步骤 对于DVPP内存申请接口,增加日志打印内存大小及地址,检查VDEC输出内存,检查申请的内存大小是否与实际使用的一致,比如典型的错误场景,VDEC解码输出格式预期是RGB,实际仍按照YUV420SP申请内存。 在DVPP内存释放接口处、以及hi_mpi_vdec_get_frame/aclvdecCallback/acldvppJpegDecodeAsync接口处,增加内存大小及地址的打印日志,确认内存释放时序,是否存在内存地址解码完成前被提前释放的情况。 04 DVPP读/写内存地址无效,导致应用程序异常中断 现象描述 从日志存放路径(默认为“$HOME/ascend/log”)下获取运行应用程序的日志,Device侧内核态日志报错图像处理模块异常,报错示例如下: vpc get err int: vpc_cvdr_axi_rd_resp_err vpc get err int: vpc_cvdr_axi_wr_resp_err 可能原因 cvdr_axi_rd_resp_err:表示读地址越界,可能申请的输入内存太小或内存地址无效,昇腾AI处理器执行读操作时访问到了无效地址。 cvdr_axi_wr_resp_err:表示写地址越界,可能申请的输出内存太小或内存地址无效,昇腾AI处理器执行写操作时访问到了无效地址。 处理步骤 1. 在申请DVPP内存的接口处、以及在异常任务接口处增加日志打印,检查申请的输入\输出内存大小与实际使用的输入\输出内存大小是否一致; 2. 在释放DVPP内存的接口处增加打印日志,检查任务完成之前是否存在内存被提前释放的情况。 05 更多介绍 [1]昇腾文档中心 [2]昇腾社区在线课程 [3]昇腾论坛 点击关注,第一时间了解华为云新鲜技术~

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册