diff options
author | Joel Becker <joel.becker@oracle.com> | 2008-02-01 15:04:48 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-04-18 11:56:03 -0400 |
commit | fc881fa0d59596c02f8707b5572567c369d4789a (patch) | |
tree | 1925db8ac3262ebd343d85ec5e9de799d2e3afd9 /fs/ocfs2/slot_map.c | |
parent | 1c8d9a6a330f46b3a6ddd204a2580131d5f0d6b7 (diff) |
ocfs2: De-magic the in-memory slot map.
The in-memory slot map uses the same magic as the on-disk one. There is
a special value to mark a slot as invalid. It relies on the size of
certain types and so on.
Write a new in-memory map that keeps validity as a separate field. Outside
of the I/O functions, OCFS2_INVALID_SLOT now means what it is supposed to.
It also is no longer tied to the type size.
This also means that only the I/O functions refer to 16bit quantities.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/slot_map.c')
-rw-r--r-- | fs/ocfs2/slot_map.c | 130 |
1 files changed, 72 insertions, 58 deletions
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index 5bddee110091..65a61bfa3f2e 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c | |||
@@ -42,21 +42,41 @@ | |||
42 | 42 | ||
43 | #include "buffer_head_io.h" | 43 | #include "buffer_head_io.h" |
44 | 44 | ||
45 | |||
46 | struct ocfs2_slot { | ||
47 | int sl_valid; | ||
48 | unsigned int sl_node_num; | ||
49 | }; | ||
50 | |||
45 | struct ocfs2_slot_info { | 51 | struct ocfs2_slot_info { |
46 | struct inode *si_inode; | 52 | struct inode *si_inode; |
47 | unsigned int si_blocks; | 53 | unsigned int si_blocks; |
48 | struct buffer_head **si_bh; | 54 | struct buffer_head **si_bh; |
49 | unsigned int si_num_slots; | 55 | unsigned int si_num_slots; |
50 | unsigned int si_size; | 56 | struct ocfs2_slot *si_slots; |
51 | s16 si_global_node_nums[OCFS2_MAX_SLOTS]; | ||
52 | }; | 57 | }; |
53 | 58 | ||
54 | 59 | ||
55 | static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, | 60 | static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, |
56 | s16 global); | 61 | unsigned int node_num); |
57 | static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, | 62 | |
58 | s16 slot_num, | 63 | static void ocfs2_invalidate_slot(struct ocfs2_slot_info *si, |
59 | s16 node_num); | 64 | int slot_num) |
65 | { | ||
66 | BUG_ON((slot_num < 0) || (slot_num >= si->si_num_slots)); | ||
67 | si->si_slots[slot_num].sl_valid = 0; | ||
68 | } | ||
69 | |||
70 | static void ocfs2_set_slot(struct ocfs2_slot_info *si, | ||
71 | int slot_num, unsigned int node_num) | ||
72 | { | ||
73 | BUG_ON((slot_num < 0) || (slot_num >= si->si_num_slots)); | ||
74 | BUG_ON((node_num == O2NM_INVALID_NODE_NUM) || | ||
75 | (node_num >= O2NM_MAX_NODES)); | ||
76 | |||
77 | si->si_slots[slot_num].sl_valid = 1; | ||
78 | si->si_slots[slot_num].sl_node_num = node_num; | ||
79 | } | ||
60 | 80 | ||
61 | /* | 81 | /* |
62 | * Post the slot information on disk into our slot_info struct. | 82 | * Post the slot information on disk into our slot_info struct. |
@@ -71,8 +91,12 @@ static void ocfs2_update_slot_info(struct ocfs2_slot_info *si) | |||
71 | * should've made sure we have the most recent copy. */ | 91 | * should've made sure we have the most recent copy. */ |
72 | disk_info = (__le16 *) si->si_bh[0]->b_data; | 92 | disk_info = (__le16 *) si->si_bh[0]->b_data; |
73 | 93 | ||
74 | for (i = 0; i < si->si_size; i++) | 94 | for (i = 0; i < si->si_num_slots; i++) { |
75 | si->si_global_node_nums[i] = le16_to_cpu(disk_info[i]); | 95 | if (le16_to_cpu(disk_info[i]) == (u16)OCFS2_INVALID_SLOT) |
96 | ocfs2_invalidate_slot(si, i); | ||
97 | else | ||
98 | ocfs2_set_slot(si, i, le16_to_cpu(disk_info[i])); | ||
99 | } | ||
76 | } | 100 | } |
77 | 101 | ||
78 | int ocfs2_refresh_slot_info(struct ocfs2_super *osb) | 102 | int ocfs2_refresh_slot_info(struct ocfs2_super *osb) |
@@ -114,8 +138,13 @@ static int ocfs2_update_disk_slots(struct ocfs2_super *osb, | |||
114 | __le16 *disk_info = (__le16 *) si->si_bh[0]->b_data; | 138 | __le16 *disk_info = (__le16 *) si->si_bh[0]->b_data; |
115 | 139 | ||
116 | spin_lock(&osb->osb_lock); | 140 | spin_lock(&osb->osb_lock); |
117 | for (i = 0; i < si->si_size; i++) | 141 | for (i = 0; i < si->si_num_slots; i++) { |
118 | disk_info[i] = cpu_to_le16(si->si_global_node_nums[i]); | 142 | if (si->si_slots[i].sl_valid) |
143 | disk_info[i] = | ||
144 | cpu_to_le16(si->si_slots[i].sl_node_num); | ||
145 | else | ||
146 | disk_info[i] = cpu_to_le16(OCFS2_INVALID_SLOT); | ||
147 | } | ||
119 | spin_unlock(&osb->osb_lock); | 148 | spin_unlock(&osb->osb_lock); |
120 | 149 | ||
121 | status = ocfs2_write_block(osb, si->si_bh[0], si->si_inode); | 150 | status = ocfs2_write_block(osb, si->si_bh[0], si->si_inode); |
@@ -147,39 +176,39 @@ static int ocfs2_slot_map_physical_size(struct ocfs2_super *osb, | |||
147 | return 0; | 176 | return 0; |
148 | } | 177 | } |
149 | 178 | ||
150 | /* try to find global node in the slot info. Returns | 179 | /* try to find global node in the slot info. Returns -ENOENT |
151 | * OCFS2_INVALID_SLOT if nothing is found. */ | 180 | * if nothing is found. */ |
152 | static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, | 181 | static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, |
153 | s16 global) | 182 | unsigned int node_num) |
154 | { | 183 | { |
155 | int i; | 184 | int i, ret = -ENOENT; |
156 | s16 ret = OCFS2_INVALID_SLOT; | ||
157 | 185 | ||
158 | for(i = 0; i < si->si_num_slots; i++) { | 186 | for(i = 0; i < si->si_num_slots; i++) { |
159 | if (global == si->si_global_node_nums[i]) { | 187 | if (si->si_slots[i].sl_valid && |
160 | ret = (s16) i; | 188 | (node_num == si->si_slots[i].sl_node_num)) { |
189 | ret = i; | ||
161 | break; | 190 | break; |
162 | } | 191 | } |
163 | } | 192 | } |
193 | |||
164 | return ret; | 194 | return ret; |
165 | } | 195 | } |
166 | 196 | ||
167 | static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, | 197 | static int __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, |
168 | s16 preferred) | 198 | int preferred) |
169 | { | 199 | { |
170 | int i; | 200 | int i, ret = -ENOSPC; |
171 | s16 ret = OCFS2_INVALID_SLOT; | ||
172 | 201 | ||
173 | if (preferred >= 0 && preferred < si->si_num_slots) { | 202 | if ((preferred >= 0) && (preferred < si->si_num_slots)) { |
174 | if (OCFS2_INVALID_SLOT == si->si_global_node_nums[preferred]) { | 203 | if (!si->si_slots[preferred].sl_valid) { |
175 | ret = preferred; | 204 | ret = preferred; |
176 | goto out; | 205 | goto out; |
177 | } | 206 | } |
178 | } | 207 | } |
179 | 208 | ||
180 | for(i = 0; i < si->si_num_slots; i++) { | 209 | for(i = 0; i < si->si_num_slots; i++) { |
181 | if (OCFS2_INVALID_SLOT == si->si_global_node_nums[i]) { | 210 | if (!si->si_slots[i].sl_valid) { |
182 | ret = (s16) i; | 211 | ret = i; |
183 | break; | 212 | break; |
184 | } | 213 | } |
185 | } | 214 | } |
@@ -189,16 +218,13 @@ out: | |||
189 | 218 | ||
190 | int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num) | 219 | int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num) |
191 | { | 220 | { |
192 | s16 slot; | 221 | int slot; |
193 | struct ocfs2_slot_info *si = osb->slot_info; | 222 | struct ocfs2_slot_info *si = osb->slot_info; |
194 | 223 | ||
195 | spin_lock(&osb->osb_lock); | 224 | spin_lock(&osb->osb_lock); |
196 | slot = __ocfs2_node_num_to_slot(si, node_num); | 225 | slot = __ocfs2_node_num_to_slot(si, node_num); |
197 | spin_unlock(&osb->osb_lock); | 226 | spin_unlock(&osb->osb_lock); |
198 | 227 | ||
199 | if (slot == OCFS2_INVALID_SLOT) | ||
200 | return -ENOENT; | ||
201 | |||
202 | return slot; | 228 | return slot; |
203 | } | 229 | } |
204 | 230 | ||
@@ -212,10 +238,10 @@ int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num, | |||
212 | BUG_ON(slot_num < 0); | 238 | BUG_ON(slot_num < 0); |
213 | BUG_ON(slot_num > osb->max_slots); | 239 | BUG_ON(slot_num > osb->max_slots); |
214 | 240 | ||
215 | if (si->si_global_node_nums[slot_num] == OCFS2_INVALID_SLOT) | 241 | if (!si->si_slots[slot_num].sl_valid) |
216 | return -ENOENT; | 242 | return -ENOENT; |
217 | 243 | ||
218 | *node_num = si->si_global_node_nums[slot_num]; | 244 | *node_num = si->si_slots[slot_num].sl_node_num; |
219 | return 0; | 245 | return 0; |
220 | } | 246 | } |
221 | 247 | ||
@@ -241,19 +267,7 @@ static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si) | |||
241 | kfree(si); | 267 | kfree(si); |
242 | } | 268 | } |
243 | 269 | ||
244 | static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, | 270 | int ocfs2_clear_slot(struct ocfs2_super *osb, int slot_num) |
245 | s16 slot_num, | ||
246 | s16 node_num) | ||
247 | { | ||
248 | BUG_ON(slot_num == OCFS2_INVALID_SLOT); | ||
249 | BUG_ON(slot_num >= si->si_num_slots); | ||
250 | BUG_ON((node_num != O2NM_INVALID_NODE_NUM) && | ||
251 | (node_num >= O2NM_MAX_NODES)); | ||
252 | |||
253 | si->si_global_node_nums[slot_num] = node_num; | ||
254 | } | ||
255 | |||
256 | int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num) | ||
257 | { | 271 | { |
258 | struct ocfs2_slot_info *si = osb->slot_info; | 272 | struct ocfs2_slot_info *si = osb->slot_info; |
259 | 273 | ||
@@ -261,7 +275,7 @@ int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num) | |||
261 | return 0; | 275 | return 0; |
262 | 276 | ||
263 | spin_lock(&osb->osb_lock); | 277 | spin_lock(&osb->osb_lock); |
264 | __ocfs2_fill_slot(si, slot_num, OCFS2_INVALID_SLOT); | 278 | ocfs2_invalidate_slot(si, slot_num); |
265 | spin_unlock(&osb->osb_lock); | 279 | spin_unlock(&osb->osb_lock); |
266 | 280 | ||
267 | return ocfs2_update_disk_slots(osb, osb->slot_info); | 281 | return ocfs2_update_disk_slots(osb, osb->slot_info); |
@@ -324,11 +338,13 @@ bail: | |||
324 | 338 | ||
325 | int ocfs2_init_slot_info(struct ocfs2_super *osb) | 339 | int ocfs2_init_slot_info(struct ocfs2_super *osb) |
326 | { | 340 | { |
327 | int status, i; | 341 | int status; |
328 | struct inode *inode = NULL; | 342 | struct inode *inode = NULL; |
329 | struct ocfs2_slot_info *si; | 343 | struct ocfs2_slot_info *si; |
330 | 344 | ||
331 | si = kzalloc(sizeof(struct ocfs2_slot_info), GFP_KERNEL); | 345 | si = kzalloc(sizeof(struct ocfs2_slot_info) + |
346 | (sizeof(struct ocfs2_slot) * osb->max_slots), | ||
347 | GFP_KERNEL); | ||
332 | if (!si) { | 348 | if (!si) { |
333 | status = -ENOMEM; | 349 | status = -ENOMEM; |
334 | mlog_errno(status); | 350 | mlog_errno(status); |
@@ -336,10 +352,8 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb) | |||
336 | } | 352 | } |
337 | 353 | ||
338 | si->si_num_slots = osb->max_slots; | 354 | si->si_num_slots = osb->max_slots; |
339 | si->si_size = OCFS2_MAX_SLOTS; | 355 | si->si_slots = (struct ocfs2_slot *)((char *)si + |
340 | 356 | sizeof(struct ocfs2_slot_info)); | |
341 | for(i = 0; i < si->si_num_slots; i++) | ||
342 | si->si_global_node_nums[i] = OCFS2_INVALID_SLOT; | ||
343 | 357 | ||
344 | inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE, | 358 | inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE, |
345 | OCFS2_INVALID_SLOT); | 359 | OCFS2_INVALID_SLOT); |
@@ -375,7 +389,7 @@ void ocfs2_free_slot_info(struct ocfs2_super *osb) | |||
375 | int ocfs2_find_slot(struct ocfs2_super *osb) | 389 | int ocfs2_find_slot(struct ocfs2_super *osb) |
376 | { | 390 | { |
377 | int status; | 391 | int status; |
378 | s16 slot; | 392 | int slot; |
379 | struct ocfs2_slot_info *si; | 393 | struct ocfs2_slot_info *si; |
380 | 394 | ||
381 | mlog_entry_void(); | 395 | mlog_entry_void(); |
@@ -390,11 +404,11 @@ int ocfs2_find_slot(struct ocfs2_super *osb) | |||
390 | * own journal recovery? Possibly not, though we certainly | 404 | * own journal recovery? Possibly not, though we certainly |
391 | * need to warn to the user */ | 405 | * need to warn to the user */ |
392 | slot = __ocfs2_node_num_to_slot(si, osb->node_num); | 406 | slot = __ocfs2_node_num_to_slot(si, osb->node_num); |
393 | if (slot == OCFS2_INVALID_SLOT) { | 407 | if (slot < 0) { |
394 | /* if no slot yet, then just take 1st available | 408 | /* if no slot yet, then just take 1st available |
395 | * one. */ | 409 | * one. */ |
396 | slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); | 410 | slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); |
397 | if (slot == OCFS2_INVALID_SLOT) { | 411 | if (slot < 0) { |
398 | spin_unlock(&osb->osb_lock); | 412 | spin_unlock(&osb->osb_lock); |
399 | mlog(ML_ERROR, "no free slots available!\n"); | 413 | mlog(ML_ERROR, "no free slots available!\n"); |
400 | status = -EINVAL; | 414 | status = -EINVAL; |
@@ -404,7 +418,7 @@ int ocfs2_find_slot(struct ocfs2_super *osb) | |||
404 | mlog(ML_NOTICE, "slot %d is already allocated to this node!\n", | 418 | mlog(ML_NOTICE, "slot %d is already allocated to this node!\n", |
405 | slot); | 419 | slot); |
406 | 420 | ||
407 | __ocfs2_fill_slot(si, slot, osb->node_num); | 421 | ocfs2_set_slot(si, slot, osb->node_num); |
408 | osb->slot_num = slot; | 422 | osb->slot_num = slot; |
409 | spin_unlock(&osb->osb_lock); | 423 | spin_unlock(&osb->osb_lock); |
410 | 424 | ||
@@ -430,7 +444,7 @@ void ocfs2_put_slot(struct ocfs2_super *osb) | |||
430 | spin_lock(&osb->osb_lock); | 444 | spin_lock(&osb->osb_lock); |
431 | ocfs2_update_slot_info(si); | 445 | ocfs2_update_slot_info(si); |
432 | 446 | ||
433 | __ocfs2_fill_slot(si, osb->slot_num, OCFS2_INVALID_SLOT); | 447 | ocfs2_invalidate_slot(si, osb->slot_num); |
434 | osb->slot_num = OCFS2_INVALID_SLOT; | 448 | osb->slot_num = OCFS2_INVALID_SLOT; |
435 | spin_unlock(&osb->osb_lock); | 449 | spin_unlock(&osb->osb_lock); |
436 | 450 | ||