-
Notifications
You must be signed in to change notification settings - Fork 94
/
Copy pathsimplefs.h
155 lines (127 loc) · 5.05 KB
/
simplefs.h
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef SIMPLEFS_H
#define SIMPLEFS_H
/* source: https://en.wikipedia.org/wiki/Hexspeak */
#define SIMPLEFS_MAGIC 0xDEADCELL
#define SIMPLEFS_SB_BLOCK_NR 0
#define SIMPLEFS_BLOCK_SIZE (1 << 12) /* 4 KiB */
#define SIMPLEFS_MAX_EXTENTS \
((SIMPLEFS_BLOCK_SIZE - sizeof(uint32_t)) / sizeof(struct simplefs_extent))
#define SIMPLEFS_MAX_BLOCKS_PER_EXTENT 8 /* It can be ~(uint32) 0 */
#define SIMPLEFS_MAX_SIZES_PER_EXTENT \
(SIMPLEFS_MAX_BLOCKS_PER_EXTENT * SIMPLEFS_BLOCK_SIZE)
#define SIMPLEFS_MAX_FILESIZE \
((uint64_t) SIMPLEFS_MAX_BLOCKS_PER_EXTENT * SIMPLEFS_BLOCK_SIZE * \
SIMPLEFS_MAX_EXTENTS)
#define SIMPLEFS_FILENAME_LEN 255
#define SIMPLEFS_FILES_PER_BLOCK \
(SIMPLEFS_BLOCK_SIZE / sizeof(struct simplefs_file))
#define SIMPLEFS_FILES_PER_EXT \
(SIMPLEFS_FILES_PER_BLOCK * SIMPLEFS_MAX_BLOCKS_PER_EXTENT)
#define SIMPLEFS_MAX_SUBFILES (SIMPLEFS_FILES_PER_EXT * SIMPLEFS_MAX_EXTENTS)
/* simplefs partition layout
* +---------------+
* | superblock | 1 block
* +---------------+
* | inode store | sb->nr_istore_blocks blocks
* +---------------+
* | ifree bitmap | sb->nr_ifree_blocks blocks
* +---------------+
* | bfree bitmap | sb->nr_bfree_blocks blocks
* +---------------+
* | data |
* | blocks | rest of the blocks
* +---------------+
*/
#ifdef __KERNEL__
#include <linux/jbd2.h>
#endif
struct simplefs_inode {
uint32_t i_mode; /* File mode */
uint32_t i_uid; /* Owner id */
uint32_t i_gid; /* Group id */
uint32_t i_size; /* Size in bytes */
uint32_t i_ctime; /* Inode change time */
uint32_t i_atime; /* Access time */
uint32_t i_mtime; /* Modification time */
uint32_t i_blocks; /* Block count */
uint32_t i_nlink; /* Hard links count */
uint32_t ei_block; /* Block with list of extents for this file */
char i_data[32]; /* store symlink content */
};
#define SIMPLEFS_INODES_PER_BLOCK \
(SIMPLEFS_BLOCK_SIZE / sizeof(struct simplefs_inode))
struct simplefs_sb_info {
uint32_t magic; /* Magic number */
uint32_t nr_blocks; /* Total number of blocks (incl sb & inodes) */
uint32_t nr_inodes; /* Total number of inodes */
uint32_t nr_istore_blocks; /* Number of inode store blocks */
uint32_t nr_ifree_blocks; /* Number of inode free bitmap blocks */
uint32_t nr_bfree_blocks; /* Number of block free bitmap blocks */
uint32_t nr_free_inodes; /* Number of free inodes */
uint32_t nr_free_blocks; /* Number of free blocks */
#ifdef __KERNEL__
journal_t *journal;
struct block_device *s_journal_bdev; /* v5.10+ external journal device */
struct bdev_handle
*s_journal_bdev_handle; /* v6.7+ external journal device */
unsigned long *ifree_bitmap; /* In-memory free inodes bitmap */
unsigned long *bfree_bitmap; /* In-memory free blocks bitmap */
#endif
};
#ifdef __KERNEL__
#include <linux/version.h>
/* compatibility macros */
#define SIMPLEFS_AT_LEAST(major, minor, rev) \
LINUX_VERSION_CODE >= KERNEL_VERSION(major, minor, rev)
#define SIMPLEFS_LESS_EQUAL(major, minor, rev) \
LINUX_VERSION_CODE <= KERNEL_VERSION(major, minor, rev)
/* A 'container' structure that keeps the VFS inode and additional on-disk
* data.
*/
struct simplefs_inode_info {
uint32_t ei_block; /* Block with list of extents for this file */
char i_data[32];
struct inode vfs_inode;
};
struct simplefs_extent {
uint32_t ee_block; /* first logical block extent covers */
uint32_t ee_len; /* number of blocks covered by extent */
uint32_t ee_start; /* first physical block extent covers */
};
struct simplefs_file_ei_block {
uint32_t nr_files; /* Number of files in directory */
struct simplefs_extent extents[SIMPLEFS_MAX_EXTENTS];
};
struct simplefs_file {
uint32_t inode;
char filename[SIMPLEFS_FILENAME_LEN];
};
struct simplefs_dir_block {
struct simplefs_file files[SIMPLEFS_FILES_PER_BLOCK];
};
/* superblock functions */
int simplefs_fill_super(struct super_block *sb, void *data, int silent);
void simplefs_kill_sb(struct super_block *sb);
/* inode functions */
int simplefs_init_inode_cache(void);
void simplefs_destroy_inode_cache(void);
struct inode *simplefs_iget(struct super_block *sb, unsigned long ino);
/* dentry function */
struct dentry *simplefs_mount(struct file_system_type *fs_type,
int flags,
const char *dev_name,
void *data);
/* file functions */
extern const struct file_operations simplefs_file_ops;
extern const struct file_operations simplefs_dir_ops;
extern const struct address_space_operations simplefs_aops;
/* extent functions */
extern uint32_t simplefs_ext_search(struct simplefs_file_ei_block *index,
uint32_t iblock);
/* Getters for superblock and inode */
#define SIMPLEFS_SB(sb) (sb->s_fs_info)
/* Extract a simplefs_inode_info object from a VFS inode */
#define SIMPLEFS_INODE(inode) \
(container_of(inode, struct simplefs_inode_info, vfs_inode))
#endif /* __KERNEL__ */
#endif /* SIMPLEFS_H */