-
Notifications
You must be signed in to change notification settings - Fork 20
/
amap_smart.h
137 lines (110 loc) · 4.05 KB
/
amap_smart.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
/*
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SDFAT_AMAP_H
#define _SDFAT_AMAP_H
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/rbtree.h>
/* AMAP Configuration Variable */
#define SMART_ALLOC_N_HOT_AU (5)
/* Allocating Destination (for smart allocator):
* moved to sdfat.h
*/
/*
* #define ALLOC_COLD_ALIGNED (1)
* #define ALLOC_COLD_PACKING (2)
* #define ALLOC_COLD_SEQ (4)
*/
/* Minimum sectors for support AMAP create */
#define AMAP_MIN_SUPPORT_SECTORS (1048576)
#define amap_add_hot_au(amap, au) amap_insert_to_list(au, &amap->slist_hot)
/* singly linked list */
struct slist_head {
struct slist_head *next;
struct slist_head *head;
};
/* AU entry type */
typedef struct __AU_INFO_T {
uint16_t idx; /* the index of the AU (0, 1, 2, ... ) */
uint16_t free_clusters; /* # of available cluster */
union {
struct list_head head;
struct slist_head shead;/* singly linked list head for hot list */
};
} AU_INFO_T;
/* Allocation Target AU */
typedef struct __TARGET_AU_T {
AU_INFO_T *au; /* Working AU */
uint16_t idx; /* Intra-AU cluster index */
uint16_t clu_to_skip; /* Clusters to skip */
} TARGET_AU_T;
/* AMAP free-clusters-based node */
typedef struct {
struct list_head head; /* the list of AUs */
} FCLU_NODE_T;
/* AMAP options */
typedef struct {
unsigned int packing_ratio; /* Tunable packing ratio */
unsigned int au_size; /* AU size in sectors */
unsigned int au_align_factor; /* Hidden sectors % au_size */
} AMAP_OPT_T;
typedef struct __AMAP_T {
spinlock_t amap_lock; /* obsolete */
struct super_block *sb;
int n_au;
int n_clean_au, n_full_au;
int clu_align_bias;
uint16_t clusters_per_au;
AU_INFO_T **au_table; /* An array of AU_INFO entries */
AMAP_OPT_T option;
/* Size-based AU management pool (cold) */
FCLU_NODE_T *fclu_nodes; /* An array of listheads */
int fclu_order; /* Page order that fclu_nodes needs */
int fclu_hint; /* maximum # of free clusters in an AU */
/* Hot AU list */
unsigned int total_fclu_hot; /* Free clusters in hot list */
struct slist_head slist_hot; /* Hot AU list */
/* Ignored AU list */
struct slist_head slist_ignored;
/* Allocator variables (keep 2 AUs at maximum) */
TARGET_AU_T cur_cold;
TARGET_AU_T cur_hot;
int n_need_packing;
} AMAP_T;
/* AU table */
#define N_AU_PER_TABLE (int)(PAGE_SIZE / sizeof(AU_INFO_T))
#define GET_AU(amap, i_AU) (amap->au_table[(i_AU) / N_AU_PER_TABLE] + ((i_AU) % N_AU_PER_TABLE))
//#define MAX_CLU_PER_AU (int)(PAGE_SIZE / sizeof(FCLU_NODE_T))
#define MAX_CLU_PER_AU (1024)
/* Cold AU bucket <-> # of freeclusters */
#define NODE_CLEAN(amap) (&amap->fclu_nodes[amap->clusters_per_au - 1])
#define NODE(fclu, amap) (&amap->fclu_nodes[fclu - 1])
#define FREE_CLUSTERS(node, amap) ((int)(node - amap->fclu_nodes) + 1)
/* AU status */
#define MAGIC_WORKING ((struct slist_head *)0xFFFF5091)
#define IS_AU_HOT(au, amap) (au->shead.head == &amap->slist_hot)
#define IS_AU_IGNORED(au, amap) (au->shead.head == &amap->slist_ignored)
#define IS_AU_WORKING(au, amap) (au->shead.head == MAGIC_WORKING)
#define SET_AU_WORKING(au) (au->shead.head = MAGIC_WORKING)
/* AU <-> cluster */
#define i_AU_of_CLU(amap, clu) ((amap->clu_align_bias + clu) / amap->clusters_per_au)
#define CLU_of_i_AU(amap, i_au, idx) \
((uint32_t)(i_au) * (uint32_t)amap->clusters_per_au + (idx) - amap->clu_align_bias)
/*
* NOTE : AMAP internal functions are moved to core.h
*/
#endif /* _SDFAT_AMAP_H */