Creating Linux virtual filesystems

I tried to create simplest vfs and this is really useless, "hellofs". Basically "libfs.c" does most of things which each filesystem is supposed to do.

doyu@oreo:~/modules$ sudo mount -t hellofs none mnt
doyu@oreo:~/modules$ ls mnt
hello.txt
doyu@oreo:~/modules$ cat mnt/hello.txt 
Hello World!

The source code is:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

#define HELLOFS_MAGIC 0x20060313

static int hellofs_open(struct inode *inode, struct file *filp) { return 0; }

static ssize_t hellofs_read_file(struct file *filp, char *buf,
                                 size_t count, loff_t *offset)
{
        const char *s = "Hello World!\n";
        if (*offset != 0)
                return 0;
        if (copy_to_user(buf, s, strlen(s)+1))
                return -EFAULT;
        *offset += count;
        return count;
}

static struct file_operations hellofs_file_ops = {
        .open   = hellofs_open,
        .read   = hellofs_read_file,
};

struct tree_descr hellofiles[] = {
        { NULL, NULL, 0 },
        { "hello.txt", &hellofs_file_ops, S_IWUSR|S_IRUGO },
        { "", NULL, 0},
};

static int hellofs_fill_super (struct super_block *sb, void *data, int silent)
{
        return simple_fill_super(sb, HELLOFS_MAGIC, hellofiles);
}

static struct super_block *hellofs_get_super(struct file_system_type *fst,
                                             int flags, const char *devname, void *data)
{
        return get_sb_single(fst, flags, data, hellofs_fill_super);
}

static struct file_system_type hellofs_type = {
        .owner          = THIS_MODULE,
        .name           = "hellofs",
        .get_sb         = hellofs_get_super,
        .kill_sb        = kill_litter_super,
};

static int __init hellofs_init(void)
{
        return register_filesystem(&hellofs_type);
}

static void __exit hellofs_exit(void)
{
        unregister_filesystem(&hellofs_type);
}

module_init(hellofs_init);
module_exit(hellofs_exit);

This should be improved somewhat...;)

This is based on http://lwn.net/Articles/57369/