working vfs
hardcoded structure - mount - list directory - read a file
This commit is contained in:
parent
e087715248
commit
9b6c341349
5
Makefile
5
Makefile
@ -3,4 +3,7 @@ obj-m += voidfs.o
|
|||||||
all: voidfs
|
all: voidfs
|
||||||
|
|
||||||
voidfs:
|
voidfs:
|
||||||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
|
||||||
|
|
||||||
|
clean:
|
||||||
|
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
|
||||||
|
102
voidfs.c
102
voidfs.c
@ -17,6 +17,10 @@ static int voidfs_fill_super(struct super_block *sb, void *data, int silent);
|
|||||||
void voidfs_kill_superblock(struct super_block *sb);
|
void voidfs_kill_superblock(struct super_block *sb);
|
||||||
|
|
||||||
|
|
||||||
|
struct dentry *voidfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int);
|
||||||
|
int voidfs_readdir(struct file *fp, struct dir_context *ctx);
|
||||||
|
|
||||||
|
int voidfs_open(struct inode *inode, struct file *fp);
|
||||||
ssize_t voidfs_read(struct file *fp, char __user *buf, size_t len, loff_t *ppos);
|
ssize_t voidfs_read(struct file *fp, char __user *buf, size_t len, loff_t *ppos);
|
||||||
ssize_t voidfs_write(struct file *fp, const char __user *buf, size_t len, loff_t *ppos);
|
ssize_t voidfs_write(struct file *fp, const char __user *buf, size_t len, loff_t *ppos);
|
||||||
|
|
||||||
@ -30,36 +34,70 @@ struct file_system_type voidfs_fs_type = {
|
|||||||
|
|
||||||
struct super_operations voidfs_super_ops = {
|
struct super_operations voidfs_super_ops = {
|
||||||
// null for now
|
// null for now
|
||||||
}
|
};
|
||||||
|
|
||||||
struct super_operations voidfs_inode_ops = {
|
struct inode_operations voidfs_inode_ops = {
|
||||||
// null for now
|
.lookup = voidfs_lookup,
|
||||||
}
|
};
|
||||||
|
|
||||||
struct file_operations voidfs_dir_ops = {
|
struct file_operations voidfs_dir_ops = {
|
||||||
.iterate_shared = voidfs_readdir,
|
.iterate_shared = voidfs_readdir,
|
||||||
}
|
};
|
||||||
|
|
||||||
struct file_operations voidfs_file_ops = {
|
struct file_operations voidfs_file_ops = {
|
||||||
|
.open = voidfs_open,
|
||||||
.read = voidfs_read,
|
.read = voidfs_read,
|
||||||
.write = voidfs_write,
|
.write = voidfs_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dentry *voidfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int) {
|
||||||
|
struct inode* inode = NULL;
|
||||||
|
|
||||||
|
printk(KERN_INFO "listing directory %s %s", dentry->d_parent->d_name.name, dentry->d_name.name);
|
||||||
|
printk(KERN_INFO " %p %p", dentry->d_inode, dir->i_sb);
|
||||||
|
|
||||||
|
// parse an entry path
|
||||||
|
// right now, let's just create a dummy path
|
||||||
|
if (strcmp(dentry->d_name.name, "dummyfile") == 0) {
|
||||||
|
// inode->i_sb = sb;
|
||||||
|
inode = new_inode(dir->i_sb);
|
||||||
|
inode->i_op = &voidfs_inode_ops;
|
||||||
|
inode->i_fop = &voidfs_file_ops;
|
||||||
|
inode->i_mode = S_IFREG | 0644;
|
||||||
|
inode->i_ino = 3;
|
||||||
|
// inode->i_private = (void*)1;
|
||||||
|
}
|
||||||
|
|
||||||
|
d_add(dentry, inode);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int voidfs_readdir(struct file *fp, struct dir_context *ctx) {
|
int voidfs_readdir(struct file *dir, struct dir_context *ctx) {
|
||||||
// populate directory entry maybe
|
// populate directory entry maybe
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct super_block *sb;
|
struct super_block *sb;
|
||||||
|
|
||||||
printk(KERN_INFO "readdir");
|
printk(KERN_INFO "readdir");
|
||||||
|
|
||||||
inode = file_inode(file);
|
if (ctx->pos > 3) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
inode = file_inode(dir);
|
||||||
sb = inode->i_sb;
|
sb = inode->i_sb;
|
||||||
|
|
||||||
// if (inode &&
|
dir_emit_dots(dir, ctx);
|
||||||
// !dir_emit(ctx, f->filename, SIMPLEFS_FILENAME_LEN, f->inode,
|
|
||||||
// DT_UNKNOWN))
|
|
||||||
// break;
|
|
||||||
|
|
||||||
|
dir_emit(ctx, "dummydir", 8, 2, DT_DIR);
|
||||||
|
ctx->pos += 1;
|
||||||
|
dir_emit(ctx, "dummyfile", 9, 3, DT_REG);
|
||||||
|
ctx->pos += 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int voidfs_open(struct inode *inode, struct file *fp) {
|
||||||
|
printk(KERN_INFO "voidfs open");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +105,14 @@ ssize_t voidfs_read(struct file *fp, char __user *buf, size_t len, loff_t *ppos)
|
|||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct super_block *sb;
|
struct super_block *sb;
|
||||||
|
|
||||||
inode = file_inode(file);
|
printk(KERN_INFO "voidfs read");
|
||||||
|
|
||||||
|
// we only allow read 1 time, should be at the start
|
||||||
|
if (*ppos > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inode = file_inode(fp);
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
@ -83,14 +128,16 @@ ssize_t voidfs_read(struct file *fp, char __user *buf, size_t len, loff_t *ppos)
|
|||||||
// get as much as we can
|
// get as much as we can
|
||||||
|
|
||||||
if (copy_to_user(buf, buffer, nbytes)) {
|
if (copy_to_user(buf, buffer, nbytes)) {
|
||||||
brelse(bh);
|
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"Error copying file content to userspace buffer\n");
|
"Error copying file content to userspace buffer\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
*ppos += nbytes;
|
||||||
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t voidfs_write(struct file *fp, const char __user *buf, size_t len, loff_t *ppos) {
|
ssize_t voidfs_write(struct file *fp, const char __user *buf, size_t len, loff_t *ppos) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dentry *voidfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) {
|
struct dentry *voidfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) {
|
||||||
@ -127,41 +174,34 @@ static int voidfs_fill_super(struct super_block *sb, void *data, int silent) {
|
|||||||
if (!root_inode) {
|
if (!root_inode) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
inode_init_owner(root_inode, NULL, root_inode->i_mode);
|
root_inode->i_mode = S_IFDIR | 0644;
|
||||||
|
inode_init_owner(&nop_mnt_idmap, root_inode, NULL, root_inode->i_mode);
|
||||||
|
|
||||||
root_inode->i_sb = sb;
|
root_inode->i_sb = sb;
|
||||||
root_inode->i_op = &voidfs_inode_ops;
|
root_inode->i_op = &voidfs_inode_ops;
|
||||||
root_inode->i_atime = root_inode->i_mtime
|
|
||||||
= root_inode->i_ctime
|
|
||||||
= CURRENT_TIME;
|
|
||||||
|
|
||||||
root_inode->i_fop = &voidfs_dir_ops;
|
root_inode->i_fop = &voidfs_dir_ops;
|
||||||
|
|
||||||
// create a dummy file entry point
|
|
||||||
root_inode->i_fop = &voidfs_file_ops;
|
|
||||||
|
|
||||||
sb->s_root = d_make_root(root_inode);
|
sb->s_root = d_make_root(root_inode);
|
||||||
|
|
||||||
|
// create a dummy file entry point
|
||||||
|
// root_inode->i_fop = &voidfs_file_ops;
|
||||||
|
|
||||||
|
// create a child file
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void voidfs_kill_superblock(struct super_block *sb) {
|
void voidfs_kill_superblock(struct super_block *sb) {
|
||||||
printk(KERN_INFO "voidfs try to unmount\n");
|
printk(KERN_INFO "voidfs try to unmount\n");
|
||||||
|
|
||||||
|
kill_block_super(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init voidfs_init(void)
|
static int __init voidfs_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
// hellofs_inode_cache = kmem_cache_create("hellofs_inode_cache",
|
|
||||||
// sizeof(struct hellofs_inode),
|
|
||||||
// 0,
|
|
||||||
// (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD),
|
|
||||||
// NULL);
|
|
||||||
// if (!hellofs_inode_cache) {
|
|
||||||
// return -ENOMEM;
|
|
||||||
// }
|
|
||||||
|
|
||||||
ret = register_filesystem(&voidfs_fs_type);
|
ret = register_filesystem(&voidfs_fs_type);
|
||||||
if (likely(0 == ret)) {
|
if (likely(0 == ret)) {
|
||||||
printk(KERN_INFO "Sucessfully registered voidfs\n");
|
printk(KERN_INFO "Sucessfully registered voidfs\n");
|
||||||
@ -190,5 +230,5 @@ static void __exit voidfs_exit(void)
|
|||||||
module_init(voidfs_init);
|
module_init(voidfs_init);
|
||||||
module_exit(voidfs_exit);
|
module_exit(voidfs_exit);
|
||||||
|
|
||||||
MODULE_LICENSE("MIT");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("nganhkhoa");
|
MODULE_AUTHOR("nganhkhoa");
|
||||||
|
Loading…
Reference in New Issue
Block a user