文件系统、POSIX标准及VFS

2020-03-24 10:10:03

一、POSIX标准 以及 POSIX文件接口

    POSIX(Portable Operating System Interface of UNIX)表示可移植操作系统接口,是IEEE为要在各种UNIX操作系统上运行软件,而定义API接口的一系列互相关联的标准的总称。

    POSIX标准意在期望获得源代码级别的软件可移植性。换句话说,为一个POSIX兼容的操作系统编写的程序,应该可以在任何其它的POSIX操作系统(即使是来自另一个厂商)上编译执行。

    Linux基本上逐步实现了POSIX兼容,但并没有参加正式的POSIX认证。微软的Windows NT声称部分实现了POSIX标准

简单总结:

    完成同一功能,不同内核提供的系统调用(也就是一个函数)是不同的,例如创建进程,linux下是fork函数,windows下是creatprocess函数。好,我现在在linux下写一个程序,用到fork函数,那么这个程序该怎么往windows上移植?我需要把源代码里的fork通通改成creatprocess,然后重新编译...

    Posix标准的出现就是为了解决这个问题。linux和windows都要实现基本的posix标准,linux把fork函数封装成posix_fork(随便说的),windows把creatprocess函数也封装成posix_fork,都声明在unistd.h里。这样,程序员编写普通应用时候,只用包含unistd.h,调用posix_fork函数,程序就在源代码级别可移植了。

    POSIX标准的文件接口有:close、creat、open、read、sync、write、dup、dup2、flock、fcntl、fsync、lseek、mkstemp等。

二、文件系统类型

    文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件结构称为文件管理系统,简称文件系统。

    从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,安全控制,日志,压缩,加密等。

常见的文件系统类型有:

    ext2(Extended file system),ext3,ext4

    xfs,brtfs,zfs,UFS、UFS2、HFS等

    JFS、JFS2(IBM AIX系统使用的文件系统)

    FAT16、FAT32、NTFS

    上面除了ext2不支持journal日志功能,其他都持续日志功能,同时支持日志的方式也有所不同,这些方式分别有自己特性,不过总的区别是文件安全和性能之间的取舍。

    文件系统简单来说,好比一个停车场,但是比停车场更加复杂,更加有序,读写的文件,就是通过文件系统来管理的。分区必须经过格式化后才可以使用,格式化的过程就是在分区内建立文件系统的过程。

    不同文件系统采用不同的方法来管理磁盘空间,根据存储设备的硬件特性、系统需求等有不同的应用场合。

  • ext2具有极快的速度和极小的CPU占用率,可用于硬盘和移动存储设备

  • ext3增加日志功能,可回溯追踪

  • ext4日志式文件系统,支持1EB(1024*1024TB),最大单文件16TB,支持连续写入可减少文件碎片。为rhel6默认文件系统。

  • xfs可以管理500T的硬盘。为rhel7默认文件系统。

  • brtfs文件系统针对固态盘做优化。

  • NTFS:支持最大分区2TB,最大文件2TB,安全性和稳定性非常好,不易出现文件碎片。

  • JFS2(又称 enhanced journaled file system)是最早期的日志文件系统。很早就被应用于 IBM AIX操作系统。

其他文件系统:

  • RAMFS:内存文件系统

  • ISO 9660:光盘

  • NFS:网络文件系统

  • SMBAFS/CIFS:支持Samba协议的网络文件系统

  • Linux swap:交换分区,用以提供虚拟内存。

主要由三类:

  • 基于磁盘

  • 基于网络

  • 虚拟

更多参见:文件系统概述 - Oracle Solaris 管理:设备和文件系统

为了对各类文件系统进行统一管理,Linux引入了虚拟文件系统VFS(Virtual File System),为各类文件系统提供一个统一的操作界面和应用编程接口。可以肯定的是 文件系统(FS)之下直接面对的就是硬件存储设备(的物理块层,下面还有驱动层)。

Linux系统文件架构:

