1
Linux File System
? 文件系统
? VFS
VFS的作用
基于 VFS的文件访问
VFS重要数据结构
? 文件系统的注册与安装
? ext2,ext3文件系统
? 文件操作
? proc文件系统
? CRAMFS文件系统
2
各种各样的文件系统
? Windows FAT16,FAT32,NTFS
? 传统 UNIX,UFS (Unix File System)
? BSD文件系统 FFS(Fast File System)
? Proc File System,只存在于内存中
? Linux File System
– ext2 ( is first introduced in kernel 2.0.x )
– reiserfs ( is first introduced in kernel 2.2.x )
– ext3 ( is first introduced in kernel 2.4.x,default in RedHat now)
– xfs (from SGI )
– Jfs (from IBM )
? 嵌入式小型文件系统
? CRAMFS
? JFFS2
3
linux文件系统目录布局
To comply with FSSTND(File System STaNDard):
/ - first of mount point in linux
/etc - keep linux default configuration
/boot - keep important linux booting files(can be a separate file system)
/bin - Essential command binaries for both root and ord,users
/sbin - Essential system binaries for administrator
/dev - keep all device files
/usr - keep all user binary and X library
/home - keep user home directory
/proc - is pseudo file system for tracking running process and state of linux system
/var - keeping mail,log file and printer spooling
/lib - contain shared library that is required by system program
/tmp - contain system temporary file
/opt - Add-on application software packages
4
UNIX文件系统文件类型
? Directory --> catalogue of file name
? Normal file --> format of data
– source file
– text file
? Symbolic link --> a pointer to another file
? Special file --> use for device controller in
kernel
? Named pipe --> communication channel which
can be used by serveral processes(may be
irrelevant) in order to exchange data
5
硬链接( Hard Link)
[root@localhost link]# ls -l
total 1
-rw-r--r-- 1 root root 667 Oct 15 13:39 a
[root@localhost link]# ln a b
[root@localhost link]# ls -l
total 2
-rw-r--r-- 2 root root 667 Oct 15 13:39 a
-rw-r--r-- 2 root root 667 Oct 15 13:39 b
[root@localhost link]# rm a
rm,remove `a'? y
[root@localhost link]# ls -l
total 1
-rw-r--r-- 1 root root 667 Oct 15 13:39 b
inode
/root/link
a
b
6
符号链接( Symbolic link)
[root@localhost symlink]# ls -l
total 1
-rw-r--r-- 1 root root 667 Oct 15 13:39 a
[root@localhost symlink]# ln -s a b
[root@localhost symlink]# ls -l
total 1
-rw-r--r-- 1 root root 667 Oct 15 13:39 a
lrwxrwxrwx 1 root root 1 Oct 15 14:20 b -> a
[root@localhost yy]# rm a
rm,remove `a'? y
[root@localhost symlink]# ls -l
total 0
lrwxrwxrwx 1 root root 1 Oct 15 14:20 b -> a
[root@localhost symlink]# cat b
cat,b,No such file or directory
inode
/root/link
a
b
7
VFS(Virtual FileSystem)的作用
Virtual File System
Ext2 Ext3,..
Buffer Cache
Device Driver
Process
Control
Subsyste
m
System Call Interface
User Programs
Inter-process
communicatio
n
Scheduler
Memory
manageme
nt
Hardware
8
基于 VFS的文件访问
进程1
进程1
进程1
file 对象
file 对象
file 对象
in od e 对象超级块
磁盘
进程1
进程2
进程3
file 对象
file 对象
file 对象
超级块 in od e 对象
de ntry
对象
de ntry
对象
9
根目录
子目录 子目录
文件子目录
子目录
新文件系统根
d_subdirs
d_subdirs
d_child d_child
d_child
d_mounts d_covers
d_parent
d_parentVFS的目录项( dentry)
VFS的 dentry定义在 include/linux/dcache.h中
为了加快文件的查找,每一个曾被读取的目录或文件都可
能在目录高速缓存( directory cache) 中有一个 dentry项;
dentry描述了目录与文件的关系树。
10
VFS的目录项( dentry)
struct dentry { /*include/linux/dcache.h*/
atomic_t d_count;
unsigned int d_flags;
struct inode * d_inode; /* Where the name belongs to - NULL is negative */
struct dentry * d_parent; /* parent directory */
struct list_head d_hash; /* lookup hash list */
struct list_head d_lru; /* d_count = 0 LRU list */
struct list_head d_child; /* child of parent list */
struct list_head d_subdirs; /* our children */
struct list_head d_alias; /* inode alias list */
int d_mounted;
struct qstr d_name;
unsigned long d_time; /* used by d_revalidate */
struct dentry_operations *d_op;
struct super_block * d_sb; /* The root of the dentry tree */
unsigned long d_vfs_flags;
void * d_fsdata; /* fs-specific data */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
};
11
打开文件表
?linux系统运行期间维护一张以 struct file ( 在
include/linux/fs.h 中) 作为节点的双向链表(系统打
开文件表)。表头由 first_file给出。
struct file *first_file = NULL; /* fs/file_table.c */
?对于每个进程,struct task_struct中的 files指向的
files_struct结构中有一个 fd指针数组,即维护 一张
进程打开文件表。数组元素即是指向系统打开文件
表中某一节点的指针。
12
VFS重要数据结构
?files_struct ( 在 sched.h);
?file ( 在 fs.h);
?dentry ( 在 dcache.h);
?superblock( 在 fs.h);
?inode ( 在 fs.h)
13
文件系统类型
static struct file_system_type *file_systems =
(struct file_system_type *) NULL;
struct file_system_type {
struct super_block *(*read_super)();
/* 读出该文件系统在外存的 super_block */
const char *name; /* 文件系统的类型名 */
int requires_dev; /* 支持文件系统的设备 */
struct file_system_type * next;
/* 文件系统类型链表的后续指针 */
};
14
文件系统 注册与注销
? 文件系统类型的注册和注销函数
int register_filesystem(struct file_system_type * fs)
int unregister_filesystem(struct file_system_type * fs)
file_systems file_system_type file_system_type file_system_type
15
文件系统的安装( mount)
/
bin etcdev usr
Root filesystem /usr filesystem
Complete hierarchy after mounting /usr
/
bin manlib
/
bin etcdev usr
bin manlib
16
文件系统的安装( mount)
安装点 dentry
root
d_mounted!=0
i_sb mnt_mountpoint
mnt_root
下挂文件系统 安装点 vfsmount
17
已安装文件系统的描述
static LIST_HEAD(vfsmntlist);
struct vfsmount
{
struct list_head mnt_hash;
struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
struct list_head mnt_mounts; /* list of children,anchored here */
struct list_head mnt_child; /* and going through their mnt_child */
atomic_t mnt_count;
int mnt_flags;
char *mnt_devname; /* Name of device e.g,/dev/dsk/hda1 */
struct list_head mnt_list;
};
18
已安装文件系统的描述
mnt_sb s_type
mnt_sb
vfsmntlist
vfsmount super_block file_system_type
file_systems
19
路径查找
? 系统调用 open,mkdir,rename,stat等要查找路径
– open_namei()
? path_init()
? path_walk()
? link_path_walk();
? 返回时,struct nameidata中的 dentry和 mnt标识找
到的文件或目录
struct nameidata { /*include/linux/fs.h*/
struct dentry *dentry; /*找到的 dentry指针 */
struct vfsmount *mnt; /*找到的文件所在文件系统 */
struct qstr last;
unsigned int flags;
int last_type;};
20
ext2文件系统
? 支持 UNIX所有标准的文件系统特征,包括正文, 目录、设备文
件和连接文件等,这使得它很容易被 UNIX程序员接受。事实上
,ext2的绝大多数的数据结构和系统调用与经典的 UNIX一致
? 能够管理海量存储介质。支持多达 4TB的数据,即一个分区的容
量最大可达 4TB
? 支持长文件名,最多可达 255个字符,并且可扩展到 1012个字符
? 允许通过文件属性改变内核的行为;目录下的文件继承目录的属

