summaryrefslogtreecommitdiff
path: root/etcfs.c
blob: 4440e051cceaaeb784296bd2168fdd1c73ce8d69 (plain)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#define DEBUG
#define ETCFS_MAGIC 0x49c643f4 /* random number */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/fs_context.h>
#include <linux/dcache.h>
#include <linux/mnt_idmapping.h>

#if 0
static const struct super_operations etcfs_ops = {

};
#endif

static int etcfs_fill_super(struct super_block *sb, strcut fc_context *fc) {
	struct inode *inode;
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_blocksize = PAGE_SIZE;
	sb->s_blocksize_bits = PAGE_SHIFT;
	sb->s_magic = ETCFS_MAGIC;
	sb->s_time_gran = 1; /* I have no idea what is's doing */

	inode = new_inode(sb);

	if (!inode)
		return -ENOMEM;

	inode->i_ino = get_next_ino();
	inode_init_owner(&nop_mnt_idmap, inode, NULL, S_IFDIR);
	inode->i_mapping->a_ops = &ram_aops;
	/*
	mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
	mapping_set_unevictable(inode->i_mapping);
	*/
	simple_inode_init_ts(inode);

	sb->s_root = d_make_root(inode);
	if (!sb->s_root)
		return -ENOMEM;
	return 0;
}

static int etcfs_get_tree(struct fs_context *fc) {
	pr_debug("Get tree\n");
	return get_tree_nodev(fc, etcfs_fill_super);
}

static struct fs_context_operations etcfs_context_ops = {
	.get_tree = etcfs_get_tree,
};

static int etcfs_init_fs_context(struct fs_context *fc) {
	pr_debug("Etcfs init fs context\n");
	fc->ops = &etcfs_context_ops;
	return 0;
}

static struct file_system_type etcfs_fs_type = {
	.name = "etcfs",
	.fs_flags = FS_USERNS_MOUNT,
	.init_fs_context = etcfs_init_fs_context,
};

static int __init etcfs_init(void) {
	int err;
	err = register_filesystem(&etcfs_fs_type);
	if (err) {
		return err;
	}
	return 0;
}

static void __exit etcfs_exit(void) {
	int err;
	err = unregister_filesystem(&etcfs_fs_type);
	if (err) {
		pr_err("Error, can't unregister filesystem: %d\n", err);
		return;
	}
	return;
}

module_init(etcfs_init);
module_exit(etcfs_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("c4llv07e <igor@c4llv07e.xyz>");
MODULE_DESCRIPTION("Read-only preconfigured etc filesystem");