Appearance
题目
在文件的索引节点中存放直接索引指针 10 个,一级和二级索引指针各 1 个。磁盘块大小为 1KB,每个索引指针占 4 个字节。若某文件的索引节点已在内存中,则把该文件偏移量(按字节编址)为 1234 和 307400 处所在的磁盘块读入内存,需访问的磁盘块个数分别是( )。
错因
A
把第二个偏移 307400 算成了一级索引——一级间接索引覆盖范围 10240~272383B,307400 超出了一级范围,必须落到二级索引区。误把它放在一级里就会算成"1 个间接块 + 1 个数据块 = 2 块",得出 1、2。
C
把第一个偏移 1234 也算了 1 次间接访问——但 1234B 在前 10KB 内(直接索引区),inode 已经在内存里,直接拿到 10 个直接块指针,再读 1 个数据块就够了。多算的那一次"访问页表/索引块"是不存在的(索引节点已在内存就意味着 10 个直接指针已可读)。
D
两个值都各加了 1:把 1234 算 2 块、307400 算 4 块。多半是把"索引节点本身"也当成一次磁盘访问——但题目明确说**"索引节点已在内存中"**,inode 不需要再读,从读盘块的角度只算外存读取。
总解析
索引节点结构:
| 类型 | 指针数 | 覆盖范围 |
|---|---|---|
| 直接 | 10 | 0 ~ 10×1KB - 1 = 10239 B(即前 10KB) |
| 一级间接 | 1(指向 1 个间接块,间接块含 1KB/4B = 256 个数据块指针) | 10240 ~ 10239 + 256×1KB = 10240 ~ 272383 B |
| 二级间接 | 1(指向 1 个一级间接块,再指向 256 个二级间接块,每个 256 个数据块指针) | 272384 B 起,覆盖 256² × 1KB = 64MB |
inode 已在内存 → 10 个直接指针、一级指针、二级指针都不需要再读盘。
偏移 1234 B:
inode 里直接拿到对应数据块的盘块号 → 只读 1 块(数据块本身)。
偏移 307400 B:
数据流:
inode(已在内存)→ 二级间接指针 → ① 读"一级间接块" → ② 读"二级间接块" → ③ 读"数据块"需要访问的磁盘块:
| 顺序 | 读什么 | 为什么要读 |
|---|---|---|
| ① | 一级间接块 | 内存里 inode 给出它的盘块号,但内容(256 个二级间接块指针)不在内存 |
| ② | 二级间接块 | ① 读出后才知道二级间接块在哪里,但里面的 256 个数据块指针不在内存 |
| ③ | 数据块 | 真正要读的目标 |
共 3 块。
| 偏移 | 区间 | 访问块数 |
|---|---|---|
| 1234 | 直接区 | 1 |
| 307400 | 二级间接区 | 3 |
最终答案是 B。