User层:GLIBC ---> 内核Kernel层:SCI --> VFS --> FS --> Block layer --> Device drivers

参见:linux的VFS详解_jinking01的专栏-CSDN博客_vfs

Linux下文件系统及LVM简概【图文】_落地成盒_51CTO博客

三、VFS(virtual File System)

VFS的作用就是采用标准的Unix系统调用读写位于不同物理介质上的不同文件系统,即为各类文件系统提供了一个统一的操作界面和应用编程接口。VFS是一个可以让open()、read()、write()等系统调用不用关心底层的存储介质和文件系统类型就可以工作的粘合层。从VFS的设计原理可知,VFS之下直接面对的是文件系统(FS),这里的文件系统包括网络文件系统(例如NFS、SMBAFS)。

疑问:Windows系统有VFS吗?回答:应该是没有的,VFS按定义来看,是Unix系统采用的一种文件系统管理方式。

四、FUFS和POSIX的关系

    FUSE是(Unix)用户空间的文件系统接口,FUSE内核模块为普通应用程序与内核虚拟文件系统VFS的交互提供了一个桥梁。基于FUSE用户空间模块,开发人员可以不必了解VFS内核机制就能快速便捷地开发POSIX兼容的文件系统交互接口。

    疑问:FUFS支持Windows吗?应该不支持,Windows下没有FUFS,但是Windows上可以找到功能类似于FUFS的实现函数。

    即便是没有安装FUSE模块,通过VFS内核也能够操作各种文件系统。

参见:深入理解GlusterFS之POSIX接口

五、问一个问题:Oracle底层核心存储使用了FUSE和VFS吗?

