aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/slot_map.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-02-01 15:04:48 -0500
committerMark Fasheh <mfasheh@suse.com>2008-04-18 11:56:03 -0400
commitfc881fa0d59596c02f8707b5572567c369d4789a (patch)
tree1925db8ac3262ebd343d85ec5e9de799d2e3afd9 /fs/ocfs2/slot_map.c
parent1c8d9a6a330f46b3a6ddd204a2580131d5f0d6b7 (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.c130
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
46struct ocfs2_slot {
47 int sl_valid;
48 unsigned int sl_node_num;
49};
50
45struct ocfs2_slot_info { 51struct 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
55static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 60static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
56 s16 global); 61 unsigned int node_num);
57static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, 62
58 s16 slot_num, 63static 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
70static 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
78int ocfs2_refresh_slot_info(struct ocfs2_super *osb) 102int 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. */
152static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 181static 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
167static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, 197static 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
190int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num) 219int 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
244static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, 270int 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
256int 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
325int ocfs2_init_slot_info(struct ocfs2_super *osb) 339int 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)
375int ocfs2_find_slot(struct ocfs2_super *osb) 389int 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