configuration for simplicity:
- Each file’s size is less than 512 byte.
- Only one root directory and regular files under it.
- Pathname lookup includes only one component name.
建立 Root File System 的 mount object
1
2
3
4
5
6
7
8
9
| struct mount {
struct dentry* root; // root directory
struct filesystem* fs;
};
struct filesystem {
char* name;
int (*setup_mount)(struct filesystem* fs, struct mount* mount);
};
|
在 setup mount 的同時,建立對應的 vnode 與 directory entry (dentry)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| struct vnode {
struct vnode_operations* v_ops;
struct file_operations* f_ops;
struct dentry* dentry;
void* internal; // internal representation of a vnode
};
struct dentry {
char name[32];
struct dentry* parent;
struct list_head list;
struct list_head childs;
struct vnode* vnode;
int type;
struct mount* mountpoint;
struct dentry* mount_origin;
};
|
1
2
3
4
5
6
7
8
9
10
| void rootfs_init() {
struct filesystem* tmpfs = (struct filesystem*)kmalloc(sizeof(struct filesystem));
tmpfs->name = (char*)kmalloc(sizeof(char) * 6);
strcpy(tmpfs->name, "tmpfs");
tmpfs->setup_mount = tmpfs_setup_mount;
register_filesystem(tmpfs);
rootfs = (struct mount*)kmalloc(sizeof(struct mount));
tmpfs->setup_mount(tmpfs, rootfs);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| int tmpfs_setup_mount(struct filesystem* fs, struct mount* mount) {
mount->fs = fs;
mount->root = tmpfs_create_dentry(NULL, "/", DIRECTORY);
return 0;
}
struct dentry* tmpfs_create_dentry(struct dentry* parent, const char* name, int type) {
struct dentry* dentry = (struct dentry*)kmalloc(sizeof(struct dentry));
strcpy(dentry->name, name);
dentry->parent = parent;
list_head_init(&dentry->list);
list_head_init(&dentry->childs);
if (parent != NULL) {
list_add(&dentry->list, &parent->childs);
}
dentry->vnode = tmpfs_create_vnode(dentry);
dentry->mountpoint = NULL;
dentry->type = type;
return dentry;
}
struct vnode* tmpfs_create_vnode(struct dentry* dentry) {
struct vnode* vnode = (struct vnode*)kmalloc(sizeof(struct vnode));
vnode->dentry = dentry;
vnode->f_ops = tmpfs_f_ops;
vnode->v_ops = tmpfs_v_ops;
return vnode;
}
|
將對應的 file system 的 object 初始化
1
2
3
4
5
6
7
8
9
| int register_filesystem(struct filesystem* fs) {
// register the file system to the kernel.
// you can also initialize memory pool of the file system here.
if (!strcmp(fs->name, "tmpfs")) {
uart_printf("\n[%f] Register tmpfs", get_timestamp());
return tmpfs_register();
}
return -1;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| struct vnode_operations* tmpfs_v_ops;
struct file_operations* tmpfs_f_ops;
int tmpfs_register() {
tmpfs_v_ops = (struct vnode_operations*)kmalloc(sizeof(struct vnode_operations));
tmpfs_v_ops->create = tmpfs_create;
tmpfs_v_ops->lookup = tmpfs_lookup;
tmpfs_v_ops->ls = tmpfs_ls;
tmpfs_v_ops->mkdir = tmpfs_mkdir;
tmpfs_f_ops = (struct file_operations*)kmalloc(sizeof(struct file_operations));
tmpfs_f_ops->read = tmpfs_read;
tmpfs_f_ops->write = tmpfs_write;
return 0;
}
|