-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathballoc.h
139 lines (117 loc) · 4.44 KB
/
balloc.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
#ifndef __BALLOC_H
#define __BALLOC_H
#include "inode.h"
/* DRAM structure to hold a list of free PMEM blocks */
struct free_list {
// Used in softirq context
spinlock_t s_lock;
struct rb_root block_free_tree;
struct nova_range_node *first_node; // lowest address free range
struct nova_range_node *last_node; // highest address free range
int index; // Which CPU do I belong to?
/* Where are the data checksum blocks */
unsigned long csum_start;
unsigned long replica_csum_start;
unsigned long num_csum_blocks;
/* Where are the data parity blocks */
unsigned long parity_start;
unsigned long replica_parity_start;
unsigned long num_parity_blocks;
/* Start and end of allocatable range, inclusive. Excludes csum and
* parity blocks.
*/
unsigned long block_start;
unsigned long block_end;
unsigned long num_free_blocks;
/* How many nodes in the rb tree? */
unsigned long num_blocknode;
u32 csum; /* Protect integrity */
/* Statistics */
unsigned long alloc_log_count;
unsigned long alloc_data_count;
unsigned long free_log_count;
unsigned long free_data_count;
unsigned long alloc_log_pages;
unsigned long alloc_data_pages;
unsigned long freed_log_pages;
unsigned long freed_data_pages;
u64 padding[8]; /* Cache line break */
};
static inline
struct free_list *nova_get_free_list(struct super_block *sb, int cpu)
{
struct nova_sb_info *sbi = NOVA_SB(sb);
return &sbi->free_lists[cpu];
}
enum nova_alloc_direction {ALLOC_FROM_HEAD = 0,
ALLOC_FROM_TAIL = 1};
enum nova_alloc_init {ALLOC_NO_INIT = 0,
ALLOC_INIT_ZERO = 1};
enum alloc_type {
LOG = 1,
DATA,
};
/* Range node type */
enum node_type {
NODE_BLOCK = 1,
NODE_INODE,
NODE_DIR,
};
struct block_allocator_per_cpu {
unsigned long blocknr;
unsigned long num;
};
DECLARE_PER_CPU(struct block_allocator_per_cpu, block_allocator_per_cpu);
int nova_alloc_block_free_lists(struct super_block *sb);
void nova_delete_free_lists(struct super_block *sb);
struct nova_range_node *nova_alloc_blocknode(struct super_block *sb);
struct nova_range_node *nova_alloc_inode_node(struct super_block *sb);
struct nova_range_node *nova_alloc_dir_node(struct super_block *sb);
struct vma_item *nova_alloc_vma_item(struct super_block *sb);
void nova_free_range_node(struct nova_range_node *node);
void nova_free_snapshot_info(struct snapshot_info *info);
void nova_free_blocknode(struct nova_range_node *bnode);
void nova_free_inode_node(struct nova_range_node *bnode);
void nova_free_dir_node(struct nova_range_node *bnode);
void nova_free_vma_item(struct super_block *sb,
struct vma_item *item);
extern void nova_init_blockmap(struct super_block *sb, int recovery);
extern int nova_free_data_blocks(struct super_block *sb,
struct nova_inode_info_header *sih, unsigned long blocknr, int num);
int nova_free_data_block(struct super_block *sb,
unsigned long blocknr);
extern int nova_free_log_blocks(struct super_block *sb,
struct nova_inode_info_header *sih, unsigned long blocknr, int num);
int nova_free_log_block(struct super_block *sb,
unsigned long blocknr);
extern int nova_new_data_blocks(struct super_block *sb,
struct nova_inode_info_header *sih, unsigned long *blocknr,
unsigned long start_blk, unsigned int num,
enum nova_alloc_init zero, int cpu,
enum nova_alloc_direction from_tail);
unsigned long nova_new_data_block(struct super_block *sb);
extern int nova_new_log_blocks(struct super_block *sb,
struct nova_inode_info_header *sih,
unsigned long *blocknr, unsigned int num,
enum nova_alloc_init zero, int cpu,
enum nova_alloc_direction from_tail);
unsigned long nova_new_log_block(struct super_block *sb,
enum nova_alloc_init zero, int cpu);
extern unsigned long nova_count_free_blocks(struct super_block *sb);
int nova_search_inodetree(struct nova_sb_info *sbi,
unsigned long ino, struct nova_range_node **ret_node);
int nova_insert_blocktree(struct rb_root *tree,
struct nova_range_node *new_node);
int nova_insert_inodetree(struct nova_sb_info *sbi,
struct nova_range_node *new_node, int cpu);
int nova_find_free_slot(struct rb_root *tree, unsigned long range_low,
unsigned long range_high, struct nova_range_node **prev,
struct nova_range_node **next);
extern int nova_insert_range_node(struct rb_root *tree,
struct nova_range_node *new_node, enum node_type type);
extern int nova_find_range_node(struct rb_root *tree,
unsigned long key, enum node_type type,
struct nova_range_node **ret_node);
extern void nova_destroy_range_node_tree(struct super_block *sb,
struct rb_root *tree);
#endif