linux/fs/inode.c/_bmap() and bmap()

2023-05-16

// bmap函数的实体。用来实现文件数据块号到设备中的逻辑块号的映射。
// inode是文件i节点指针,block是要操作的文件数据块号,creat为创建标志
// 有0和1两种情况。若create为0(不置位)则只是映射。换句话说,若block
// 对应的逻辑块不存在,还是返回inode->i_zone[block],此时应该是0.
// 若create为1(创建标志置位)则block对应的逻辑块好不存在时调用new_block
// 函数注册一个新逻辑快,并返回这个新逻辑快的块号。
static int _bmap(struct m_inode * inode,int block,int create)
{
struct buffer_head * bh;
int i;


// block是文件数据块号,因此其范围是(0,7+512+512*512),这是由Minix1.0
// 文件系统决定的
if (block<0)
panic("_bmap: block<0");
if (block >= 7+512+512*512)
panic("_bmap: block>big");


// 下面分三部分来处理。要明晰这一块代码,首先要明白Minix1.0文件系统中
// 记录文件数据块号索引的方法。inode->i_zone[9]总计记录9个索引号,分
// 配方式如下:i_zone[0]~i_zone[7]直接存储文件数据块号,因此可以存储
// 7个数据块号。对于文件数据量小于7k的文件,前7个块号就能满足了;i_zone[8]
// 采用间接存储块号方式。即i_zone[8]中存储的块号对应的块内存储着512个
// 文件数据块号(1块为1k,而一个块号是short型,因此一块正好存储512个块号)
// 因此文件数据块的1+7~512+7是由i_zone[8]来间接获取的;i_zone[9]则是两级
// 间接存储方式。即i_zone[9]内块号对应的块内存储着512个块号。这512个块号
// 每一个对应的块内又存储着512个块号,因此一共有512*512个块号可以被索引
// 因此由i_zone[9]能间接索引到的块为512+7+1~512*512+512+7+1
// 实际映射时,根据block就能计算出当前需要的数据块在哪一部分并分头处理
// 若block<7,在直接映射区域。
if (block<7) {
// 若create置位,并且block对应的逻辑块号不存在(i_zone[block]取出的
// 块号),就调用new_block申请一个新逻辑块号
if (create && !inode->i_zone[block])
if (inode->i_zone[block]=new_block(inode->i_dev)) {
// 写上inode修改时间时间(ctime stands for change time)
inode->i_ctime=CURRENT_TIME;
// 脏标志置位,这样在sync时就会将这个块同步到设备上。
inode->i_dirt=1;
}
// 返回找到的block对应的逻辑块号
return inode->i_zone[block];
}
// 若block>7,则先将block减7,然后再看在后面两段哪一段内
block -= 7;
// 对应block落在i_zone[7]的情况,此时为一次间接存储
if (block<512) {
// 同上面,若create置位并且i_zone[7]为空,则创建新的block
if (create && !inode->i_zone[7])
if (inode->i_zone[7]=new_block(inode->i_dev)) {
inode->i_dirt=1;
inode->i_ctime=CURRENT_TIME;
}
// 若此处i_zone[7]仍为0,则说明create没有置位,而且要找的block
// 真的不存在,此时直接返回0即可。
if (!inode->i_zone[7])
return 0;
// 运行到这里,说明inode->i_zone[7]不为空,可以进行间接读取了。
// 先读出i_zone[7]内存储的512个块号所在的块内容。
if (!(bh = bread(inode->i_dev,inode->i_zone[7])))
return 0;
// bh->b_data为读出来的i_zone[7]里面存储的块号对应的块内容,也就是那
// 512个块号了。用(unsigned short *)格式化之,下面欲访问某个块号,
// 就可以考虑用指针或者数组两种方式访问了。
i = ((unsigned short *) (bh->b_data))[block];
if (create && !i)
if (i=new_block(inode->i_dev)) {
((unsigned short *) (bh->b_data))[block]=i;
bh->b_dirt=1;
}
// 用完bh后即释放
brelse(bh);
return i;
}
// block属于二次间接访问的情况,先减去512(注意这个block在上面已经被
// 减去7一次了,所以累计减去了512+7,就是前两级的逻辑快总数)
block -= 512;
// 同上面,若create置位,并且i_zone[8]为空,则进入创建i_zone[8]的一次
// 间接索引块
if (create && !inode->i_zone[8])
if (inode->i_zone[8]=new_block(inode->i_dev)) {
inode->i_dirt=1;
inode->i_ctime=CURRENT_TIME;
}
// 到此处若还为空,那说明create没置位并且i_zone[8]为空,直接返回0
if (!inode->i_zone[8])
return 0;
// 读出i_zone[8]中存储的逻辑块号对应的块内容,这一块的数据包含了用于
// 二次间接寻块的块号索引。
if (!(bh=bread(inode->i_dev,inode->i_zone[8])))
return 0;
// 请记住这里读出的一块内容(1024bytes)被解析成512个两字节的块号,而
// 每个块号指向的不再是我们要的最终的记录文件的逻辑块,而是记录逻辑快
// 的逻辑块。因此这里的每一项(2字节)将来都对应着512个逻辑块。
// block>>9相当于block除512,这算出了block在i_zone[8]的一级块内的序号,
// 因此i就是512个专存块号的块(称为二次间接块好了,一次间接块指的就是
// i_zone[8])中和block对应的那个块。
i = ((unsigned short *)bh->b_data)[block>>9];
if (create && !i)
if (i=new_block(inode->i_dev)) {
((unsigned short *) (bh->b_data))[block>>9]=i;
bh->b_dirt=1;
}
brelse(bh);
if (!i)
return 0;
// 经过上面的一番折腾,到这里找到了block的二次间接块了,把丫读出来
// 这里面存的就是block % 512 这512个文件数据库对应的逻辑块块号了。
if (!(bh=bread(inode->i_dev,i)))
return 0;
// 这次读的是真正的文件数据库的块号了,bh->b_data中共有512个块号。
// 为了保证访问不越界,block & 511处理了。读出的i就是block对应的块号了。
i = ((unsigned short *)bh->b_data)[block&511];
if (create && !i)
if (i=new_block(inode->i_dev)) {
((unsigned short *) (bh->b_data))[block&511]=i;
bh->b_dirt=1;
}
brelse(bh);
return i;
}


