-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaeon.h
328 lines (278 loc) · 9.25 KB
/
aeon.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
/*
*
* BRIEF DESCRIPTION
*
* Definitions for the AEON filesystem.
*
* Copyright 2018 Fumiya Shigemitsu <[email protected]>
* Copyright 2015-2016 Regents of the University of California,
* UCSD Non-Volatile Systems Lab, Andiry Xu <[email protected]>
* Copyright 2012-2013 Intel Corporation
* Copyright 2009-2011 Marco Stornelli <[email protected]>
* Copyright 2003 Sony Corporation
* Copyright 2003 Matsushita Electric Industrial Co., Ltd.
* 2003-2004 (c) MontaVista Software, Inc. , Steve Longerbeam
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __AEON_H
#define __AEON_H
#define AEON_MAGIC 0xEFF10
#define AEON_ROOT_INO (1)
/*
* The first block contains super blocks;
* and reserved inodes.
*/
#define RESERVED_BLOCKS 1
/* AEON supported data blocks */
#define AEON_BLOCK_TYPE_4K 0
#include <linux/types.h>
#include <linux/magic.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/crc32.h>
#include <linux/slab.h>
/* manual */
#define AEON_I_SHIFT 8
#define AEON_D_SHIFT 8
#define AEON_PAGES_FOR_INODE 1
#define AEON_PAGES_FOR_DENTRY 1
#define SEED 131
/* auto */
#define CHECKSUM_SIZE 4
#define AEON_SHIFT 12
#define AEON_DEF_BLOCK_SIZE_4K (1 << AEON_SHIFT)
#ifdef pr_fmt
#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#endif
extern void aeon_err_msg(struct super_block *sb, const char *fmt, ...);
#define AEON_ERR(msg) printk(KERN_CRIT "aeon_err:" \
"%s - %d - %d\n", \
__func__, __LINE__, msg)
#define aeon_dbg(s, args ...) pr_info(s, ## args)
#define aeon_err(sb, s, args ...) aeon_err_msg(sb, s, ## args)
#define aeon_warn(s, args ...) pr_warning(s, ## args)
#define aeon_info(s, args ...) pr_info(s, ## args)
#ifdef CONFIG_AEON_FS_DEBUG_MODE
#define aeon_dbgv(s, args ...) pr_info(s, ## args)
#else
#define aeon_dbgv(s, args ...) do { } while (0)
#endif
#define READDIR_END (ULONG_MAX)
#define ANY_CPU (65536)
#define dax_sem_down_write(aeon_inode) down_write(&(aeon_inode)->dax_sem)
#define dax_sem_up_write(aeon_inode) up_write(&(aeon_inode)->dax_sem)
/*
* Mount flags
*/
#define AEON_MOUNT_PROTECT 0x000001 /* wprotect CR0.WP */
#define AEON_MOUNT_DAX 0x000008 /* Direct Access */
#define AEON_MOUNT_COMPRESSION 0x000010 /* Compression mode */
#define AEON_MOUNT_FORMAT 0x000200 /* was FS formatted on mount? */
#define AEON_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */
#define set_opt(o, opt) (o |= AEON_MOUNT_##opt)
#define clear_opt(o, opt) (o &= ~AEON_MOUNT_##opt)
#define test_opt(sb, opt) (AEON_SB(sb)->s_mount_opt & \
AEON_MOUNT_##opt)
/*
* ioctl commands
*/
#define AEON_IOC_GETFLAGS FS_IOC_GETFLAGS
#define AEON_IOC_SETFLAGS FS_IOC_SETFLAGS
#define AEON_IOC_GETVERSION FS_IOC_GETVERSION
#define AEON_IOC_SETVERSION FS_IOC_SETVERSION
#define AEON_IOC_INODE_ATTACK _IOWR('f', 5, long)
#define AEON_IOC_DENTRY_ATTACK _IOWR('f', 6, long)
#define AEON_IOC_CHILD_ID_ATTACK _IOWR('f', 7, long)
#define AEON_IOC_TEST_LIBAEON _IOWR('f', 8, long)
#define AEON_IOC_TEST_COMPRESSION _IOWR('f', 9, long)
/*
* ioctl commands in 32 bit emulation
*/
#define AEON_IOC32_GETFLAGS FS_IOC32_GETFLAGS
#define AEON_IOC32_SETFLAGS FS_IOC32_SETFLAGS
#define AEON_IOC32_GETVERSION FS_IOC32_GETVERSION
#define AEON_IOC32_SETVERSION FS_IOC32_SETVERSION
/*
* ioctl flags
*/
#define AEON_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */
#define AEON_APPEND_FL FS_APPEND_FL /* writes to file may only append */
#define AEON_FL_USER_VISIBLE FS_FL_USER_VISIBLE
#define AEON_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE
#define AEON_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
#define AEON_NODUMP_FL FS_NODUMP_FL /* do not dump file */
#define AEON_NOATIME_FL FS_NOATIME_FL /* do not update atime */
/* Flags that are appropriate for regular files (all but dir-specific ones). */
#define AEON_REG_FLMASK ~AEON_TOPDIR_FL
/* Flags that are appropriate for non-directories/regular files. */
#define AEON_OTHER_FLMASK (AEON_NODUMP_FL | AEON_NOATIME_FL)
extern int wprotect;
extern int compression;
struct aeon_mdata {
u64 pi_addr;
u64 de_addr;
u32 ino;
umode_t mode;
struct aeon_inode *pidir;
size_t size;
dev_t rdev;
};
struct opaque_list {
struct aeon_inode *pi;
struct aeon_dentry *de;
struct list_head opaque_list;
};
struct aeon_range_node {
struct rb_node node;
struct vm_area_struct *vma;
union {
struct {
unsigned long range_low;
unsigned long range_high;
};
struct {
unsigned long hash;
struct aeon_dentry *direntry;
};
struct {
unsigned long offset;
int length;
struct aeon_extent *extent;
};
};
u32 csum;
};
struct aeon_region_table {
spinlock_t r_lock;
u64 pmem_pool_addr;
__le64 freed;
__le32 i_num_allocated_pages;
__le32 i_range_high;
__le32 b_range_low;
__le64 allocated; /* allocated entire inodes */
__le16 i_allocated; /* allocated inodes in current pages */
__le32 i_head_ino;
__le64 i_blocknr; /* it can be deleted */
__le64 this_block; /* this table blocknr */
__le32 i_top_ino;
__le64 num_free_blocks;
__le64 alloc_data_count;
__le64 alloc_data_pages;
__le64 freed_data_count;
__le64 freed_data_pages;
/* The num of block range nodes when last saved */
__le16 range_nodes;
} __attribute((__packed__));
#include "aeon_super.h"
#include "aeon_inode.h"
#include "aeon_dir.h"
static inline int memcpy_to_pmem_nocache(void *dst, const void *src,
unsigned int size)
{
int ret;
ret = __copy_from_user_inatomic_nocache(dst, src, size);
return ret;
}
static inline unsigned int
aeon_get_numblocks(unsigned short btype)
{
return 1;
}
/*TODO: not use it and remove it */
static inline struct aeon_region_table *AEON_R_TABLE(struct inode_map *inode_map)
{
return (struct aeon_region_table *)(inode_map->i_table_addr);
}
static inline
struct aeon_region_table *aeon_get_rtable(struct super_block *sb, int cpu_id)
{
struct inode_map *inode_map = aeon_get_inode_map(sb, cpu_id);
return (struct aeon_region_table *)(inode_map->i_table_addr);
}
/* ======================= Write ordering ========================= */
#define CACHELINE_SIZE (64)
#define CACHELINE_MASK (~(CACHELINE_SIZE - 1))
#define CACHELINE_ALIGN(addr) (((addr)+CACHELINE_SIZE-1) & CACHELINE_MASK)
extern int support_clwb;
static inline bool arch_has_clwb(void)
{
return static_cpu_has(X86_FEATURE_CLWB);
}
#define _mm_clflush(addr)\
asm volatile("clflush %0" : "+m" (*(volatile char *)(addr)))
#define _mm_clflushopt(addr)\
asm volatile(".byte 0x66; clflush %0" : "+m" \
(*(volatile char *)(addr)))
#define _mm_clwb(addr)\
asm volatile(".byte 0x66; xsaveopt %0" : "+m" \
(*(volatile char *)(addr)))
static inline void PERSISTENT_BARRIER(void)
{
asm volatile ("sfence\n" : : );
}
static inline void aeon_flush_buffer(void *buf, uint32_t len, bool fence)
{
uint32_t i;
len = len + ((unsigned long)(buf) & (CACHELINE_SIZE - 1));
if (support_clwb) {
for (i = 0; i < len; i += CACHELINE_SIZE)
_mm_clwb(buf + i);
} else {
for (i = 0; i < len; i += CACHELINE_SIZE)
_mm_clflush(buf + i);
}
/* Do a fence only if asked. We often don't need to do a fence
* immediately after clflush because even if we get context switched
* between clflush and subsequent fence, the context switch operation
* provides implicit fence.
*/
if (fence)
PERSISTENT_BARRIER();
}
static inline void aeon_flush_64bit(void *buf)
{
aeon_flush_buffer(buf, 64, 1);
}
#include "mprotect.h"
/* operations */
extern const struct inode_operations aeon_dir_inode_operations;
extern const struct inode_operations aeon_dir_inode_operations;
extern const struct inode_operations aeon_file_inode_operations;
extern const struct inode_operations aeon_symlink_inode_operations;
extern const struct inode_operations aeon_special_inode_operations;
extern const struct file_operations aeon_dax_file_operations;
extern const struct file_operations aeon_compress_file_operations;
extern const struct file_operations aeon_dir_operations;
extern const struct iomap_ops aeon_iomap_ops;
extern const struct address_space_operations aeon_dax_aops;
/* rebuild.c */
int aeon_rebuild_extenttree(struct super_block *sb,
struct aeon_inode *pi, struct inode *inode);
int aeon_rebuild_dir_inode_tree(struct super_block *sb, struct aeon_inode *pi,
u64 pi_addr, struct inode *inode);
void aeon_rebuild_inode_cache(struct super_block *sb);
/* symlink.c */
int aeon_delete_symblock(struct super_block *sb,
struct aeon_inode_info_header *sih);
int aeon_block_symlink(struct super_block *sb, struct aeon_inode *pi,
const char *symname, int len);
/* ioctl.c */
long aeon_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
long aeon_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
#endif
/* compression file.c */
ssize_t do_dax_decompress_read(struct inode *inode, char __user *buf,
size_t len, loff_t *ppos);
ssize_t aeon_compress_write(struct file *filp, const char __user *buf,
size_t len, loff_t *ppos);
/* debug.c */
int aeon_build_stats(struct aeon_sb_info *sbi);
void aeon_destroy_stats(struct aeon_sb_info *sbi);
int __init aeon_create_root_stats(void);
void aeon_destroy_root_stats(void);
#endif