Linux 虚拟文件系统概观

        Linux 虚拟文件系统概观

作者 Richard Gooch <rgooch@atnf.cs.iro.au>
翻译 albcamus <albcamus@gmail.com>
最后更新:2007 年 6 月 24 日
版权:1999, Richard Gooch
版权:2005, Pekka Enberg
本文件以 GPLv2 许可发放

[翻译说明:Richard Gooch 的这份 Overview of the Linux Virtual File System 位于内核
源代码的 Documentation/filesystems/下, 文件名是 vfs.txt。 该文档在 Understanding
the Linux Kernel 中被推荐, 我是从 2.6.16 官方内核中拷贝出来翻译的。 自己知道水平
差, 理解和表达都不到位, 所以还是建议看原文:( ]


介绍
====

虚拟文件系统(也被称做虚拟文件系统切换)是内核中为应用程序提供文件系统接口的一个软件层。
同时, 它也为不同的文件系统共存, 提供了一种抽象。

open(2),stat(2),read(2),write(2),chmod(2)等VFS系统调用, 是在进程上下文中被
调用的。 文件锁的描述在 Documnetation/filesystems/Locking中。


目录项缓存(dcache)
-----------------

VFS实现了诸如 open(2),stat(2),chmod(2)等系统调用。 路径名作为参数传递给这些系统
调用, 然后VFS使用路径名, 在目录项缓存(也叫 dentry cache 或 dcache)中查找相应的目
录项(dentry)。 通过目录项缓存, 路径名(文件名)能迅速得转换成相应的目录项。 目录项只存
在于内存中, 不会保存到磁盘上:它们存在的意义在于性能。

目录项缓存(dcache)旨在维护整个文件空间的一个视图。 但大多数计算机无法将文件系统的整
个目录结构缓存在内存中, 因此有些文件没有被缓存。 为了把路径名解析成相应目录项(dentry),
VFS得一步步的将路径名分解,创建目录项(dentry),读取相应的Inode。 这个过程是通过
Inode中的查找方法做到的。

Inode 对象
---------

一个目录项 (dentry) 通常包含指向 inode 的指针。 Inode是文件系统中的对象, 诸如常规文件,
目录, 管道(FIFO) 和其他的文件系统对象。 它们要么保存在于磁盘上(块设备上的文件系统), 要么
存在于内存中(伪文件系统)。 当需要时, 在磁盘上的 inode会被读取到内存中; 对inode的修改也会
写回到磁盘上。 一个 Inode可以被多个目录项(dentry)指向(例如硬链接就是这样)。

查找一个文件的Inode, VFS需要调用它的父目录对应Inode的lookup()方法。 该方法由Inode所在
的文件系统实现来定义。 一旦 VFS找到了dentry(因此也就知道了inode), open(2)系统调用就能
打开文件、 stat(2)就能查看inode内的数据。 Stat(2)操作非常简单: 一旦 VFS找到了dentry,
它就查看相关的inode并把部分数据返回给用户空间。

File 对象
--------

打开文件时还需要一个操作: 分配一个file结构(就是内核对文件描述符的实现)。 初始化这个新分配的
file结构时, 其中的一个指针会指向目录项(dentry),另一个指针会指向文件操作成员函数表──这是
从 inode中取来的。 然后函数表中的open()方法会被调用, 这样, 就调用了文件系统自己的open方法。
File结构被放置在进程的文件描述符表中。

读、写和关闭文件(以及其他与 VFS有关的操作)时, 首先使用用户空间提供的的文件描述符找到相应的
file结构, 然后调用file结构指向的函数表中的相应函数, 去执行相应的操作。只要文件还在打开着, 目录
项(dentry)就处于使用状态, 也就意味着inode也处在使用状态。


注册和挂载一个文件系统
=====================

注册或注销一个文件系统, 使用如下的 API 函数:

#include <linux/fs.h>

extern int register_filesystem(struct file_system_type *);
extern int unregister_filesystem(struct file_system_type *);

传递进来的 file_system_type 结构描述了一个文件系统。 当有将把某个设备挂载到文件空间的某个目录
上的请求时, VFS会调用对应文件系统(由 file_system_type 结构代表)的 get_sb()方法。 挂载点的
目录项(dentry)将被更新, 指向inode的指针将指向新挂载的文件系统的根目录inode。
( 这里更新挂载点d_inode的描述是错的 )

在/proc/filesystems文件中, 你可以看到内核中所有已注册的文件系统。


file_system_type 结构
---------------------

该结构描述了文件系统。 例如 2.6.22 内核中的代码, 该结构具有下列成员:

struct file_system_type {
const char *name;
int fs_flags;
int (*get_sb) (struct file_system_type *, int,
const char *, void *, struct vfsmount *);
void (*kill_sb) (struct super_block *);
struct module *owner;
struct file_system_type * next;
struct list_head fs_supers;
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
};


name: 文件系统的名字, 例如"ext2"、"iso9660"、"msdos"等

fs_flags: 各种标志(亦即: FS_REQUIRES_DEV, FS_NO_DCACHE 等)

get_sb: 每当该类型的文件系统被挂载时, 调用该方法

kill_sb: 每当该类型的文件系统被卸载时, 调用该方法

owner: VFS 内部使用:多数情况下该被赋值为 THIS_MODULE

next: VFS 内部使用: 多数情况下该被赋值为 NULL

s_lock_key, s_umount_key: 处理锁依赖相关

get_sb()方法有如下参数:

struct file_system_type *fs_type: 描述文件系统, 由特定文件系统初始化

int flags: 挂载标志

const char *dev_name:要挂载的设备名

void *data: 任意的挂载选项, 通常是 ASCII 字符串的形式

struct vfsmount *mnt: 挂载点的VFS内部呈现

get_sb()方法必须探测 dev_name指定的块设备所包含的文件系统类型, 判断该方法是否支持fs_type
指定的文件系统。 如果dev_name指定的块设备被成功打开, 它将为块设备中的文件系统初始化一个
super_block结构, 如果失败, 将返回错误代码。

由get_sb()方法填充的 super_block结构的一些域中, s_op 最值得关注。 它指向是一个super_operations结构,
这个结构描述了文件系统的下一层的实现。

通常, 一个文件系统会使用通用的 get_sb()实现并自己提供一个 fill_super()方法。 通用
的 get_sb()实现有:

get_sb_bdev: 挂载一个基于块设备的文件系统

get_sb_nodev: 挂载不存在于磁盘上的文件系统

get_sb_single: 挂载所有挂载点共享一个super_block结构的文件系统

fill_super()方法具有下列参数:

struct super_block *sb: superblock 结构, fill_super()方法必须初始化它

void *data: 任意的挂载选项, 通常由 ASCII 字符串组成

int silent: 出错时是否打印错误信息


Superblock 对象
==============

一个 superblock 对象代表一个挂载的文件系统。


super_operations 结构
---------------------

该结构描述了 VFS 如何操作文件系统上的 superblock, 以 2.6.22 为例, 它具有下列成员:

struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);

void (*read_inode) (struct inode *);

void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *);
void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
void (*write_super_lockfs) (struct s
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值