无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 16661|回复: 90
打印 上一主题 下一主题

最简单的 Linux 文件系统是哪个?

    [复制链接]
跳转到指定楼层
1#
发表于 2019-3-5 10:43:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Linux 的文件系统有一大堆,每个文件系统都有自己的优点。但是,我认为 “简单就是美”。我开这个帖子,希望通过探讨学到知识。

大家最熟悉的文件系统,莫过于微软的 FAT 了。也许它不能算作“最”简单,但也算比较简单了。它的几个部分非常单纯:

保留空间(含有引导扇区)
FAT 表
FAT 表的备份
根目录表
数据区


FAT 文件系统用了几十年,没啥问题。只是文件长度限制为 4G 以内,才逐渐显示出瓶颈。遗憾的是,FAT 文件系统的目录项,没有权限设置相关字段,无法直接用作 Linux 的主文件系统,只能作为辅助的文件系统(mount 之后仅仅存放普通数据文件)。

由于 Linux 的文件系统太多,而一个人精力有限,很难逐个学习了解,所以,我希望有兴趣者,能一起讨论,互相帮助,少走弯路。

今天先贴一篇 blog 文章,作为学习的开端:


从零开始编写一个简单的Linux文件系统

作者:shuxiaogd
来源:CSDN
原文:https://blog.csdn.net/shuxiaogd/article/details/48829671
版权声明:本文为博主原创文章,转载请附上博文链接!


最近想研究一下 Linux 文件系统,最好的开始当然是自己写一个简单的文件系统,并能够 mount 上。

这方面的工作其实已经有很多人做过了,比如 IBM Linux 技术中心的教程:


Linux FileSystems in 21 Days( A step by step introduction to writing a Linux Filesystem)


点此下载源代码 samplefs

推荐
发表于 2019-3-5 12:27:30 | 只看该作者
插眼
回复

使用道具 举报

3#
发表于 2019-3-5 13:08:43 | 只看该作者
不管底层是什么文件系统,上层的vfs文件系统基本绕不过去吧,能学懂vfs,其他文件系统也就知道怎么学了

上层文件系统可以认为是一个<文件路径,vfs-inode>的映射,底层文件系统则是<vfs-inode,real-inode>的映射,找到文件系统里自己实现的inode基本就可以读文件了。

个人的linux文件系统学习时用的方法,仅供参考

点评

不是泛泛地学习,而是提出一个问题:如何让它“简单”。比如说,一个像微软 FAT 那样简单的文件系统,又能满足桌面 Linux 的使用,这样就 OK。 当然了,“简单”之后,肯定会损失某些东西,比如损失速度、性能,  详情 回复 发表于 2019-3-5 14:53
回复

使用道具 举报

4#
 楼主| 发表于 2019-3-5 14:42:28 | 只看该作者
ext2/3/4的inode结构说明
https://www.cnblogs.com/liuxuzzz/p/5348545.html

上述 blog 对比了 ext2/3 和 ext4 的 inode 结构,在文章结尾,给出了相关链接。值得一看。
回复

使用道具 举报

5#
 楼主| 发表于 2019-3-5 14:53:33 | 只看该作者
2013olly 发表于 2019-3-5 13:08
不管底层是什么文件系统,上层的vfs文件系统基本绕不过去吧,能学懂vfs,其他文件系统也就知道怎么学了

...

不是泛泛地学习,而是提出一个问题:如何让它“简单”。比如说,一个像微软 FAT 那样简单的文件系统,又能满足桌面 Linux 的使用,这样就 OK。

当然了,“简单”之后,肯定会损失某些东西,比如损失速度、性能,或者损失存储效率,等等。

但既然选择“简单”,就比较注重“简单”,而能够接受在其他方面的不足。

这不是技术,而是哲学。

点评

那么,假如在fat基础上添加一两个字段,用来存放权限,软链接等内容,其他基本不怎么改,这是否算一个简单的文件系统? 如果真的实现了这样一个文件系统,文件系统和linux的接口部分估计不会太简单了,因为需要满  详情 回复 发表于 2019-3-6 10:52
回复

使用道具 举报

6#
 楼主| 发表于 2019-3-5 15:38:45 | 只看该作者
漫谈 Linux 标准的文件系统 (Ext2/Ext3/Ext4)
http://www.cnblogs.com/justmine/p/9128730.html

这篇文章讲了很多基本概念。比如:
inode(索引节点)
记录文件的权限、属性和数据所在块 block 的号码,每个文件都有且仅有一个的 inode,每个 inode 都有自己的编号,可以把 inode 简单地理解为文档索引。

    备注:在磁盘格式化后,inode 的大小和数量都已经固定了,大小均为128 Bytes(新的 Ext4 和 xfs 为 256 Bytes)。读取文件时,先读取 inode 里面记录的文件属性和权限,匹配正确后,才会读取文件内容(block)。在 Linux 系统中,实际使用 inode 来识别文件,而不是用文件名,类似于用户标识和昵称的设计。


回复

使用道具 举报

7#
发表于 2019-3-5 22:39:48 | 只看该作者
如果作为文件系统学习的话,越小越好。

Menuet OS 1.4MB,不过这货不是Linux。Linux体系的话4MB?




  1. title MenuetOS
  2. find --set-root --ignore-floppies /M6413060.IMG
  3. map --mem /M6413060.IMG (fd0)
  4. map --hook
  5. chainloader (fd0)+1
  6. rootnoverify (fd0)
复制代码