// 将文件中数据块号block映射到设备上的逻辑块号。这个函数用在bread函数之前,
// 因为bread读盘需要盘号(即逻辑块号),而文件inode只能得到文件中的数据块号
// 因此要用bread读盘,必须先用bmap把文件数据块号映射到设备上的逻辑块号
int bmap(struct m_inode * inode,int block)
{
return _bmap(inode,block,0);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux/fs/inode.c/_bmap() and bmap() 的相关文章

  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • 域套接字“sendto”遇到“errno 111,连接被拒绝”

    我正在使用域套接字从另一个进程获取值 就像 A 从 B 获取值一样 它可以运行几个月 但最近 A 向 B 发送消息时偶尔会失败 出现 errno 111 连接被拒绝 我检查了B域套接字绑定文件 它是存在的 我也在另一台机器上做了一些测试 效
  • 加载数据infile,Windows和Linux的区别

    我有一个需要导入到 MySQL 表的文件 这是我的命令 LOAD DATA LOCAL INFILE C test csv INTO TABLE logs fields terminated by LINES terminated BY n
  • 所有平台上的java

    如果您想用 java 为 Windows Mac 和 Linux 编写桌面应用程序 那么所有这些代码都相同吗 您只需更改 GUI 即可使 Windows 应用程序更像 Windows 等等 如果不深入细节 它是如何工作的 Java 的卖点之
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 将 PDF 转换为 600dpi 的 TIFF 和 jpg 96 dpi

    我想使用 ImageMagick 从 Python 脚本将 pdf 转换为 600 dpi 的 tiff 和 96 dpi 的 jpg 我使用 imagemagick 命令行完成了这项任务 但我想使用python中的Imagemagick将
  • 有谁知道在哪里定义硬件、版本和序列号。 /proc/cpuinfo 的字段?

    我想确保我的 proc cpuinfo 是准确的 目前它输出 Hardware am335xevm Revision 0000 Serial 0000000000000000 我可以在代码中的哪里更改它以给出实际值 这取决于 Linux 的
  • 将 jar 作为 Linux 服务运行 - init.d 脚本在启动应用程序时卡住

    我目前正在致力于在 Linux VM 上实现一个可运行的 jar 作为后台服务 我已经使用了找到的例子here https gist github com shirish4you 5089019作为工作的基础 并将 start 方法修改为
  • 在我的 index.php 中加载 CSS 和 JS 等资源时出现错误 403

    我使用的是 Linux Elementary OS 并在 opt 中安装了 lampp My CSS and JS won t load When I inspect my page through browser The console
  • 查找哪个程序运行另一个程序

    我有一个 NAS 运行在 Redhat Linux 的有限版本上 我按照指示破解了它 这样我就可以访问 shell 这很有帮助 我还做了一些修改 其他人也做过修改 除了一个问题之外 它们似乎都工作得很好 不知何故 每隔 22 天 系统就会关
  • 内核模式下的线程(和进程)与用户模式下的线程(和进程)有什么区别?

    我的问题 1 书中现代操作系统 它说线程和进程可以处于内核模式或用户模式 但没有明确说明它们之间有什么区别 2 为什么内核态线程和进程的切换比用户态线程和进程的切换花费更多 3 现在 我正在学习Linux 我想知道如何在LINUX系统中分别
  • Gtk-ERROR **:检测到 GTK+ 2.x 符号

    我正在使用 gcc 编译我的 c 应用程序 并使用以下标志 gcc evis c pkg config cflags libs gtk 2 0 libs clutter gtk 1 0 libs gthread 2 0 Wall o evi
  • Linux 上的用户空间能否实现本机代码的抢占式多任务处理?

    我想知道是否可以在 Linux 用户空间的单个进程中实现本机代码的抢占式多任务处理 也就是说 从外部暂停一些正在运行的本机代码 保存上下文 交换到不同的上下文 然后恢复执行 所有这些都由用户空间精心安排 但使用可能进入内核的调用 我认为这可
  • 删除 Git 存储库,但保留所有文件

    在我使用 Linux 的过程中的某个时刻 我决定将我的主目录中的所有内容都放入源代码管理中是个好主意 我不是在问这是否是一个好主意 我是在问如何撤销它 删除存储库的原因是我最近安装了 Oh My Zsh 而且我非常喜欢它 问题是我的主目录有
  • 我不明白 execlp() 在 Linux 中如何工作

    过去两天我一直在试图理解execlp 系统调用 但我还在这里 让我直奔主题 The man pageexeclp 将系统调用声明为int execlp const char file const char arg 与描述 execl exe
  • 需要一些建议来开始在 ARM(使用 Linux)平台上编程

    我 也许 很快就会在托管 Linux 发行版的 ARM 平台上工作 我不知道哪个发行版 我知道该项目涉及视频流 但我无法告诉你更多信息 其实我只收到通知 还没见到任何人 我从来没有在这样的平台上工作过 所以我的想法是在项目开始之前进行测试
  • 如何减去两个 gettimeofday 实例?

    我想减去两个 gettimeofday 实例 并以毫秒为单位给出答案 这个想法是 static struct timeval tv gettimeofday tv NULL static struct timeval tv2 gettime
  • Linux:如何设置进程的时区?

    我需要设置在 Linux 机器上启动的各个进程的时区 我尝试设置TZ变量 在本地上下文中 但它不起作用 有没有一种方法可以使用与系统日期不同的系统日期从命令行运行应用程序 这可能听起来很愚蠢 但我需要一种sandbox系统日期将被更改的地方
  • 我如何知道 C 程序的可执行文件是在前台还是后台运行?

    在我的 C 程序中 我想知道我的可执行文件是否像这样在前台运行 a out 或者像这样 a out 如果你是前台工作 getpgrp tcgetpgrp STDOUT FILENO or STDIN FILENO or STDERR FIL

随机推荐

  • numpy.maximum()函数和numpy.minimum()函数的使用

    参考链接 numpy maximum 参考链接 numpy minimum 这两个函数的功能大体分别是在两个多维数组中逐元素求最大值和最小值 实验1 numpy maximum 函数 Python span class token numb
  • ImageDraw.rectangle(xy, fill=None, outline=None, width=1)使用举例

    参考链接 ImageDraw rectangle xy fill 61 None outline 61 None width 61 1 ImageDraw rectangle 函数使用说明 在指定的图片上绘制矩形 通过xy可以指定矩形的位置
  • 爬取IP(快代理)

    python 爬IP 分析网页获取IP储存IP全部代码 分析网页 这次分析的是快代理 xff0c 就是这个 想要获取这上面的IP需要分析网页结构 打开开发者工具进行分析 发现所有IP组数据在tr节点中 xff0c 每个具体数据在td节点中
  • Hadoop安装及hdfs操作

    Hadoop安装及hdfs操作如下 先安装完成了centos7 xff0c 首先要对宿主机 xff08 windows xff09 和虚拟机 xff08 centos7 xff09 的网络进行测试 xff0c 保证虚拟机可以与宿主机互通 在
  • Process finished with exit code -1066598274 (0xC06D007E)解决办法

    转载的 xff0c 直接上解决方法 xff1a 1066598274 0xC06D007E 解决matplotlib版本冲突问题 Desny的博客 CSDN博客 process finished with exit code 1066598
  • 硬核!30张图深入理解计算机应用层,附上例题,秒解子网规划,IP分址!

    网络层 已同步微信公众号 xff1a 乐享Coding xff0c 欢迎各位的关注 xff01 主要功能 xff1a 实现主机与主机之间的通信 xff0c 也叫点对点 xff08 end to end xff09 通信 思维导图附上 实现网
  • 银河麒麟用x11vnc实现远程桌面

    1 安装x11vnc 插入x11vnc的命令 sudo apt span class token operator span get update sudo apt span class token operator span get in
  • 阿里云设置密钥对登录服务器

    背景 SSH密钥对通过加密算法生成一对密钥 xff0c 默认采用RSA 2048位的加密方式 优势 密钥对安全强度远高于常规用户口令 xff0c 可以杜绝暴力破解威胁 注意事项 配置完一定要重启服务器 xff0c 重启后就自动无法通过密码连
  • 选择排序、冒泡排序---伪代码

    选择和冒泡排序 选择排序 xff08 排序时 xff0c 相对顺序不变 xff09 span class token keyword for span span class token punctuation span i span cla
  • C#播放音乐

    今天在调试机器的时候 xff0c 要对一个双通道的信号发生器两路输出进行自动校准 每通道校准的时间大概是六七分钟 xff0c 关键是回环中测试的GPIB卡和频谱仪只有一个 xff0c 所以在换路测试时要手工转接信号发生器的输出口才能完成双路
  • Stratis 管理分层存储

    Stratis管理分层存储 介绍配置yum源 xff0c 安装软件包配置本地yum源安装软件包 启动stratisd服务创建池构建文件系统挂载扩容创建快照文件系统删除删除池 介绍 通过Stratis xff0c 便捷使用精简配置 xff0c
  • 神经网络公式推导

    1 规定 y i j y ij y i j 为第
  • Linux 通过 log 日志检查服务器是否被暴力破解

    远程服务器一般需要启用 ssh 远程登录功能 对于 ssh 协议的常见攻击是进行暴力破解 通过查看 log 日志检测服务器是否被暴力破解 日志位置 不同的linux发行版 xff0c 关于 ssh 登录的日志信息存储的地方不同 xff1a
  • Keil报错Error: Flash Download failed - “Cortex-M4”

    stm32下载程序时出现如下报错 xff1a 解决方案 xff1a 1 点击魔术棒 2 选择 Debug 3 点击 Settings 4 点击 Flash Download 5 点击 Add 6 添加对应芯片flash对应的型号 7 点击
  • Java中a++ 和 ++a的区别

    a 43 43 是先计算 xff0c 执行语句之后 xff0c 再 43 1 xff0c 43 43 a是先 43 1 xff0c 再运算 例子代码 xff1a public class Test public static void ma
  • 你知道CSS中的替换元素吗?

    前言 你知道CSS中的替换元素吗 xff1f 你知道哪些元素是替换元素吗 xff1f 替换元素 xff08 replaced element xff09 可以说是 CSS 中的另一个派系 根据元素是否具有可替换内容 xff0c 把元素分为替
  • STM32烧录程序失败

    故障如下 xff1a 原因 xff1a 1 芯片选择错误 编译生产的hex文件不是STM32系列的芯片 2 预留空间不足 下图的内存空间可以调大一些
  • 系统架构设计师论文范文

    论混合软件架构的设计 摘要 xff1a 2007年3月 xff0c 我所在的公司组织开发了一套完整的变电综合信息管理系统 xff0c 在这个项目中 xff0c 我担任系统架构设计师职务 xff0c 主要负责软件架构和网络安全体系架构设计的工
  • 计算机网络

    文章目录 隐藏 七层模型网络技术校准与协议拓扑结构网络规划与设计无线网网络接入技术网络存储技术磁盘阵列 RAID IPv6物联网云计算 七层模型 网络技术校准与协议 TCP与UDP UDP 是无连接的 xff0c TCP 是面向连接的 xf
  • linux/fs/inode.c/_bmap() and bmap()

    bmap函数的实体 用来实现文件数据块号到设备中的逻辑块号的映射 inode是文件i节点指针 xff0c block是要操作的文件数据块号 xff0c creat为创建标志 有0和1两种情况 若create为0 xff08 不置位 xff0