回答:

    首先,Oracle可以不使用OS的文件管理系统,这是肯定的(很多资料都有说明)。

    其次,Oracle可以安装在NAS网络存储上,这说明,Oracle可以使用多种文件系统(例如NTFS、JFS2、EXT4、NFS)。

    另外,Oracle 11gR2提供了DBFS,可以将Oracle数据库当成文件系统来使用,兼容FUSE接口。这说明Oracle不但能使用多种文件系统,而且还可以把自己伪装成类似于NFS的网络文件系统(支持POSIX标准)。

    所以,据我分析,Oracle应该没有使用FUSE,但是在Linux下应该可以直接用VFS接口,当然也不排除Oracle不通过VFS,直接使用底层的FS,甚至FS都不用(直接用裸设备驱动)。

    ————继续研究

    我们知道Linux下在系统(OS)底层,通过LVM(Logical Volume Manager,逻辑卷管理)和LDM,将OS识别到的物理磁盘或虚拟化的逻辑磁盘进行组合,再分配给其他程序使用。而Oracle 10g R2推出了ASM(自动存储管理),这是Oracle自己提供的卷管理器,主要用于替代操作系统所提供的LVM,它不仅支持单实例,同时对RAC集群的支持也是非常好。参见:探索ORACLE之ASM概念(完整版)_内德-CSDN博客

    ASM它提供了以平台无关的文件系统、逻辑卷管理以及软RAID服务。ASM可以支持条带化和磁盘镜像,从而实现了在数据库被加载的情况下添加或移除磁盘以及自动平衡I/O以删除“热点”。

    安装Oracle的时候,文件存储方式时有几种选择:

  1. 操作系统文件系统,操作系统提供的,如AIX的JFS2,WINDOWS的NTFS等等;

  2. UNIX平台,可以直接使用裸(RAW)设备,比起使用操作系统的文件系统,有利有弊;

  3. 集群文件系统

  4. 自动存储管理 (ASM)

    具体参见这篇文章:Oracle 存储类型

    综上,答案显而易见了,Oracle可以用VFS,也可以不用VFS,感叹Oracle真是复杂、技术含量很高,人家买这么贵也是有底气的,包括网络设备F5也是一样,人家有软硬件结合的核心技术。

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本科毕业论文 Linux下文件管理与文件传送的研究与实现 目 录 摘 要 III 关键词 III Abstract III Key words III 前言 1 1 Linux操作系统 1 1.1 Linux操作系统的产生及发展 1 1.2 Linux操作系统的特点 3 1.2.1自由开放软件 3 1.2.2 真正的多任务多用户 3 1.2.3 UNIX的完整实现 3 1.2.4完全符合POSIX标准 3 1.2.5良好的用户界面 3 1.2.6 强大的网络功能 4 1.2.7 良好的可移植性 4 1.2.8设备独立性 4 2 界面设计工具——QT 5 2.1 QT发展历史 5 2.2 QT优点 5 2.2.1 优良的跨平台特性: 5 2.2.2 面向对象 6 2.2.3丰富的 API 6 2.3 KDE 和GNOME 6 2.4 QT的安装 7 2.4.1 获取源代码 7 2.4.2 解压缩 7 2.4.3 生成Makefile 7 2.4.4编译 7 2.4.5 安装 7 2.4.6 编程环境的设置 8 2.5 QT信号与槽机制 8 3 Linux虚拟文件系统 10 3.1 虚拟文件系统概述 10 3.2 VFS支持的文件系统可以划分为三种类型: 10 3.3 VFS功能 11 4 界面的实现 12 4.1发送端界面的实现 12 4.2 接收端的界面实现 13 4.3 锚接部件界面的实现 14 4.4 主窗口界面的现实 19 4.4.1 菜单栏 19 4.4.2状态栏 19 4.4.3 工具栏 19 4.4.4 中心部件 19 5 后台的实现 19 5.1 发送端后台实现 19 5.2 接收端后台实现 22 5.3锚接部件后台的实现 24 5.3.1 文件的搜索 24 5.3.2 修改文件的权限 26 5.4主窗口后台现实 27 5.4.1 文件的打开与关闭 27 5.4.2 文件的创建 27 5.4.3 文件的复制 27 5.4.4 文件的删除 28 6 结论 29 参考文献 29 致 谢 30
第1章 操作系统概述 1 1.1 认识操作系统 1 1.1.1 从使用者角度 1 1.1.2 从程序开发者角度 2 1.1.3 从操作系统在整个计算机系统中所处位置 2 1.1.4 从操作系统设计者的角度 3 1.2 操作系统的发展 4 1.2.1 操作系统的演变 4 1.2.2 硬件的发展轨迹 5 1.2.3 软件的轨迹 6 1.2.4 单内核与微内核操作系统 7 1.3 开放源代码的Unix/Linux操作系统 8 1.3.1 Unix的诞生和发展 8 1.3.2 Linux的诞生 9 1.3.3 操作系统标准POSIX 9 1.3.4 GNU和Linux 9 1.3.5 Linux的开发模式 10 1.4 Linux内核 10 1.4.1 Linux内核的位置 10 1.4.2 Linux内核的作用 11 1.4.3 Linux内核子系统 11 1.5 Linux内核源代码 13 1.5.1 多版本的内核源代码 13 1.5.2 Linux内核源代码的结构 13 1.5.3 Linux内核源代码分析工具 14 习题1 15 第2章 内存寻址 17 2.1 内存寻址简介 17 2.1.1 Intel x86 CPU寻址方式的演变 18 2.1.2 IA32寄存器简介 19 2.1.3 物理地址、虚拟地址及线性地址 21 2.2 分段机制 22 2.2.1 地址转换及保护 24 2.2.2 Linux中的段 24 2.3 分页机制 25 2.3.1 页与页表 25 2.3.2 线性地址到物理地址的转换 28 2.3.3 分页示例 28 2.3.4 页面高速缓存(cache) 29 2.3.5 Linux中的分页机制 30 2.4 Linux中的汇编语言 31 2.4.1 AT&T与Intel汇编语言的比较 31 2.4.2 AT&T汇编语言的相关知识 32 2.5 Linux系统地址映射示例 33 习题2 35 第3章 进程 37 3.1 进程介绍 37 3.1.1 程序和进程 37 3.1.2 进程的层次结构 38 3.1.3 进程状态 39 3.1.4 进程实例 40 3.2 进程控制块 41 3.2.1 进程状态 42 3.2.2 进程标识符 43 3.2.3 进程之间的亲属关系 43 3.2.4 进程控制块的存放 44 3.3 进程的组织方式 45 3.3.1 进程链表 45 3.3.2 散列表 46 3.3.3 可运行队列 47 3.3.4 等待队列 47 3.4 进程调度 48 3.4.1 基本原理 48 3.4.2 时间片 50 3.4.3 Linux进程调度时机 50 3.4.4 进程调度的依据 51 3.4.5 调度函数schedule()的实现 52 3.5 进程的创建 54 3.5.1 创建进程 55 3.5.2 线程及其创建 56 3.6 与进程相关的系统调用及其应用 58 3.6.1 fork系统调用 58 3.6.2 exec系统调用 59 3.6.3 wait系统调用 60 3.6.4 exit系统调用 62 3.6.5 进程的一生 63 3.7 与调度相关的系统调用及应用 63 习题3 65 第4章 内存管理 67 4.1 Linux的内存管理概述 67 4.1.1 虚拟内存、内核空间和用户空间 67 4.1.2 虚拟内存实现机制间的关系 69 4.2 进程用户空间的管理 70 4.2.1 进程用户空间的描述 71 4.2.2 进程用户空间的创建 74 4.2.3 虚存映射 76 4.2.4 进程的虚存区示例 76 4.2.5 与用户空间相关的系统调用 78 4.3 请页机制 79 4.3.1 缺页异常处理程序 79 4.3.2 请求调页 81 4.3.3 写时复制 83 4.4 物理内存的分配与回收 83 4.4.1 伙伴算法 85 4.4.2 物理页面的分配 86 4.4.3 物理页面的回收 88 4.4.4 slab分配模式 89 4.4.5 内核空间非连续内存区的分配 93 4.5 交换机制 95 4.5.1 交换的基本原理 95 4.5.2 页面交换守护进程kswapd 99 4.6 内存管理实例 99 4.6.1 相关背景知识 100 4.6.2 代码体系结构介绍 100 4.6.3 实现步骤 103 4.6.4 程序代码 103 习题4 108 第5章 中断和异常 110 5.1 中断的基本知识 110 5.1.1 中断向量 110 5.1.2 外设可屏蔽中断 111 5.1.3 异常及非屏蔽中断 112 5.1.4 中断描述符表 112 5.1.5 相关汇编指令 113 5.2 中断描述符表的初始化 114 5.2.1 IDT表项的设置 114 5.2.2 对陷阱门和系统门的初始化 115 5.2.3 中断门的设置 116 5.3 中断处理 116 5.3.1 中断和异常的硬件处理 116 5.3.2 中断请求队列的建立 117 5.3.3 中断处理程序的执行 119 5.3.4 从中断返回 121 5.4 中断的下半部处理机制 121 5.4.1 为什么把中断分为两部分来处理 122 5.4.2 小任务机制 122 5.4.3 下半部 124 5.4.4 任务队列 125 5.5 中断应用——时钟中断 125 5.5.1 时钟 125 5.5.2 时钟运作机制 126 5.5.3 Linux的时间系统 127 5.5.4 时钟中断处理程序 128 5.5.5 时钟中断的下半部处理 129 5.5.6 定时器及其应用 129 习题5 132 第6章 系统调用 133 6.1 系统调用与应用编程接口、系统命令、内核函数的关系 133 6.1.1 系统调用与API 133 6.1.2 系统调用与系统命令 134 6.1.3 系统调用与内核函数 134 6.2 系统调用处理程序及服务例程 135 6.2.1 初始化系统调用 136 6.2.2 system_call()函数 136 6.2.3 参数传递 137 6.2.4 跟踪系统调用的执行 139 6.3 封装例程 140 6.4 添加新系统调用 141 6.5 实例——利用系统调用实现一个调用日志收集系统 143 6.5.1 代码体系结构 143 6.5.2 把代码集成到内核中 146 6.5.3 实现步骤 148 习题6 148 第7章 内核中的同步 149 7.1 临界区和竞争状态 149 7.1.1 临界区举例 149 7.1.2 共享队列和加锁 150 7.1.3 确定保护对象 151 7.1.4 死锁 152 7.1.5 并发执行的原因 153 7.2 内核同步方法 153 7.2.1 原子操作 153 7.2.2 自旋锁 155 7.2.3 信号量 156 7.3 并发控制实例 157 7.3.1 内核任务及其并发关系 158 7.3.2 实现机制 158 7.3.3 关键代码解释 162 7.3.4 实现步骤 163 习题7 164 第8章 文件系统 165 8.1 Linux文件系统基础 165 8.1.1 Linux文件结构 165 8.1.2 Linux文件系统 166 8.1.3 文件类型 167 8.1.4 文件访问权限 168 8.2 虚拟文件系统 168 8.2.1 虚拟文件系统的引入 168 8.2.2 VFS中的数据结构 170 8.2.3 VFS超级块数据结构 171 8.2.4 VFS的索引节点 173 8.2.5 目录项对象 174 8.2.6 与进程相关的文件结构 176 8.2.7 主要的数据结构之间的关系 179 8.3 文件系统的注册、安装与卸载 180 8.3.1 文件系统的注册和注销 180 8.3.2 文件系统的安装 181 8.3.3 文件系统的卸载 183 8.4 页缓冲区 183 8.4.1 address_space对象 183 8.4.2 address_space对象的操作函数表 184 8.5 文件的打开与读写 185 8.5.1 打开文件 185 8.5.2 读写文件 187 8.6 编写一个文件系统 189 8.6.1 Linux文件系统的实现要素 189 8.6.2 什么是romfs文件系统 191 8.6.3 romfs文件系统的布局与文件结构 191 8.6.4 具体实现的对象 192 习题8 195 第9章 设备驱动 196 9.1 概述 196 9.2 设备驱动程序基础 198 9.2.1 I/O端口 199 9.2.2 设备文件 200 9.2.3 中断处理 201 9.2.4 设备驱动程序框架 203 9.3 字符设备驱动程序 204 9.3.1 字符设备驱动程序的注册 204 9.3.2 简单的字符设备驱动程序示例 205 9.4 块设备驱动程序 208 9.4.1 块设备驱动程序的注册 209 9.4.2 块设备请求 212 习题9 215 附录A 内核中的链表 216 A.1 链表数据结构简介 216 A.2 内核链表数据结构的定义及初始化 217 A.3 操作链表的接口 218 A.4 遍历链表 219 附录B 内核模块 221 B.1 什么是模块 221 B.2 编写一个简单的模块 221 B.3 模块编程的基础知识 222 B.4 模块的编译 224 B.5 模块实用程序modutils 226 附录C Linux内核编译 228 C.1 内核简介 228 C.2 为什么重新编译内核 228 C.3 内核编译模式 229 C.4 新版本内核的获取和更新 229 C.5 内核编译 230 C.6 修改并重启管理器 232 附录D Linux编程基础(C语言环境) 233 D.1 Linux编程常识 233 D.1.1 相关标准(ANSI C、POSIX、SVID、XPG) 233 D.1.2 函数库和系统调用 234 D.1.3 在线文档(man、info、HOWTO) 235 D.1.4 C语言编程风格 237 D.2 Linux上的C/C++编译器和调试器 238 D.2.1 运行gcc/egcs 238 D.2.2 gcc/egcs的主要选项 240 D.2.3 gdb简介 240 D.2.4 gdb的常用命令 241 D.2.5 gdb使用示例 242 D.3 GNU make和makefile 243 D.3.1 GNU make 243 D.3.2 makefile的基本结构 243 D.3.3 makefile的变量 244 D.3.4 GNU make的主要预定义变量 245 D.3.5 GNU make的隐含规则 245 D.3.6 运行make 246

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值