M6413060.7z (804.76 KB, 下载次数: 41)

点评

去了解了一下这个系统....太可怕了,叹为观止  详情 回复 发表于 2019-4-3 13:34
当年玩过一个小系统,好像是1.4M,,还能驱动网卡,内置几个小游戏。不过忘记名字了。  详情 回复 发表于 2019-3-6 22:04
这玩意怎么这么厉害。。。  详情 回复 发表于 2019-3-5 23:46
回复

使用道具 举报

8#
发表于 2019-3-5 22:54:09 | 只看该作者
多谢大神的分享,学习下。。。
回复

使用道具 举报

9#
发表于 2019-3-5 23:46:33 | 只看该作者
slore 发表于 2019-3-5 22:39
如果作为文件系统学习的话,越小越好。

Menuet OS 1.4MB,不过这货不是Linux。Linux体系的话4MB?

这玩意怎么这么厉害。。。
回复

使用道具 举报

10#
 楼主| 发表于 2019-3-6 09:09:32 | 只看该作者
今天贴点 exFAT 的资料。从 exFAT 卷的布局可以了解,总体布局与 FAT32 相似,但缺少“保留扇区”这样一个区域。FAT32 的保留扇区数不是定死的。现在的“主引导区”就相当于原来的“保留扇区”区域,但现在它是固定的,总共占用 24 个扇区,不多也不少。这一点,算是与以往 FAT 系列文件系统最大的差别了。


exFAT volume layout

Offset, sectors
Size, sectors
Block
Comments
Main Boot Region(主引导区,占用 12 扇区)
0
1
Boot Sector
引导扇区(1个)
1
8
Extended Boot Sectors
扩展的引导扇区(8个)
9
1
OEM Parameters
OEM 参数扇区(1个)
10
1
Reserved
保留扇区(1个)
11
1
Boot Checksum
校验和扇区(1个)
Backup Boot Region(备份引导区,占用 12 扇区)
12
1
Boot Sector

13
8
Extended Boot Sectors

21
1
OEM Parameters

22
1
Reserved

23
1
Boot Checksum

FAT Region(文件分配表区)
24
FatOffset - 24
FAT Alignment
Boot Sectors contain FatOffset
FatOffset
FatLength
First FAT
Boot Sectors contain FatOffset and FatLength
FatOffset + FatLength
FatLength
Second FAT
For TexFAT only
Data Region(数据区)
FatOffset + FatLength * NumberOfFats
ClusterHeapOffset – (FatOffset + FatLength * NumberOfFats)
Cluster Heap Alignment
簇堆对齐
ClusterHeapOffset
ClusterCount * 2^SectorsPerClusterShift
Cluster Heap
簇堆起始扇区号
和占用扇区数
ClusterHeapOffset + ClusterCount * 2^SectorsPerClusterShift
VolumeLength – (ClusterHeapOffset + ClusterCount * 2^SectorsPerClusterShift)
Excess Space
尾部多余的空间

回复

使用道具 举报

11#
发表于 2019-3-6 10:52:20 | 只看该作者
不点 发表于 2019-3-5 14:53
不是泛泛地学习,而是提出一个问题:如何让它“简单”。比如说,一个像微软 FAT 那样简单的文件系统,又 ...

那么,假如在fat基础上添加一两个字段,用来存放权限,软链接等内容,其他基本不怎么改,这是否算一个简单的文件系统?

如果真的实现了这样一个文件系统,文件系统和linux的接口部分估计不会太简单了,因为需要满足像vfs提供inode节点等功能,可能需要不少封装和模拟才可以实现。

如果实现一个和vfs比较相近的文件系统,接口和处理代码应该会简单很多,但是文件系统的二进制结构可能就没那么简单了。

点评

exFAT 是微软的,大概只能用来学习、研究,不能企图把它改造成符合 Linux 要求的根文件系统。微软不会提供这种方便(或者说,可能性),不符合微软的利益。前面我已经说了,假如有可能那样改造的话,估计早都有人做  详情 回复 发表于 2019-3-6 12:11
回复

使用道具 举报

12#
 楼主| 发表于 2019-3-6 12:01:57 | 只看该作者
exFAT Boot Sector
Offset
Size
Description
Comments
0 (0x00)
3
JumpBoot
0xEB7690
3 (0x03)
8
FileSystemName
"EXFAT>
11 (0x0B)
53
MustBeZero

