Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Joel Becker and committed by
Mark Fasheh
fc881fa0 1c8d9a6a

+77 -63
+1 -1
fs/ocfs2/journal.c
··· 71 71 */ 72 72 73 73 struct ocfs2_recovery_map { 74 - int rm_used; 74 + unsigned int rm_used; 75 75 unsigned int *rm_entries; 76 76 }; 77 77
+3 -3
fs/ocfs2/ocfs2.h
··· 216 216 unsigned long s_mount_opt; 217 217 unsigned int s_atime_quantum; 218 218 219 - u16 max_slots; 219 + unsigned int max_slots; 220 220 s16 node_num; 221 - s16 slot_num; 222 - s16 preferred_slot; 221 + int slot_num; 222 + int preferred_slot; 223 223 int s_sectsize_bits; 224 224 int s_clustersize; 225 225 int s_clustersize_bits;
+72 -58
fs/ocfs2/slot_map.c
··· 42 42 43 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 51 struct ocfs2_slot_info { 46 52 struct inode *si_inode; 47 53 unsigned int si_blocks; 48 54 struct buffer_head **si_bh; 49 55 unsigned int si_num_slots; 50 - unsigned int si_size; 51 - s16 si_global_node_nums[OCFS2_MAX_SLOTS]; 56 + struct ocfs2_slot *si_slots; 52 57 }; 53 58 54 59 55 - static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 56 - s16 global); 57 - static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, 58 - s16 slot_num, 59 - s16 node_num); 60 + static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 61 + unsigned int node_num); 62 + 63 + static void ocfs2_invalidate_slot(struct ocfs2_slot_info *si, 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 82 * Post the slot information on disk into our slot_info struct. ··· 91 71 * should've made sure we have the most recent copy. */ 92 72 disk_info = (__le16 *) si->si_bh[0]->b_data; 93 73 94 - for (i = 0; i < si->si_size; i++) 95 - si->si_global_node_nums[i] = le16_to_cpu(disk_info[i]); 74 + for (i = 0; i < si->si_num_slots; i++) { 75 + if (le16_to_cpu(disk_info[i]) == (u16)OCFS2_INVALID_SLOT) 76 + ocfs2_invalidate_slot(si, i); 77 + else 78 + ocfs2_set_slot(si, i, le16_to_cpu(disk_info[i])); 79 + } 96 80 } 97 81 98 82 int ocfs2_refresh_slot_info(struct ocfs2_super *osb) ··· 138 114 __le16 *disk_info = (__le16 *) si->si_bh[0]->b_data; 139 115 140 116 spin_lock(&osb->osb_lock); 141 - for (i = 0; i < si->si_size; i++) 142 - disk_info[i] = cpu_to_le16(si->si_global_node_nums[i]); 117 + for (i = 0; i < si->si_num_slots; i++) { 118 + if (si->si_slots[i].sl_valid) 119 + disk_info[i] = 120 + cpu_to_le16(si->si_slots[i].sl_node_num); 121 + else 122 + disk_info[i] = cpu_to_le16(OCFS2_INVALID_SLOT); 123 + } 143 124 spin_unlock(&osb->osb_lock); 144 125 145 126 status = ocfs2_write_block(osb, si->si_bh[0], si->si_inode); ··· 176 147 return 0; 177 148 } 178 149 179 - /* try to find global node in the slot info. Returns 180 - * OCFS2_INVALID_SLOT if nothing is found. */ 181 - static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 182 - s16 global) 150 + /* try to find global node in the slot info. Returns -ENOENT 151 + * if nothing is found. */ 152 + static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 153 + unsigned int node_num) 183 154 { 184 - int i; 185 - s16 ret = OCFS2_INVALID_SLOT; 155 + int i, ret = -ENOENT; 186 156 187 157 for(i = 0; i < si->si_num_slots; i++) { 188 - if (global == si->si_global_node_nums[i]) { 189 - ret = (s16) i; 158 + if (si->si_slots[i].sl_valid && 159 + (node_num == si->si_slots[i].sl_node_num)) { 160 + ret = i; 190 161 break; 191 162 } 192 163 } 164 + 193 165 return ret; 194 166 } 195 167 196 - static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, 197 - s16 preferred) 168 + static int __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, 169 + int preferred) 198 170 { 199 - int i; 200 - s16 ret = OCFS2_INVALID_SLOT; 171 + int i, ret = -ENOSPC; 201 172 202 - if (preferred >= 0 && preferred < si->si_num_slots) { 203 - if (OCFS2_INVALID_SLOT == si->si_global_node_nums[preferred]) { 173 + if ((preferred >= 0) && (preferred < si->si_num_slots)) { 174 + if (!si->si_slots[preferred].sl_valid) { 204 175 ret = preferred; 205 176 goto out; 206 177 } 207 178 } 208 179 209 180 for(i = 0; i < si->si_num_slots; i++) { 210 - if (OCFS2_INVALID_SLOT == si->si_global_node_nums[i]) { 211 - ret = (s16) i; 181 + if (!si->si_slots[i].sl_valid) { 182 + ret = i; 212 183 break; 213 184 } 214 185 } ··· 218 189 219 190 int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num) 220 191 { 221 - s16 slot; 192 + int slot; 222 193 struct ocfs2_slot_info *si = osb->slot_info; 223 194 224 195 spin_lock(&osb->osb_lock); 225 196 slot = __ocfs2_node_num_to_slot(si, node_num); 226 197 spin_unlock(&osb->osb_lock); 227 - 228 - if (slot == OCFS2_INVALID_SLOT) 229 - return -ENOENT; 230 198 231 199 return slot; 232 200 } ··· 238 212 BUG_ON(slot_num < 0); 239 213 BUG_ON(slot_num > osb->max_slots); 240 214 241 - if (si->si_global_node_nums[slot_num] == OCFS2_INVALID_SLOT) 215 + if (!si->si_slots[slot_num].sl_valid) 242 216 return -ENOENT; 243 217 244 - *node_num = si->si_global_node_nums[slot_num]; 218 + *node_num = si->si_slots[slot_num].sl_node_num; 245 219 return 0; 246 220 } 247 221 ··· 267 241 kfree(si); 268 242 } 269 243 270 - static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, 271 - s16 slot_num, 272 - s16 node_num) 273 - { 274 - BUG_ON(slot_num == OCFS2_INVALID_SLOT); 275 - BUG_ON(slot_num >= si->si_num_slots); 276 - BUG_ON((node_num != O2NM_INVALID_NODE_NUM) && 277 - (node_num >= O2NM_MAX_NODES)); 278 - 279 - si->si_global_node_nums[slot_num] = node_num; 280 - } 281 - 282 - int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num) 244 + int ocfs2_clear_slot(struct ocfs2_super *osb, int slot_num) 283 245 { 284 246 struct ocfs2_slot_info *si = osb->slot_info; 285 247 ··· 275 261 return 0; 276 262 277 263 spin_lock(&osb->osb_lock); 278 - __ocfs2_fill_slot(si, slot_num, OCFS2_INVALID_SLOT); 264 + ocfs2_invalidate_slot(si, slot_num); 279 265 spin_unlock(&osb->osb_lock); 280 266 281 267 return ocfs2_update_disk_slots(osb, osb->slot_info); ··· 338 324 339 325 int ocfs2_init_slot_info(struct ocfs2_super *osb) 340 326 { 341 - int status, i; 327 + int status; 342 328 struct inode *inode = NULL; 343 329 struct ocfs2_slot_info *si; 344 330 345 - si = kzalloc(sizeof(struct ocfs2_slot_info), GFP_KERNEL); 331 + si = kzalloc(sizeof(struct ocfs2_slot_info) + 332 + (sizeof(struct ocfs2_slot) * osb->max_slots), 333 + GFP_KERNEL); 346 334 if (!si) { 347 335 status = -ENOMEM; 348 336 mlog_errno(status); ··· 352 336 } 353 337 354 338 si->si_num_slots = osb->max_slots; 355 - si->si_size = OCFS2_MAX_SLOTS; 356 - 357 - for(i = 0; i < si->si_num_slots; i++) 358 - si->si_global_node_nums[i] = OCFS2_INVALID_SLOT; 339 + si->si_slots = (struct ocfs2_slot *)((char *)si + 340 + sizeof(struct ocfs2_slot_info)); 359 341 360 342 inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE, 361 343 OCFS2_INVALID_SLOT); ··· 389 375 int ocfs2_find_slot(struct ocfs2_super *osb) 390 376 { 391 377 int status; 392 - s16 slot; 378 + int slot; 393 379 struct ocfs2_slot_info *si; 394 380 395 381 mlog_entry_void(); ··· 404 390 * own journal recovery? Possibly not, though we certainly 405 391 * need to warn to the user */ 406 392 slot = __ocfs2_node_num_to_slot(si, osb->node_num); 407 - if (slot == OCFS2_INVALID_SLOT) { 393 + if (slot < 0) { 408 394 /* if no slot yet, then just take 1st available 409 395 * one. */ 410 396 slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); 411 - if (slot == OCFS2_INVALID_SLOT) { 397 + if (slot < 0) { 412 398 spin_unlock(&osb->osb_lock); 413 399 mlog(ML_ERROR, "no free slots available!\n"); 414 400 status = -EINVAL; ··· 418 404 mlog(ML_NOTICE, "slot %d is already allocated to this node!\n", 419 405 slot); 420 406 421 - __ocfs2_fill_slot(si, slot, osb->node_num); 407 + ocfs2_set_slot(si, slot, osb->node_num); 422 408 osb->slot_num = slot; 423 409 spin_unlock(&osb->osb_lock); 424 410 ··· 444 430 spin_lock(&osb->osb_lock); 445 431 ocfs2_update_slot_info(si); 446 432 447 - __ocfs2_fill_slot(si, osb->slot_num, OCFS2_INVALID_SLOT); 433 + ocfs2_invalidate_slot(si, osb->slot_num); 448 434 osb->slot_num = OCFS2_INVALID_SLOT; 449 435 spin_unlock(&osb->osb_lock); 450 436
+1 -1
fs/ocfs2/slot_map.h
··· 39 39 int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num, 40 40 unsigned int *node_num); 41 41 42 - int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num); 42 + int ocfs2_clear_slot(struct ocfs2_super *osb, int slot_num); 43 43 44 44 #endif