1. 实现文件系统要记住两个重要链表
a.文件系统链表。
b.每一个文件系统的mount挂载点链表。
2. 注意vfs提供的三类接口
a.和POSIX系统调用有关的接口 即实现open/read/write的操作的接口。
b.和底层介质有关的接口 即下接块设备层的接口。
c.如何管理自身的接口,即何时以及如何操作vfs数据结构,inode,dentry,mount等对象。
一个文件系统如果能实现上面三类接口,那它就是个完整的文件系统了。
3. Linux内核自带的ramfs就是一个现成的小的文件系统,但它有两个问题导致无法领略实现一个文件系统的全过程
a.ramfs无法让你自己设计底层模拟介质的格式,不完整。
b.ramfs调用了大量的fs/libfs.c中的内核库例程,不纯碎。
4. 下面是实现一个实现简单文件系统的案例
a.最多容纳512个文件(包括目录在内)。
b.每个文件包括元数据在内最多32个字节。
c.文件名最多8个字节。
5. 实现代码如下:
// tinyfs.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define MAXLEN 8
#define MAX_FILES 32
#define MAX_BLOCKSIZE 512
//定义每一个目录项的格式
struct dir_entry {
char filename[MAXLEN];
uint8_t idx;
};
//定义每一个文件的格式。
struct file_blk {
uint8_t busy;
mode_t mode;
uint8_t idx;
union {
uint8_t file_size;
uint8_t dir_children;
};
char data[0];
};
//下面的block数组所占据的连续内存就是我的tinyfs的介质,每一个元素代表一个文件。
struct file_blk block[MAX_FILES + 1];
int curr_count = 0;
//获得一个尚未使用的文件块,保存新创建的文件或者目录
static int get_block(void)
{
int i;
//就是一个遍历,但实现快速。
for (i = 2; i < MAX_FILES; i++) {
if (!block[i].busy) {
block[i].busy = 1;
return i;
}
}
return -1;
}
static struct inode_operations tinyfs_inode_ops;
//读取目录的实现
static int tinyfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
loff_t pos;
struct file_blk *blk;
struct dir_entry *entry;
int i;
pos = filp->f_pos;
if (pos)
return 0;
blk = (struct file_blk *)filp->f_dentry->d_inode->i_private;
if (!S_ISDIR(blk->mode)) {
return -ENOTDIR;
}
//循环获取一个目录的所有文件的文件名
entry = (struct dir_entry *)&blk->data[0];
for (i = 0; i <