VFS

来源:互联网 发布:网络通信平台 socket 编辑:程序博客网 时间:2024/06/06 04:42

VFS

 因为在一个操作系统中不单只有一种文件系统,要使操作系统能够支持不同的文件系统,让他们能够友好共存,这就是VFS(Virtaul Filesystem Switch)的使命。VFS将对各种不同文件系统的管理和操作纳入到一个统一的框架中,使得用户程序可以通过同一个文件系统调用,对各种不同的文件系统和文件进行操作,而无需关心文件属于什么文件系统。  

接下来看看具体实现:

//定义指向函数的指针,对应不同的文件系统,有不同的函数,使用这种方式可以//统一接口typedef unsigned int (*read_type_t)(struct fs_node*,unsigned int,unsigned int,unsigned char*);//读文件typedef unsigned int (*write_type_t)(struct fs_node*,unsigned int,unsigned int,unsigned char*);//写文件typedef void (*open_type_t)(struct fs_node*);//打开文件,然后可以接下其他动作typedef void (*close_type_t)(struct fs_node*);//关闭文件typedef struct dirent * (*readdir_type_t)(struct fs_node*,unsigned int);//获取目录文件信息,返回目录项指针,因为有很多的目录项(每个文件对应一个)typedef struct fs_node * (*finddir_type_t)(struct fs_node*,char *name);//找到文件
 上面是函数指针,实际上就是函数跳转表,每个函数指针指向具体文件系统用来实现文件操作的入口函数。    typedef 指令用来简化指针函数的写法,这样就可以在接下的结构体定义中,写出清晰的代码。

在看下界面的主体结构体:

typedef struct fs_node{    char name[128];     // 文件名    unsigned int mask;        // 权限掩码,读写和执行    unsigned int uid;         // 用户id,user id    unsigned int gid;         // 组id,group id    unsigned int flags;       // 文件类型    unsigned int inode;       //文件id,唯一,用来表示不同的文件    unsigned int length;      // 文件大小(byte)    unsigned int impl;        // An implementation-defined number.    read_type_t read;    write_type_t write;    open_type_t open;    close_type_t close;    readdir_type_t readdir;    finddir_type_t finddir;    struct fs_node *ptr; // 有符号链接时存在} fs_node_t;

可以这样初始化一个文件的函数指针:

root_nodes[i].read = &initrd_read;root_nodes[i].write = &initrd_write;

统一的函数实现如下,比如读文件:

unsigned int read_fs(fs_node_t *node, unsigned int offset, unsigned int size, unsigned char *buffer)//读取索引节点node的文件数据,读取从offset位置开始,大小为size的数据//将他们写到buffer中{    if (node->read != 0)    //有读函数        return node->read(node, offset, size, buffer);    else        return 0;}

initrd

  initrd 的英文含义是 boot loader initialized RAM disk,就是由 boot loader 初始化的内存盘。在 linux内核启动前, boot loader 会将存储介质中的 initrd 文件加载到内存,内核启动时会在访问真正的根文件系统前先访问该内存中的 initrd 文件系统。  

通过一下两个结构管理initrd中的文件。

unsigned int num_files; // ramdisk中的文件数typedef struct//文件格式信息{    unsigned char name[64];  // 文件名    unsigned int address;   // 文件在内存中的偏离起始位置的               //的大小,就是文件的地    unsigned int length;   // 文件的长度} initrd_file;

通过address和length,就可以找到文件,完成读写等操作。写操作如下:

static unsigned int write(fs_node_t *node,unsigned int offset,unsigned int size,unsigned char *buffer){    initrd_file header = file_headers[node->inode];    if(offset>header.length)        return 0;    if(size>strlen(buffer))        size=strlen(buffer);    file_headers[node->inode].length=offset+strlen(buffer);    root_nodes[node->inode].length=offset+strlen(buffer);    memcpy((unsigned char*)(header.offset+offset),buffer,size);    return size;}
0 0
原创粉丝点击