64 (0x40)
8
PartitionOffset
In sectors; if 0, shall be ignored ——分区的起始扇区号(64位
72 (0x48)
8
VolumeLength
Size of exFAT volume in sectors —— 卷的扇区总数(64位
80 (0x50)
4
FatOffset
In sectors —— FAT 表的起始扇区号,应该是相对于分区起始吧
84 (0x54)
4
FatLength
In sectors. May exceed the required space in order to align the second FAT
88 (0x58)
4
ClusterHeapOffset
In sectors ——簇堆的起始扇区号,应该是相对于分区起始吧
92 (0x5C)
4
ClusterCount
2^32-11 is the maximum number of clusters could be described
96 (0x60)
4
RootDirectoryCluster
根目录的簇号
100 (0x64)
4
VolumeSerialNumber
卷序列号
104 (0x68)
2
FileSystemRevision
as MAJOR.minor, major revision is high byte, minor is low byte; currently 01.00 —— 文件系统版本号
106 (0x6A)
2
VolumeFlags * ↓
卷的标志
Offset
Size
Field
0
1
ActiveFat 0 - First FAT and Allocation Bitmap are active, 1- Second.
1
1
VolumeDirty (0-clean, 1-dirty)
2
1
MediaFailure (0 – no failures reported or they already marked as BAD clusters) 1- some read/write operations failed)
3
1
ClearToZero (no meaning)
4
12
Reserved (no meaning)
108 (0x6C)
1

BytesPerSectorShift
Power of 2. Minimum 9 (512 bytes per sector), maximum 12 (4096 bytes per sector)
109 (0x6D)
1
SectorsPerCluster Shift
Power of 2. Minimum 0 (1 sector per cluster), maximum 25 – BytesPerSectorShift, so max cluster size is 32 MB
110 (0x6E)
1

NumberOfFats
2 is for TexFAT only
111 (0x6F)
1
DriveSelect
Extended INT 13h drive number; typically 0x80 ——暗示,主板需要支持 EBIOS(LBA),而不是通常的 CHS。
112 (0x70)
1

PercentInUse
0..100 – percentage of allocated clusters rounded down to the integer 0xFF – percentage is not available
113 (0x71)
7
Reserved

120 (0x78)
390

BootCode

510 (0x1FE)
2
BootSignature
0xAA55 —— 这个启动标志固定位于 510 处,不是位于大扇区的尾部。
512 (0x200)
2^BytesPerSectorShift - 512
ExcessSpace
Not used —— 如果扇区大小超过 512 字节,多余的部分不使用。

只有分区起始扇区号和分区长度,是 64 位值,其他的量都是小值( 32 位以内的值)。这提示我们在设计一个新文件系统的时候,没必要把所有的值,都弄成 64 位。

回复

使用道具 举报

13#
 楼主| 发表于 2019-3-6 12:11:09 | 只看该作者
2013olly 发表于 2019-3-6 10:52
那么,假如在fat基础上添加一两个字段,用来存放权限,软链接等内容,其他基本不怎么改,这是否算一个简 ...


exFAT 是微软的,大概只能用来学习、研究,不能企图把它改造成符合 Linux 要求的根文件系统。微软不会提供这种方便(或者说,可能性),因为那不符合微软的利益。前面我已经说了,假如有可能那样改造的话,估计早都有人做了。
回复

使用道具 举报

14#
 楼主| 发表于 2019-3-6 14:34:31 | 只看该作者
exFAT - Extended Boot Sector
Offset
Size
Description
Comments
0 (0x00)
2^BytesPerSectorShift - 4
ExtendedBootCode

2^BytesPerSectorShift - 4
4
ExtendedBootSignature
0xAA550000
Whole sector is used for boot code except last 4 bytes used for signature in each sector.If Extended Boot Sector is not used, it should be filled with 0x00.Extended signature must be preserved.

对于大扇区来说,这次是使用整个扇区,而不是只有开头的 512 字节。而且,扩展引导标志是在整个扇区的尾部,而不是只在 512 字节之前。猜测这可能是因为,当 boot sector 接管控制后,已经知道了扇区大小,因此,扩展引导代码部分就可以使用整个的大扇区了。

回复

使用道具 举报

15#
 楼主| 发表于 2019-3-6 17:30:56 | 只看该作者
exFAT - File Allocation Table (FAT)      

File Allocation Table (FAT) may contain 1 or 2 FATs, as defined in NumberOfFats field. ActiveFat field in VolumeFlags in the Main Boot Sector determines which FAT is active.

The first cluster is cluster 2, as in FAT32. Each FatEntry represents one cluster.

In exFAT, FAT is not used for tracking an allocation; an Allocation Bitmap is used for this purpose. FAT is only used for keeping chains of clusters of fragmented files. If a file is not fragmented, FAT table does not need to be updated. A Stream Extensions Directory Entry should be consulted to determine if the FAT chain is valid or not. If FAT chain is not valid, it does not need to be zeroed.

Offset
Size
Description
Comments
0 (0x00)
4
FatEntry[0]
Media type (should be 0xFFFFFFF8)
4 (0x04)
4
FatEntry[1]
Must be 0xFFFFFFFF
8 (0x08)
4
FatEntry[2]
First cluster
...
...
...
...
(ClusterCount + 1) * 4
4
FatEntry[ClusterCount + 1]
Last cluster
(ClusterCount + 2) * 4
Remainder of sector
ExcessSpace


Valid values of FAT entries:
  • 0x00000002 — ClusterCount +1 (max 0xFFFFFFF6) — next cluster in the chain
  • 0xFFFFFFF7 — bad cluster
  • 0xFFFFFFF8 — media descriptor
  • 0xFFFFFFFF — end of file (EOF mark)


Value 0x00000000 does not mean the cluster is free, it is an undefined value.
The second FAT table (presents only in TexFAT) is located immediately after the first one and has the same size.

Cluster Heap

The cluster heap is a set of clusters which hold data in exFAT. It contains:
  • Root Directory
  • Files
  • Directories
  • Bitmap Allocation Table
  • UP-Case Table


The allocation status of clusters in cluster heap is tracked by Bitmap Allocation Table which itself located inside the cluster heap.

从上述描述可以知道,exFAT 在很多方面都像 FAT32。它的 FAT 表项(簇号)都是 32 位的,所以,它不是 FAT64。它可以看成是改进型的 FAT32。



与 FAT32 不同,exFAT 的 FAT 表是专门用来服务于“文件碎片”的。FAT32 的文件分配表还用于跟踪空间的分配情况。在 exFAT 中,开辟了新的 “职能部门”—— Bitmap Allocation Table ——用于跟踪空间分配情况。文件无碎片时,可以不更新对应的 FAT 表项。这意味着,当文件无碎片时,FAT 表里面的原有记录,可能是错的,不能反映真实的分配情况。


我觉得还是更新了好。一个连续的文件,更新一下 FAT 表,也不会造成多大的性能损失。好处是确保 FAT 表能够反映真实分配情况。这样,第三方工具恢复误删的文件,成功的可能性就大一些。 Bitmap Allocation Table 只对提升性能有用。一个精简的文件系统,不需要 Bitmap Allocation Table,就是说,原先的 FAT32 的那种处理,就算是可以了。


再一个细节的讨论,就是有关“0xFFFFFFFF — end of file (EOF mark)” 的。这是文件的最后一簇,它没有后续的簇号,因此,使用了 0xFFFFFFFF 来当作结束的标志。但是,这个结束标志带来的信息却仅仅是 “结束”而已,没能提供更加有用的信息。在设计某个新的文件系统时,如果用该文件的起始簇号来取代此处的 0xFFFFFFFF,则能够提供有价值的信息。就是说,当遇到起始簇号时,就认为到达了文件的结尾,这完全能够清晰地表明文件“结束”了。这样做的好处是,第三方恢复工具能够从一个 chain 的随便某个簇号开始,顺藤摸瓜,最终能找到起始簇号。如果是以 0xFFFFFFFF 结束,则无法方便快捷地找到起始簇号(需要遍历整个 FAT 表,才能找到起始簇号)。



回复

使用道具 举报

16#
发表于 2019-3-6 22:04:39 | 只看该作者
slore 发表于 2019-3-5 22:39
如果作为文件系统学习的话,越小越好。

Menuet OS 1.4MB,不过这货不是Linux。Linux体系的话4MB?

当年玩过一个小系统,好像是1.4M,,还能驱动网卡,内置几个小游戏。不过忘记名字了。
回复

使用道具 举报

17#
 楼主| 发表于 2019-3-7 06:55:23 | 只看该作者
exFAT — Directory Structure


exFAT uses tree structure to describe relationship between files and directories. The root of the directory tree is defined by directory located at RootDirectoryCluster. Subdirectories are single-linked to there parents. There is no special (.) and (..) directories pointing to itself and to parent like in FAT16/FAT32.
Each directory consists of a series of directory entries. Directory entries are classified as critical/benign and primary/secondary as follows:
  • Primary Directory Entries

    • Critical Primary Entries
    • Benign Primary Entries

  • Secondary Directory Entries

    • Critical Primary Entries
    • Benign Primary Entries

Critical entries are required while benign entries are optional. Primary directory entries correspond to the entries in file system and describe main characteristics. Secondary directory entries extend the metadata associated with a primary directory entry end follow it.
A group of primary/secondary entries make up a directory entry set describing a file or directory. The first directory entry in the set is a primary directory entry. All subsequent entries, if any, must be secondary directory entries.
Each directory entry derives from Generica Directory Entry template. Size of directory entry is 32 bytes.
Offset
Size
Description
Comments
0 (0x00)
1
EntryType ↓

Bits
Size
Description
Comments
0-4
5
Code
5
1
Importance
0 — Critical entry, 1 — Benign entry
6
1
Category
0 — Primary entry, 1 — Secondary entry
7
1
In use status
0 – Not in use, 1 – In use
1 (0x01)
19
CustomDefined

20 (0x14)
4
FirstCluster
0 – no cluster allocation 2..ClusterCount+1 – cluster index
24 (0x18)
8
DataLength
In bytes
EntryType can have the following values:
  • 0x00 — End Of Directory marker. All other fields in directory entry are invalid. All subsequent directory entries are also End Of Directory markers
  • 0x01-0x7F (InUse = 0). All other fields in this entry are not defined
  • 0x81-0xFF (InUse = 1). Regular record with all fields defined.

Generic Primary Directory Entry Template

Offset
Size
Description
Comments
0 (0x00)
1
EntryType ↓

1 (0x01)
1
SecondaryCount
Number of secondary entries which immediately follow this primary entry and together comprise a directory entry set. Valid value is 0..255
2 (0x02)
2
SetChecksum
Checksum of all directory entries in the given set excluding this field. See EntrySetCheckSum().
4 (0x04)
2
GeneralPrimaryFlags

Bits
Size
Description
Comments
0
1
AllocationPossible
0-not possible (FirstCluster and DataLength undefined), 1-possible
1
1
NoFatChain
0-FAT cluster chain is valid 1-FAT cluster chain is not used (contiguous data)
2
14
CustomDefined

6 (0x06)
14
CustomDefined

20 (0x14)
4
FirstCluster

24 (0x18)
8
DataLength

All critical primary directory entries are located in root directory (except file directory entries). Benign primary directory enries are optional. If one benign primary entry is not recognized, all directory entry set is ignored.

Generic Secondary Directory Entry Template

Offset
Size
Description
Comments
0 (0x00)
1
EntryType ↓

1 (0x01)
1
GeneralSecondaryFlags

Bits
Size
Description
Comments
0
1
AllocationPossible

1
1
NoFatChain

2
14
CustomDefined

2 (0x02)
18
CustomDefined

20 (0x014)
4
FirstCluster

24 (0x018)
8
DataLength


Defined Directory Entries

EntryType
Primary
Critical
Code
Directory Entry
0x81
·
·
1
Allocation Bitmap
0x82
·
·
2
Up-case Table
0x83
·
·
3
Volume Label
0x85
·

5
File
0xA0
·
·
0
Volume GUID
0xA1
·

1
TexFAT Padding
0xA2
·

2
Windows CE Access Control Table
0xC0

·
0
Stream Extension
0xC1

·
1
File Name


可以看到,簇号占用 32 位,文件大小占用 64 位。我们留意,exFAT 对于 FAT32 的改进,最要紧的,也就在于将文件大小从 32 位扩展为 64 位。

回复

使用道具 举报

18#
 楼主| 发表于 2019-3-7 08:44:40 | 只看该作者
exFAT — File Directory Entry

File directory entry describes files and directories. It is a primary critical directory entry and must be immediately followed by 1 Stream Extension directory entry and from 1 to 17 File Name directory entries . Those 3-19 directory entries comprise a directory entry set describing a single file or a directory.
Offset
Size
Description
Comments
0 (0x00)
1
EntryType
0x85
1 (0x01)
1
SecondaryCount
Must be from 2 to 18
2 (0x02)
2
SetChecksum

4 (0x04)
2
FileAttributes

Bits
Size
Attribute
Comments
0
1
ReadOnly

1
1
Hidden

2
1
System

3
1
Reserved1
这里保留了 1 个 bit
4
1
Directory

5
1
Archive

6
10
Reserved2
这里保留了 10 个 bit
6 (0x06)
2
Reserved1
这里保留了 2 个字节
8 (0x08)
4
CreateTimestamp

12 (0x0C)
4
LastModifiedTimestamp

16 (0x10)
4
LastAccessedTimestamp

20 (0x14)
1
Create10msIncrement
0..199
21 (0x15)
1
LastModified10msIncrement
0..199
22 (0x16)
1
CreateTimezoneOffset
Offset from UTC in 15 min increments
23 (0x17)
1
LastModifiedTimezoneOffset
Offset from UTC in 15 min increments
24 (0x18)
1
LastAccessedTimezoneOffset
Offset from UTC in 15 min increments
25 (0x19)
7
Reserved2
这里保留了 7 个字节


File Name Directory Entry
     
Offset
Size
Description
Comments
0 (0x00)
1
EntryType
0xC1
1 (0x01)
1
GeneralSecondaryFlags

Bits
Size
Attribute
Comments
0
1
AllocationPossible
Must be 0
1
1
NoFatChain
Must be 0
2
14
CustomDefined

2 (0x02)
30
FileName

File Name directory entries must immediately follow the Steam Extension directory entry in the number of NameLength/15 rounded up.
The maximum number of File Name entries is 17, each can hold up to 15 Unicode characters and the maximum file name length is 255. Unused portion of FileName field must be set to 0x0000.

Invalid File Name Characters


Character Code
Character
Description
0x0000 – 0x001F

Control codes
0x0022
"
Quotation mark
0x002A
*
Asterisk
0x002F
/
Forward slash
0x003A
:
Colon
0x003C
<
Less than
0x003E
>
Greater than
0x003F
?
Question mark
0x005C
\
Back slash
0x007C
|
Vertical bar

可以看到,exFAT 的目录项中,确实有一些保留位和保留字节。这为支持 Linux 权限设置,提供了可能性。但是,这些保留的字段,微软将来也有可能使用。如果真的要着手进行改造的话,就得猜测微软到底将来会怎么使用这些字段,以及可能的冲突会有多大,严重不严重。即便能够改造,也不一定值得去改造。exFAT 沿用了微软的很多习惯,这些习惯,与 Linux 有冲突。比如,文件名不区分大小写,这反而是个问题,因为你还得花费精力去比较文件名,让大小写一样的文件名视为相同的,这就增加了负担,不如像 Linux 目前这样 “区分大小写”,更简单、方便。再比如,一个长文件名,在 exFAT 的目录项中分为好多碎片,这也不如 Linux 的 ext2 目录项中的文件名是连续的一个字符串,来得更合理。


又比如,微软习惯于在目录项中存储 unicode 文件名(UTF-16 格式),这带来的好处不一定有多大。我认为(如果设计)一个(新的) Linux 的文件系统,应该在目录项中存储 UTF-8 格式的文件名。分析如下:(一)UTF-16 和 UTF-8 都是变长的。UTF-16 的好处是,在常用文字 65536 个字符(BMP)以内,统一都是 2 字节。但在 BMP 以外,需要 4 字节。而且,UTF-16 最大只能处理 unicode 的码点 0x10FFFF,目前虽然够用,但将来 unicode 字符集完善以后,就处理不了了。UTF-8 的好处是,可以处理全部 unicode 码点,没有死角。UTF-8 的缺点是,在 65536 个字符以内,UTF-8 是变长的,可能在 1 到 3 个字节之间变动。汉字是 3 个字节。当然了,谁如果不是吃饱了撑的,也不会在文件名中采用 BMP 以外的冷僻字符。因此,在变长问题上,UTF-16 稍稍占优。(二)UTF-16 在普通的终端使用上,还是不行的,需要转换。而 UTF-8 几乎在 Linux 下取得事实工业标准的地位了。使用时不需要转换。比如,ls 命令列出的文件名,与磁盘上保存的文件名是一样的字符串,都是 UTF-8 格式。(三)UTF-16 和 UTF-32 都存在 “字节序” (大小端)问题,UTF-8 不存在这样的问题。(四)UTF-16 在 65536 个字符(BMP)以内,节约了汉字的空间占用(只占 2 字节),比 UTF-8 的 3 字节,少占用一个字节。但它浪费了英文字符一个字节:UTF-8 只需一个字节,UTF-16 需要 2 个字节(UTF-32 需要 4 个字节)。然而,英文字符文件名是更频繁使用的文件名,尤其是对于 Linux 用户来说,更是这样,因此,这种浪费就有点大了。当然了,在文件名方面,浪费一些字节,也不是很要紧的。一个长篇小说的浪费,才算是浪费。综合以上几条,在 Linux 的文件系统内部直接采用 UTF-8 文件名,相比于 UTF-16 和 UTF-32,优势更大一些。



exFAT 的文件名和目录项信息集中放在了一起;Linux 的 ext2 中的目录项只记录文件名和 inode 的对应关系,而由另外的 inode 结构来记录文件的信息。我认为,Linux 的 ext2 的做法更好一点。但是,Linux 的 ext2 中,对磁盘块多级寻址,还是复杂了。微软的 FAT 和 exFAT 中都是用单一的簇号链(链接表)来寻址,这在逻辑上是非常简单的。



回复

使用道具 举报

19#
 楼主| 发表于 2019-3-7 10:33:34 | 只看该作者
本帖最后由 不点 于 2019-3-30 10:27 编辑

Linux 文件系统中的一个特性——硬链接——好像是微软不曾使用的(更正:NTFS 好像也支持硬链接)。当然了,硬链接究竟能有多大用处的问题,也值得讨论。不过,现在先不讨论这个问题。贴一篇文章,了解这方面的知识。

理解 Linux 的硬链接与软链接
https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/

摘录如下:

由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:

    文件有相同的 inode 及 data block;
    只能对已存在的文件进行创建;
    不能交叉文件系统进行硬链接的创建;
    不能对目录进行创建,只可对文件创建;
    删除一个硬链接文件并不影响其他有相同 inode 号的文件。

软链接的创建与使用没有类似硬链接的诸多限制:

    软链接有自己的文件属性及权限等;
    可对不存在的文件或目录创建软链接;
    软链接可交叉文件系统;
    软链接可对文件或目录创建;
    创建软链接时,链接计数 i_nlink 不会增加;
    删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。


上述文章还提到了“文件太多导致 inode 被用光(无法创建新文件了),但文件系统的空闲空间却还有很多”的情况。这说明,固定 inode 数目的文件系统设计,也有它不合理的一面。微软的文件系统不存在这个问题(更正:支持硬链接的 NTFS 是否存在这个问题,也未可知)。

回复

使用道具 举报

20#
 楼主| 发表于 2019-3-8 11:46:07 | 只看该作者
ext4 — Linear (Classic) Directories


By default, each directory lists its entries in an “almost-linear”array. I write “almost” because it’s not a linear array in the memorysense because directory entries are not split across filesystem blocks.Therefore, it is more accurate to say that a directory is a series ofdata blocks and that each block contains a linear array of directoryentries. The end of each per-block array is signified by reaching theend of the block; the last entry in the block has a record length thattakes it all the way to the end of the block. The end of the entiredirectory is of course signified by reaching the end of the file. Unuseddirectory entries are signified by inode = 0. By default the filesystemuses struct ext4_dir_entry_2 for directory entries unless the“filetype” feature flag is not set, in which case it usesstruct ext4_dir_entry.
The original directory entry format is struct ext4_dir_entry, whichis at most 263 bytes long, though on disk you’ll need to referencedirent.rec_len to know for sure.

OffsetSizeNameDescription
0x0__le32inodeNumber of the inode that this directory entry points to.
0x4__le16rec_lenLength of this directory entry. Must be a multiple of 4.
0x6__le16name_lenLength of the file name.
0x8charname[EXT4_NAME_LEN]File name.

Since file names cannot be longer than 255 bytes, the new directoryentry format shortens the rec_len field and uses the space for a filetype flag, probably to avoid having to load every inode during directorytree traversal. This format is ext4_dir_entry_2, which is at most263 bytes long, though on disk you’ll need to referencedirent.rec_len to know for sure.

OffsetSizeNameDescription
0x0__le32inodeNumber of the inode that this directory entry points to.
0x4__le16rec_lenLength of this directory entry.
0x6__u8name_lenLength of the file name.
0x7__u8file_typeFile type code, see ftype table below.
0x8charname[EXT4_NAME_LEN]File name.

The directory file type is one of the following values:

ValueDescription
0x0Unknown.
0x1Regular file.
0x2Directory.
0x3Character device file.
0x4Block device file.
0x5FIFO.
0x6Socket.
0x7Symbolic link.

ext4 的上述目录结构,非常简单,它只把文件名同 inode 号码对应起来,就完事。然而,为了加快目录项的定位,后来还发明了 Hash Tree Directories,非常复杂。它为了与 ext2 兼容,可能没法对上述目录结构进行大的修改,所以,只能另外设计一个结构,而不是直接修改现有结构。假如我们要设计一个新的文件系统,就不必考虑与 ext2 的兼容问题了,因此,我们可以直接改进目录表的结构。比如说,改成这样:


OffsetSizeNameDescription
0x0__le32inodeNumber of the inode that this directory entry points to.
0x4__le16rec_lenLength of this directory entry.
0x6__u8name_lenLength of the file name.
0x7__u8file_typeFile type code.
0x8__le32hashFile name hash.
0xCcharname[EXT4_NAME_LEN]File name.

同一目录下的文件名,使用的频度是不同的。可以再增加一个字段,用来表示访问次数。访问次数多的,调整到该目录的第一磁盘块(或者前 4 个磁盘块),让它更容易被找到。


另外,目录结构也不一定从一开始就是目录项的记录。可以在开头有一个说明性的 super 区域,记录着该目录的一些变量或信息。比如,有个变量表示本信息域的长度,指示实际的目录项从哪里开始。另外有两个变量分别记录该目录下最大的访问次数和最小的访问次数。当最小的访问次数已经达到最大访问次数的一半时,应该把本目录下所有文件的访问次数都减去这个最小值。当最大值将要溢出时,把本目录下所有文件的访问次数都除以 2。



对于很久(比如 30 天)都没有修改的文件(看修改时间就可知道这一点),操作系统应该在空闲时,对其进行整理碎块,让它变成连续的。inode 结构中应该有个字段,表示文件是否连续(就像微软所做的那样)。

回复

使用道具 举报

21#
发表于 2019-3-8 22:04:28 | 只看该作者
还有几个我认为比较好的文件系统,JFS,XFS,综合实际使用比较,最终停留在EXT4和XFS上,整体觉得XFS更优秀一些,前辈有空可以研究一下,另外一个复杂的文件系统我个人并不喜欢,比如ZFS也很好。

对于个人而言,能可靠,稳定,快速,安全的保存和读写数据就是最本质的需求,过多的特性增加复杂度,有时实用价值也不大。

点评

一楼给出的那个 IBM 教程,比较了各个文件系统的代码量,发现 XFS 的代码量是最大的,达到 7 万行。ext3 是最小的,只有 1 万行。因此,XFS 不是一个简单的文件系统。  详情 回复 发表于 2019-3-9 01:08
回复

使用道具 举报

22#
 楼主| 发表于 2019-3-9 01:08:11 | 只看该作者
2011os_defend 发表于 2019-3-8 22:04
还有几个我认为比较好的文件系统,JFS,XFS,综合实际使用比较,最终停留在EXT4和XFS上,整体觉得XFS更优秀 ...

一楼给出的那个 IBM 教程,比较了各个文件系统的代码量,发现 XFS 的代码量是最大的,达到 7 万行。ext3 是最小的,只有 1 万行。因此,XFS 不是一个简单的文件系统。

点评

同意前辈的看法,xfs更新得算比较频繁,功能也越来越多。 另外ext3对手应该是ntfs吧?  详情 回复 发表于 2019-3-11 20:51
回复

使用道具 举报

23#
 楼主| 发表于 2019-3-10 15:38:57 | 只看该作者
本帖最后由 不点 于 2019-3-10 15:43 编辑

Unix 传统的 user-group-other 权限设置,被认为是不够用的,因此发展了 POSIX ACL(访问控制列表),我理解为 “附加的(或辅助的)权限控制”。相应地,在 inode 结构里面,也增加了 ACL 域。ACL 只用在特殊场合,传统的权限控制仍是基本的。如果我们为每个文件都预留很多 ACL 空间,浪费太严重。如果预留的空间少了,又可能不够用。这就看到,固定大小的 inode,暴露出了缺点。解决办法是,改进文件系统的设计,让 inode 结构长度可变。

既然 inode 结构长度都可以不固定了,那么,考虑干脆把它与文件内容放在一起。比如,将它放在文件簇链的尾部,不占用额外的空间。当然了,如果尾部剩余的空间不够用,那就多分配一簇的空间。通常 1 簇至少有 4K,足够用了。无论是否额外分配一簇,inode 结构都存放在链的最后一簇。最后一簇的簇号,就当成 inode 号码。簇尾部的 inode 结构,可以设置成倒序的,即,从后向前记录每个结构成员。当然,要有个 inode 合法标志之类的东西,放在簇的末尾几个字节中。结构中也有一个字段,记录着文件的起始簇号。

上述讨论,适用于普通文件以及目录。对于特殊文件,例如设备、软链接等,它们占用的信息很少,可以考虑将它们的 inode 信息记录在目录项里面,不放在簇链中(若放在簇链中,就太浪费了)。这些特殊文件,由于存放在目录项中,因此,它们的 inode 号可以无定义,或者说,不存在。

长度为 1K 的小文件(这里是指普通文件,不考虑目录),也可以直接放在目录项中(这种情况无 inode 号)。对于无 inode 号的文件,它们是无法用来进行硬链接的。

回复

使用道具 举报

24#
 楼主| 发表于 2019-3-10 16:00:50 | 只看该作者
嗯,得补充一个重要的理念。一个文件系统用起来是否简单,与它设计起来是否简单,是不同的概念。操作系统会让差别变得不可见,用户无法从直觉上感知文件系统是否简单。

然而,一个复杂的文件系统,有可能被高手、黑客隐藏用户不知道的某些东西,比如,偷窃用户的资料。你可能是在某个安全保密部门工作,你的电脑可能没有上网(只在安全的内部网工作),但是,你有可能用你的 U 盘跟外界交流文件,在外面上网。这个 U 盘里面的文件系统,就可能充当间谍,在你不知情的情况下,把重要的秘密信息带出去。文件系统越简单,就越不容易隐藏那些对你不利的东西。一个高手,可以混进开源队伍里面,在操作系统以及文件系统里面制造隐蔽的后门。
回复

使用道具 举报

25#
发表于 2019-3-10 21:33:25 | 只看该作者
不点大师又在钻研新领域了啊。。。
文件系统么,没研究,只会用。反正gnux下首选ext2/3/4/5,  win下当然ntfs,优盘和移动硬盘用fat和exfat。。。

reactOS新版氏同时支持fat和btrfs的,或许以后btrfs也有可能成为win和lin之间都能较好工作的文件系统选择呢。。。

点评

没什么目的,谈不上钻研,闲着没事,碰上啥就想啥。btrfs 的体积比 ext4 大,翻倍还多。 在 linux kernel 源代码中, squashfs 164K fat 207K ext2 265K ntfs 967K ext4  详情 回复 发表于 2019-3-10 22:43
回复

使用道具 举报

26#
 楼主| 发表于 2019-3-10 22:43:48 | 只看该作者
gnuxwy 发表于 2019-3-10 21:33
不点大师又在钻研新领域了啊。。。
文件系统么,没研究,只会用。反正gnux下首选ext2/3/4/5,  win下当然nt ...

没什么目的,谈不上钻研,闲着没事,碰上啥就想啥。btrfs 的体积比 ext4 大,翻倍还多。

在 linux kernel 源代码中,

squashfs   164K
fat           207K
ext2         265K
ntfs          967K
ext4       1.44M
btrfs       3.35M
xfs         3.64M

回复

使用道具 举报

27#
 楼主| 发表于 2019-3-11 16:52:11 | 只看该作者
在百度上搜 “硬链接的用途”,大都在讲硬链接和软链接的差别,而提到具体应用场景的,却很少很少。根据搜到的结果,总结一下,硬链接大致有两个作用:

1、节省磁盘空间,省去一个复制的操作。
2、保护重要文件,以防误删(相当于多备份了一份)。

如果就只有这两个作用的话,那也太寒碜了吧?

自从使用 Linux 以来,20 多年了,我还真没用过硬链接,连一次都没用过。软链接倒是用过,也经常见到系统中有很多软链接。

猜测一下硬链接很少被人使用的原因:

1、习惯问题。人们习惯于拷贝,不习惯于使用硬链接。
2、海量磁盘空间用不完,没必要节省那么一点空间。
3、硬链接不能跨文件系统,用起来感到生疏。用软链接更自由。
4、不能对目录进行硬链接,使用范围狭窄,加剧了“生疏感”和 “不习惯”。软链接没这问题。
5、(继续上述第 4 条的讨论)由于硬链接在人们正想用它(对目录进行操作)的时候却不行,它也就失去关键的吸引力了。大家无奈去寻找别的替代方法,比如,mount --bind (或 mount -o bind)就是这样一种替代方法,这种方法用于软链接失效的场合。
回复

使用道具 举报

28#
发表于 2019-3-11 20:51:01 | 只看该作者
不点 发表于 2019-3-9 01:08
一楼给出的那个 IBM 教程,比较了各个文件系统的代码量,发现 XFS 的代码量是最大的,达到 7 万行。ext3  ...

同意前辈的看法,xfs更新得算比较频繁,功能也越来越多。

另外ext3对手应该是ntfs吧?

点评

ext2/3/4之类的,属于 Linux/Unix 阵营;FAT/NTFS 类的属于微软阵营。阵营不同,谈不上 “对手”。FAT/NTFS 类的文件系统,只能在 Linux 中作为辅助文件系统,不能作为主文件系统。而 ext2/3/4 在 Linux 中是“主”  详情 回复 发表于 2019-3-12 08:36
回复

使用道具 举报

29#
 楼主| 发表于 2019-3-11 22:00:10 | 只看该作者
前面谈到硬链接的使用频度不高。假如不支持硬链接的话,文件系统可以设计得更简单一些。

没有了硬链接,也就不需要记录 link-count 了,甚至 inode 也不需要了。不知我理解得是否正确:我觉得这个 inode 就是为硬链接准备的。如果不要硬链接了,也就不需要 inode 号码了。既然 inode 号码都不要了,那么 inode 也就不需要了。把 inode 结构里面的信息直接放在目录项中即可(正如微软的 FAT、exFAT 那样)。前面说了,目录项本来就不是固定长度的,因此,再添加一些 inode 成员信息,也不影响大局。

微软 exFAT 的目录项,光是 255 个 unicode 字符,都要消耗 17×32=544 字节,再加上其他信息,总共会超过 600 字节。现在在 ext4 的目录项中添加 inode 信息,最多也只有 263+256=519 字节而已。我们可以更灵活地处理,将目录项的最大长度尽量放宽一些,比如说,必要的时候,它可以达到 4K,甚至也可以完全不封顶(不封顶其实是说可以达到双字节整数的自然上限 64K,这不会带来什么问题,因为实际的目录项长度平均都会很小的,低于 100 字节)。
回复

使用道具 举报

30#
发表于 2019-3-11 22:38:42 | 只看该作者
真氏不懂这些底层文件系统的实现细节,看到不点大师的分析,真的有不明觉厉的感觉。。。

点评

真人不露相,您太客气了。文件系统是旧领域,不是新领域。万事万物,都有一个发展过程。每个发展的阶段,也都有其缺点或局限性,都有改进的余地,都可以加入新的思想在里面。在新思想渗透进去之后,或许也可看成是进  详情 回复 发表于 2019-3-12 09:45
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2025-12-11 07:49

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表