#include <vfs.h>
#define DENTRY_HASH_TABLE_SIZE 233
+static kmem_cache_t *dentry_kmem_cache = NULL;
typedef struct {
list_head_t list;
mutex_t mutex;
return mod;
}
-dentry_t *dentry_alloc(dentry_t *parent, qstr_t *s) {
+dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s) {
dentry_t *dentry = NULL;
+
+ assert(s != NULL);
+ assert(s->len > 0);
+ assert(s->len < DENTRY_INLINE_NAME_LEN - 1);
+
+ dentry = kmem_cache_zalloc(dentry_kmem_cache, 0);
+ if (dentry == NULL) {
+ panic("no mem for dentry");
+ return dentry;
+ }
+
+ dentry->d_flags = 0;
+
+ dentry->d_name.len = 0;
+ dentry->d_name.name = 0;
+
+ memcpy(dentry->d_inline_name, s->name, s->len);
+ dentry->d_inline_name[s->len] = 0;
+
atomic_set(&dentry->d_count, 1);
- panic("to do");
+
+ if (parent != NULL) {
+ dentry->d_parent = parent;
+ } else {
+ dentry->d_parent = dentry;
+ }
+
+ INIT_LIST_HEAD(&dentry->d_child);
+ INIT_LIST_HEAD(&dentry->d_subdirs);
+ INIT_LIST_HEAD(&dentry->d_hash);
+
+ dentry->d_sb = NULL;
+ dentry->d_inode = NULL;
+ dentry->d_ops = NULL;
+ dentry->d_private = NULL;
+
+ return dentry;
+}
+
+dentry_t *dentry_alloc_root(inode_t *root_inode) {
+ dentry_t *dentry;
+
+ assert(root_inode != NULL);
+
+ static const qstr_t name = {.name = "/", .len = 1, .hash = 0};
+ dentry = dentry_alloc(NULL, &name);
+ if (dentry != NULL) {
+ dentry->d_sb = root_inode->i_sb;
+ dentry->d_parent = dentry;
+ }
+ dentry->d_inode = root_inode;
+
return dentry;
}
return ret;
}
-kmem_cache_t *dentry_kmem_cache = NULL;
-
void dentry_cache_init() {
kmem_cache_t *dentry_kmem_cache = kmem_cache_create("dentry_cache", sizeof(dentry_t), 4);
if (NULL == dentry_kmem_cache) {
#include "system.h"
#include "vfs.h"
-superblock_t *ext2_read_super(superblock_t *sb, void *data) { return sb; }
+// superblock_t *ext2_read_super(superblock_t *sb, void *data) { return sb; }
fs_type_t ext2_fs_type = {
.name = "ext2",
- .read_super = ext2_read_super,
+ // .read_super = ext2_read_super,
.next = 0,
};
*/
#include <fs.h>
#include <io.h>
+#include <mm.h>
#include <printk.h>
#include <system.h>
// void ext2_setup_fs();
unsigned int ext2_search_inpath(const char *path);
-// void setup_fs() {
-// ext2_setup_fs();
-// }
-
unsigned int namei(const char *path) { return ext2_search_inpath(path); }
+
+vfsmount_t rootfs_vfsmount;
+
+dentry_t rootfs_root_dentry;
+
+void setup_fs() {
+ // ext2_setup_fs();
+
+ void inode_cache_init();
+ inode_cache_init();
+
+ void dentry_cache_init();
+ dentry_cache_init();
+
+ void init_mount();
+ init_mount();
+}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: fslib.c
+ * Author: Zhao Yanbai
+ * 2024-08-31 21:12:58 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include "fs.h"
+
+const file_operations_t simple_dir_operations = {
+
+};
* Description: none
* ------------------------------------------------------------------------
*/
+
+#include "assert.h"
+#include "fs.h"
+#include "mm.h"
+#include "printk.h"
+#include "system.h"
+
+static kmem_cache_t *g_inode_kmem_cache = NULL;
+
+inode_t *alloc_inode(superblock_t *sb) {
+ inode_t *inode = 0;
+
+ assert(NULL != sb->sb_ops);
+ // assert(NULL != sb->sb_ops->alloc_inode);
+
+ if (NULL != sb->sb_ops->alloc_inode) {
+ inode = sb->sb_ops->alloc_inode(sb);
+ } else {
+ inode = kmem_cache_alloc(g_inode_kmem_cache, 0);
+ }
+
+ if (0 == inode) {
+ printk("alloc inode fail");
+ }
+
+ static file_operations_t empty_fops;
+ static inode_operations_t empty_iops;
+ inode->i_sb = sb;
+ // inode->i_sem;
+ inode->i_fops = &empty_fops;
+ inode->i_ops = &empty_iops;
+ inode->i_size = 0;
+ return inode;
+}
+
+void init_special_inode(inode_t *inode, umode_t mode, dev_t rdev) {
+ inode->i_mode = mode;
+ if (S_ISCHR(mode)) {
+ panic("todo");
+ } else if (S_ISBLK(mode)) {
+ panic("todo");
+ } else {
+ panic("todo");
+ }
+}
+
+void inode_cache_init() {
+ g_inode_kmem_cache = kmem_cache_create("inode_kmem_cache", sizeof(inode_t), 4);
+ assert(g_inode_kmem_cache != NULL);
+
+ //
+}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: mount.c
+ * Author: Zhao Yanbai
+ * 2024-08-30 21:40:57 Friday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include "mount.h"
+
+#include "irq.h"
+#include "mm.h"
+#include "string.h"
+#include "system.h"
+
+kmem_cache_t *vfsmount_kmem_cache = 0;
+
+// 通过挂载点目录的 path_t 也就是 {mount, dentry}计算hash
+// 就可以得到所有挂载在该目录上的挂载描述符 vfsmount
+vfsmount_t **vfsmount_hash_table = 0;
+int vfsmount_hash_table_size = 0;
+
+vfsmount_t *alloc_vfsmount(const char *name) {
+ vfsmount_t *mnt = 0;
+
+ mnt = (vfsmount_t *)kmem_cache_zalloc(vfsmount_kmem_cache, 0);
+
+ if (0 == mnt) {
+ panic("no mem alloc for vfsmount: %s", name);
+ return 0;
+ }
+
+ INIT_LIST_HEAD(&mnt->mnt_list);
+ strncpy(mnt->mnt_devname, name, MAX_VFSMNT_NAME_LEN);
+
+ assert(mnt->hash_next == 0);
+
+ return mnt;
+}
+
+vfsmount_t *vfs_kernel_mount(fs_type_t *type, int flags, const char *name, void *data) {
+ int ret = 0;
+ vfsmount_t *mnt = 0;
+
+ assert(0 != type);
+
+ mnt = alloc_vfsmount(name);
+
+ ret = type->read_super(type, flags, name, data, mnt);
+
+ assert(mnt->mnt_sb != 0);
+ assert(mnt->mnt_root != 0);
+
+ mnt->mnt_point = mnt->mnt_root;
+ mnt->mnt_parent = mnt;
+
+ // if (type->flags & FS_TYPE_NODEV) {
+ // }
+
+ return mnt;
+}
+
+unsigned long vfsmount_table_hash(vfsmount_t *mnt, dentry_t *dentry) {
+ unsigned long h = (unsigned long)mnt / 5;
+ h += 1;
+ h += (unsigned long)dentry / 5;
+ h = h + (h >> 9);
+ return h & (vfsmount_hash_table_size - 1);
+}
+
+void add_vfsmount_to_hash_table(vfsmount_t *mnt) {
+ unsigned long hash = vfsmount_table_hash(mnt->mnt_parent, mnt->mnt_point);
+
+ uint32_t eflags;
+ irq_save(eflags);
+
+ vfsmount_t **p = vfsmount_hash_table + hash;
+
+ mnt->hash_next = *p;
+
+ *p = mnt;
+
+ irq_restore(eflags);
+}
+
+void init_mount() {
+ vfsmount_kmem_cache = kmem_cache_create("vfsmount", sizeof(vfsmount_t), 4);
+ if (0 == vfsmount_kmem_cache) {
+ panic("create vfsmount kmem cache failed");
+ }
+
+ vfsmount_hash_table = (vfsmount_t **)page2va(alloc_one_page(0));
+ memset(vfsmount_hash_table, 0, PAGE_SIZE);
+
+ vfsmount_hash_table_size = PAGE_SIZE / sizeof(vfsmount_t *);
+
+ assert(vfsmount_hash_table_size != 0);
+
+ // vfsmount_hash_table_size 应该是2的n次方的数
+ int bit1_cnt = 0;
+ for (int i = 0; i < sizeof(vfsmount_hash_table_size) * 8; i++) {
+ if (vfsmount_hash_table_size & (1 << i)) {
+ bit1_cnt++;
+ }
+ }
+ assert(bit1_cnt == 1);
+}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: mount.h
+ * Author: Zhao Yanbai
+ * 2024-08-30 21:40:51 Friday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include "vfs.h"
+
+vfsmount_t *vfs_kernel_mount(fs_type_t *type, int flags, const char *name, void *data);
}
int follow_down(dentry_t **dentry, vfsmount_t **vfsmnt) {
- assert(*dentry != NULL);
- assert(*vfsmnt != NULL);
-
- list_head_t *pos;
- list_for_each(pos, &((*dentry)->d_vfsmnt)) {
- vfsmount_t *tmp_mnt = list_entry(pos, vfsmount_t, mnt_clash);
- if (*vfsmnt == tmp_mnt->mnt_parent) {
- *vfsmnt = vfsmnt_get(tmp_mnt);
- vfsmnt_put(tmp_mnt->mnt_parent);
-
- dentry_put(*dentry);
- *dentry = dentry_get(tmp_mnt->mnt_root);
- }
- }
+ // assert(*dentry != NULL);
+ // assert(*vfsmnt != NULL);
+
+ // list_head_t *pos;
+ // list_for_each(pos, &((*dentry)->d_vfsmnt)) {
+ // vfsmount_t *tmp_mnt = list_entry(pos, vfsmount_t, mnt_clash);
+ // if (*vfsmnt == tmp_mnt->mnt_parent) {
+ // *vfsmnt = vfsmnt_get(tmp_mnt);
+ // vfsmnt_put(tmp_mnt->mnt_parent);
+
+ // dentry_put(*dentry);
+ // *dentry = dentry_get(tmp_mnt->mnt_root);
+ // }
+ // }
}
int path_walk(const char *path, namei_t *ni) {
#include "mm.h"
#include "string.h"
#include "system.h"
-#include "vfs.h"
-
-superblock_t *ramfs_read_super(superblock_t *sb, void *data);
-fs_type_t ramfs_type = {
- .name = "ramfs",
- .read_super = ramfs_read_super,
- .next = 0,
-};
typedef struct ramfs_superblock {
//
typedef struct ramfs_inode {
// d
+ inode_t vfs_inode;
} ramfs_inode_t;
-void ramfs_init() { vfs_register_filesystem(&ramfs_type); }
+static kmem_cache_t *g_ramfs_inode_cache = 0;
+
+// static inode_t *ramfs_alloc_inode(superblock_t *sb) {
+// ramfs_inode_t *inode = kmem_cache_alloc(g_ramfs_inode_cache, 0);
+// assert(inode != 0);
+
+// return &(inode->vfs_inode);
+// }
+
+static const file_operations_t ramfs_file_operations = {
+ .read = 0,
+};
+
+static const inode_operations_t ramfs_file_inode_operations = {
+
+};
+
+static const inode_operations_t ramfs_dir_inode_operations = {
+
+};
+
+inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) {
+ inode_t *inode = alloc_inode(sb);
+
+ if (NULL == inode) {
+ return inode;
+ }
+
+ inode->i_mode = mode;
+
+ switch (mode & S_IFMT) {
+ case S_IFREG:
+ // panic("S_IFREG: not implement");
+ inode->i_fops = &ramfs_file_operations;
+ inode->i_ops = &ramfs_file_inode_operations;
+ break;
+ case S_IFDIR:
+ panic("S_IFDIR: not implement");
+ inode->i_fops = &simple_dir_operations;
+ inode->i_ops = &ramfs_dir_inode_operations;
+ break;
+ case S_IFLNK:
+ panic("S_IFLNK: not implement");
+ break;
+ default:
+ init_special_inode(inode, mode, dev);
+ break;
+ }
+
+ return NULL;
+}
+
+static sb_operations_t ramfs_ops = {
+ // .alloc_inode = ramfs_alloc_inode,
+};
+
+int ramfs_fill_super_cb(superblock_t *sb, void *data) {
+ int err = 0;
+
+ // assert(sb->sb_ops != NULL);
+ inode_t *fs_root_inode = ramfs_get_inode(sb, S_IFDIR, 0);
+ assert(fs_root_inode != NULL);
+
+ dentry_t *fs_root_dentry = 0;
+ fs_root_dentry = dentry_alloc_root(fs_root_inode);
+ assert(fs_root_dentry != NULL);
+
+ sb->sb_root = fs_root_dentry;
+
+ return err;
+}
+
+int ramfs_read_super(fs_type_t *type, int flags, const char *name, void *data, vfsmount_t *mnt) {
+ int ret = 0;
+
+ ret = read_super_for_nodev(type, flags, data, ramfs_fill_super_cb, mnt);
+
+ return ret;
+}
+
+fs_type_t ramfs_type = {
+ .name = "ramfs",
+ .read_super = ramfs_read_super,
+ .next = 0,
+};
-superblock_t *ramfs_read_super(superblock_t *sb, void *data) { return sb; }
+void ramfs_init() {
+ vfs_register_filesystem(&ramfs_type);
+ g_ramfs_inode_cache = kmem_cache_create("ramfs_inode_cache", sizeof(ramfs_inode_t), 4);
+ assert(0 != g_ramfs_inode_cache);
+}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: super.c
+ * Author: Zhao Yanbai
+ * 2024-08-30 21:38:05 Friday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include "errno.h"
+#include "fs.h"
+#include "irq.h"
+#include "list.h"
+#include "system.h"
+
+LIST_HEAD(g_superblocks);
+
+static superblock_t *alloc_super(fs_type_t *type) {
+ superblock_t *s;
+ s = (superblock_t *)kzalloc(sizeof(superblock_t), 0);
+ if (0 == s) {
+ panic("alloc superblock for %s", type->name);
+ return s;
+ }
+
+ static sb_operations_t default_sb_ops;
+
+ s->sb_ops = &default_sb_ops;
+ INIT_LIST_HEAD(&s->sb_list);
+ INIT_LIST_HEAD(&s->sb_instance);
+
+ return s;
+}
+
+int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt) {
+ int ret = 0;
+ superblock_t *s = 0;
+
+ // 分配superblock
+
+ //
+ s->sb_flags = flags;
+
+ ret = fill_super(s, data);
+ if (0 != ret) {
+ }
+
+ return ret;
+}
+
+superblock_t *sget(fs_type_t *type, //
+ int (*test)(superblock_t *, void *), //
+ int (*set)(superblock_t *, void *), //
+ void *data //
+) {
+ int ret = 0;
+ superblock_t *s = 0;
+
+ if (0 != test) {
+ panic("not implemented");
+ }
+
+ // TOOD REMOVE
+ assert(0 == s);
+
+ s = alloc_super(type);
+ if (0 == s) {
+ return ERR_PTR(-ENOMEM);
+ }
+
+ assert(0 != set);
+
+ ret = set(s, data);
+ assert(0 == ret);
+
+ uint32_t eflags;
+ irq_save(eflags);
+ list_add_tail(&s->sb_list, &g_superblocks);
+ irq_restore(eflags);
+
+ return s;
+}
* ------------------------------------------------------------------------
*/
+#include <errno.h>
#include <string.h>
#include <system.h>
#include <vfs.h>
fs_type_t file_systems = {"filesystems", 0, 0};
-void vfs_register_filesystem(fs_type_t *fs) {
+int vfs_register_filesystem(fs_type_t *fs) {
int ret = 0;
+ assert(fs != NULL);
+ if (fs->next != NULL) {
+ return -EBUSY;
+ }
+
+ INIT_LIST_HEAD(&fs->sbs);
+
fs_type_t *add = &file_systems;
+ // TODO: 加锁、解锁保护
+
for (fs_type_t *fst = &file_systems; fst != 0; fst = fst->next) {
if (strcmp(fst->name, fs->name) == 0) {
- return;
+ return -EBUSY;
}
add = fst;
}
add->next = fs;
fs->next = 0;
+ return 0;
}
fs_type_t *vfs_find_filesystem(const char *name) {
panic("no ramfs");
}
- superblock_t *sb = fs->read_super(NULL, NULL);
+ // superblock_t *sb = fs->read_super(NULL, NULL);
}
/////////
} qstr_t;
typedef struct dentry dentry_t;
-
+typedef struct inode inode_t;
typedef struct sb_operations sb_operations_t;
typedef struct file_operations file_operations_t;
typedef struct inode_operations inode_operations_t;
typedef struct dentry_operations dentry_operations_t;
+typedef struct vfsmount vfsmount_t;
+typedef struct path path_t;
// super block
typedef struct superblock {
// 该超级起的根目录的 dentry
dentry_t *sb_root;
+
+ int sb_flags;
+
//
void *sb_private;
//
sb_operations_t *sb_ops;
+
+ list_head_t sb_list;
+ list_head_t sb_instance;
} superblock_t;
// dentry和inode为什么不合二为一?
// 所以dentry代表逻辑意义上的文件,记录的是逻辑意义上的属性
// 而inode结构代表的是物理意义上的文件
// 它们之间的关系是多对一的关系
-typedef struct inode {
+struct inode {
superblock_t *i_sb;
void *i_private;
semaphore_t i_sem;
// fops - file ops 的副本
- file_operations_t *i_fops;
+ const file_operations_t *i_fops;
// ops - inode ops
- inode_operations_t *i_ops;
+ const inode_operations_t *i_ops;
// 缓存的pages
list_head_t i_pages;
dev_t i_rdev; // inode所代表的设备号
loff_t i_size;
-} inode_t;
+
+ umode_t i_mode; // FILE DIR CHR BLK FIFO SOCK
+};
#define DENTRY_INLINE_NAME_LEN 16
struct dentry {
// char *d_name;
+ uint32_t d_flags;
qstr_t d_name;
char d_inline_name[DENTRY_INLINE_NAME_LEN];
struct sb_operations {
// alloc inode
- inode_t *alloc_inode(superblock_t *sb);
+ inode_t *(*alloc_inode)(superblock_t *sb);
// read_inode
};
//
};
+struct path {
+ dentry_t *dentry;
+ vfsmount_t *mount;
+};
+
// 每当将一个存储设备安装到现有文件系统中的某个节点时,内核就要为之建立一个vfsmount结构
// 这个结构中即包含着该设备的有关信息,也包含了安装点的信息
// 系统中的每个文件系统,包括根设备的根文件系统,都要经过安装
// 为被安装的设备的根目录创建一个inode,由sb->sb_ops->read_inode来实现
// 将superblock与被安装设备根目录的dentry关联
// 将vfsmount与被安装设备的根目录dentry关联
-typedef struct vfsmount {
+#define MAX_VFSMNT_NAME_LEN 32
+struct vfsmount {
dentry_t *mnt_point; // 挂载点 dentry
dentry_t *mnt_root; // 设备根目录 dentry
superblock_t *mnt_sb; // 被安装的设备的superblock
list_head_t mnt_list; // vfsmount 链表
- list_head_t mnt_clash;
+ vfsmount_t *hash_next;
+
+ char mnt_devname[MAX_VFSMNT_NAME_LEN];
+
+ // list_head_t mnt_clash;
// 先简单实现:不支持一个设备挂载多次,或一个目录被挂载多次
-} vfsmount_t;
+};
+
+#define FS_TYPE_NODEV 1
+#define FS_TYPE_BLKDEV 2
-typedef struct fs_type {
+typedef struct fs_type fs_type_t;
+struct fs_type {
const char *name;
- superblock_t *(*read_super)(superblock_t *, void *);
+ // superblock_t *(*read_super)(superblock_t *, void *);
+ int (*read_super)(fs_type_t *type, int flags, const char *name, void *data, vfsmount_t *mnt);
+ int flags; // FS_REQUIRES_DEV or NODEV
struct fs_type *next;
- list_head_t sbs; // 同属于这个文件系统的所有超级块链表
-} fs_type_t;
+ // 同属于这个文件系统的所有超级块链表
+ // 因为同名文件系统可能有多个实例,所有的该文件系统的实例的superblock,都通过sbs这个链到一起
+ list_head_t sbs;
+};
extern superblock_t *root_sb;
-void vfs_register_filesystem(fs_type_t *fs);
+int vfs_register_filesystem(fs_type_t *fs);
/////
+inode_t *alloc_inode(superblock_t *sb);
+void init_special_inode(inode_t *inode, umode_t mode, dev_t rdev);
+////
+
dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s);
int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry);
+dentry_t *dentry_alloc_root(inode_t *root_inode);
vfsmount_t *vfsmnt_get(vfsmount_t *m);
void vfsmnt_put(vfsmount_t *m);
void dentry_get_locked(dentry_t *dentry);
void dentry_put(dentry_t *dentry);
+
+/////
+extern const file_operations_t simple_dir_operations;
#include <types.h>
#include <vfs.h>
+#include "stat.h"
+
/* 分区表开始的位置 */
#define PARTS_POS 0x1BE
}
#endif
+typedef int (*fill_super_cb_t)(superblock_t *sb, void *data);
+int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt);
+
+superblock_t *sget(fs_type_t *type, //
+ int (*test)(superblock_t *, void *), //
+ int (*set)(superblock_t *, void *), //
+ void *data //
+);
+
#endif //_FS_H
kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align);
void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags);
+void *kmem_cache_zalloc(kmem_cache_t *cache, gfp_t gfpflags);
unsigned long __unused5;
} Stat, *pStat;
+// 8进制
#define S_IFMT 00170000
-#define S_IFSOCK 0140000
-#define S_IFLNK 0120000
-#define S_IFREG 0100000
-#define S_IFBLK 0060000
-#define S_IFDIR 0040000
-#define S_IFCHR 0020000
-#define S_IFIFO 0010000
+#define S_IFREG 0010000
+#define S_IFDIR 0020000
+#define S_IFBLK 0030000
+#define S_IFCHR 0040000
+#define S_IFLNK 0050000
+
#define S_ISUID 0004000
#define S_ISGID 0002000
#define S_ISVTX 0001000
-#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK)
-#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
-#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
-#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR)
-#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK)
-#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO)
-#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK)
+#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
+#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
+#define S_ISBLK(x) (((x) & S_IFMT) == S_IFBLK)
+#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR)
+#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
+
+// user权限
+#define S_IURWX 00700
+#define S_IUSRR 00400
+#define S_IUSRW 00200
+#define S_IUSRX 00100
+
+// group权限
+#define S_IGRWX 00070
+#define S_IGRPR 00040
+#define S_IGRPW 00020
+#define S_IGRPX 00010
+
+// other权限
+#define S_IORWX 00007
+#define S_IOTHR 00004
+#define S_IOTHW 00002
+#define S_IOTHX 00001
#endif //_STAT_H
})
void *kmalloc(size_t size, gfp_t gfpflags);
+void *kzalloc(size_t size, gfp_t gfpflags);
void kfree(void *addr);
#define panic(msg, ...) \
#define disableIRQ() cli()
#define enableIRQ() sti()
-#define ALIGN(x, a) (((x) + (a)-1) & ~((a)-1))
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
// 定义最大显存为 16MB
#define VRAM_VADDR_SIZE (16 << 20)
#endif
+#define MAX_ERRNO 4095
+
+#ifndef ASM
+
+#define IS_ERR_VALUE(x) (((unsigned long)(x)) >= ((unsigned long)(-MAX_ERRNO)))
+
+static inline void *ERR_PTR(long err) { return ((void *)(err)); }
+
+static inline long PTR_ERR(void *p) { return ((long)(p)); }
+
+static inline bool IS_ERR(void *p) { return IS_ERR_VALUE(p); }
+
+#endif
+
#endif //_SYSTEM_H
typedef uint64_t loff_t;
typedef uint32_t dev_t;
+typedef uint32_t umode_t;
typedef unsigned long pid_t;
typedef unsigned long mode_t;
void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags) { return slub_alloc(cache, gfpflags); }
+void *kmem_cache_zalloc(kmem_cache_t *cache, gfp_t gfpflags) {
+ void *p = slub_alloc(cache, gfpflags);
+ if (0 != p) {
+ memset(p, 0, cache->objsize);
+ }
+ return p;
+}
+
void kmem_cache_free(kmem_cache_t *cache, void *addr) {
page_t *page = 0;
return addr;
}
+void *kzalloc(size_t size, gfp_t gfpflags) {
+ void *p = kmalloc(size, gfpflags);
+ if (0 != p) {
+ memset(p, 0, size);
+ }
+
+ return p;
+}
+
void kfree(void *addr) {
page_t *page = get_head_page(va2page((unsigned long)addr));
kmem_cache_t *cache = page->cache;