? 支持文件系统数据, 即时同步, 特性,即内存中的数据一旦改变
,立即更新硬盘上的数据使之一致
? 实现了, 快速连接, ( fast symbolic links) 的方式,使得连接文
件只需要存放 inode的空间
? 允许用户定制文件系统的数据单元( block) 的大小,可以是
1024,2048 或 4096 个字节,使之适应不同环境的要求
? 使用专用文件记录文件系统的状态和错误信息,供下一次系统启
动时决定是否需要检查文件系统
21
ext2体系结构
??引导块 块组N - 1 块组N
超级块 组描述符 块位图
索引节点
位图
索引节点

数据块
块组0
22
内存中的 ext2 inode
? ext2_inode_info ( 在 include/linux/ext2_fs_i.h)
struct ext2_inode_info {
__u32 i_data[15];
__u32 i_flags;
__u32 i_faddr;
__u8 i_frag_no;
__u8 i_frag_size;
__u16 i_osync;
__u32 i_file_acl;
__u32 i_dir_acl;
__u32 i_dtime;
__u32 i_block_group;
__u32 i_next_alloc_block;
__u32 i_next_alloc_goal;
__u32 i_prealloc_block;
__u32 i_prealloc_count;
__u32 i_dir_start_lookup;
int i_new_inode:1; /* Is a freshly allocated inode */
};
23
外存中的 ext2 inode
? struct ext2_inode( 在
include/linux/ext2_fs.h)
? 内、外存 inode的读写,
ext2_read_inode()
ext2_update_inode()
24
Ext2_inode
1 2 个直接块
一次间接块
二次间接块
三次间接块
数据块
ext2_inode
数据块
数据块
数据块
数据块
数据块
25
文件读写
? read()和 write()
int read(int fd,void *buf,size_t nbytes);
int write(int fd,void *buf,size_t nbytes);
? read()调用 generic_file_read(),再调用
do_generic_file_read()读入内核缓冲区,然后调用
file_read_actor()将读入内容传入用户空间。最后调用
update_atime()修改 inode
? write()调用 generic_file_write()写数据入缓冲区,如果
是同步写( O_SYNC置位),则调用 generic_osync_inode()
将缓冲区中数据写入磁盘文件。
? 直接读写( read,write时将 O_DIRECT置位)
generic_file_read()先读 page cache
generic_file_write()先写入缓冲区
generic_file_direct_IO()直接读写( self-caching)
26
ext3文件系统
? 日志文件系统( journaling file system)
? 利用数据库的日志技术( log,checkpoint)
? 3种日志方式,journal,ordered,writeback
? 日志记录在 /.journal中(隐藏的文件)
? Kjournald—5s
? Reiserfs
27
proc文件系统
? /proc,一个虚拟文件系统,只存在于内存中,通过它
可以查询、设置系统的运行情况及各种系统参数。
? 系统中的很多应用都依赖于 proc文件系统,如命令
lsmod等同于 cat /proc/modules。
? 文件的大小为 0;
? 很多文件名体现了内核的相应参数,可以通过这个文件
名修改参数值。如 #echo 2048 > /proc/sys/shmmni,修改
共享内存段的限制。
? /proc下的, 数字目录, 指代了相应 pid的进程,如目录
,1” 下的内容就是 1#进程的各种信息。
28
CRAMFS
? 由 Linus Torvalds 参与开发的小型只读压缩文件系统
? Inode,文件名称和目录信息不压缩
? 单个文件最大为 16MB
? 数据压缩存放
? 适合不需要写、且体积较大的文件系统,如 /lib,/opt等
? 与 JFFS2,Cloop相比,读取速度快
? 压缩率可以超过 50%
? 读取文件时,每次读取 4k内容,解压缩到 cache中
? Linux内核已提供了对 cramfs的支持,只要编译时选中
? 创建文件系统(生成 image文件)
#mkcramfs /lib lib.cramfs
#mkcramfs /usr usr.cramfs
? 挂载文件系统
#mount –t cramfs lib.cramfs /lib –o loop
#mount –t cramfs usr.cramfs /usr –o loop
29
CRAMFS
Super_block:76bytes,cramfs_inode:12bytes
Cramfs_inode中的 offset的单位为 4字节
30
CRAMFS
根目录的 inode内容,根目录的内容在起始偏移 19*4=76字节处
根目录下的子目录与文件
11*12 + 14*4 = 188