aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/slot_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/slot_map.c')
-rw-r--r--fs/ocfs2/slot_map.c81
1 files changed, 57 insertions, 24 deletions
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index f5727b8cc913..762360d95e93 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -42,13 +42,25 @@
42 42
43#include "buffer_head_io.h" 43#include "buffer_head_io.h"
44 44
45struct ocfs2_slot_info {
46 struct inode *si_inode;
47 struct buffer_head *si_bh;
48 unsigned int si_num_slots;
49 unsigned int si_size;
50 s16 si_global_node_nums[OCFS2_MAX_SLOTS];
51};
52
53
45static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 54static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
46 s16 global); 55 s16 global);
47static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, 56static void __ocfs2_fill_slot(struct ocfs2_slot_info *si,
48 s16 slot_num, 57 s16 slot_num,
49 s16 node_num); 58 s16 node_num);
50 59
51/* post the slot information on disk into our slot_info struct. */ 60/*
61 * Post the slot information on disk into our slot_info struct.
62 * Must be protected by osb_lock.
63 */
52static void ocfs2_update_slot_info(struct ocfs2_slot_info *si) 64static void ocfs2_update_slot_info(struct ocfs2_slot_info *si)
53{ 65{
54 int i; 66 int i;
@@ -56,13 +68,10 @@ static void ocfs2_update_slot_info(struct ocfs2_slot_info *si)
56 68
57 /* we don't read the slot block here as ocfs2_super_lock 69 /* we don't read the slot block here as ocfs2_super_lock
58 * should've made sure we have the most recent copy. */ 70 * should've made sure we have the most recent copy. */
59 spin_lock(&si->si_lock);
60 disk_info = (__le16 *) si->si_bh->b_data; 71 disk_info = (__le16 *) si->si_bh->b_data;
61 72
62 for (i = 0; i < si->si_size; i++) 73 for (i = 0; i < si->si_size; i++)
63 si->si_global_node_nums[i] = le16_to_cpu(disk_info[i]); 74 si->si_global_node_nums[i] = le16_to_cpu(disk_info[i]);
64
65 spin_unlock(&si->si_lock);
66} 75}
67 76
68int ocfs2_refresh_slot_info(struct ocfs2_super *osb) 77int ocfs2_refresh_slot_info(struct ocfs2_super *osb)
@@ -76,8 +85,11 @@ int ocfs2_refresh_slot_info(struct ocfs2_super *osb)
76 85
77 bh = si->si_bh; 86 bh = si->si_bh;
78 ret = ocfs2_read_block(osb, bh->b_blocknr, &bh, 0, si->si_inode); 87 ret = ocfs2_read_block(osb, bh->b_blocknr, &bh, 0, si->si_inode);
79 if (ret == 0) 88 if (ret == 0) {
89 spin_lock(&osb->osb_lock);
80 ocfs2_update_slot_info(si); 90 ocfs2_update_slot_info(si);
91 spin_unlock(&osb->osb_lock);
92 }
81 93
82 return ret; 94 return ret;
83} 95}
@@ -90,10 +102,10 @@ static int ocfs2_update_disk_slots(struct ocfs2_super *osb,
90 int status, i; 102 int status, i;
91 __le16 *disk_info = (__le16 *) si->si_bh->b_data; 103 __le16 *disk_info = (__le16 *) si->si_bh->b_data;
92 104
93 spin_lock(&si->si_lock); 105 spin_lock(&osb->osb_lock);
94 for (i = 0; i < si->si_size; i++) 106 for (i = 0; i < si->si_size; i++)
95 disk_info[i] = cpu_to_le16(si->si_global_node_nums[i]); 107 disk_info[i] = cpu_to_le16(si->si_global_node_nums[i]);
96 spin_unlock(&si->si_lock); 108 spin_unlock(&osb->osb_lock);
97 109
98 status = ocfs2_write_block(osb, si->si_bh, si->si_inode); 110 status = ocfs2_write_block(osb, si->si_bh, si->si_inode);
99 if (status < 0) 111 if (status < 0)
@@ -119,7 +131,8 @@ static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
119 return ret; 131 return ret;
120} 132}
121 133
122static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, s16 preferred) 134static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si,
135 s16 preferred)
123{ 136{
124 int i; 137 int i;
125 s16 ret = OCFS2_INVALID_SLOT; 138 s16 ret = OCFS2_INVALID_SLOT;
@@ -141,15 +154,36 @@ out:
141 return ret; 154 return ret;
142} 155}
143 156
144s16 ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 157int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num)
145 s16 global)
146{ 158{
147 s16 ret; 159 s16 slot;
160 struct ocfs2_slot_info *si = osb->slot_info;
148 161
149 spin_lock(&si->si_lock); 162 spin_lock(&osb->osb_lock);
150 ret = __ocfs2_node_num_to_slot(si, global); 163 slot = __ocfs2_node_num_to_slot(si, node_num);
151 spin_unlock(&si->si_lock); 164 spin_unlock(&osb->osb_lock);
152 return ret; 165
166 if (slot == OCFS2_INVALID_SLOT)
167 return -ENOENT;
168
169 return slot;
170}
171
172int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num,
173 unsigned int *node_num)
174{
175 struct ocfs2_slot_info *si = osb->slot_info;
176
177 assert_spin_locked(&osb->osb_lock);
178
179 BUG_ON(slot_num < 0);
180 BUG_ON(slot_num > osb->max_slots);
181
182 if (si->si_global_node_nums[slot_num] == OCFS2_INVALID_SLOT)
183 return -ENOENT;
184
185 *node_num = si->si_global_node_nums[slot_num];
186 return 0;
153} 187}
154 188
155static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si) 189static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si)
@@ -184,9 +218,9 @@ int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num)
184 if (si == NULL) 218 if (si == NULL)
185 return 0; 219 return 0;
186 220
187 spin_lock(&si->si_lock); 221 spin_lock(&osb->osb_lock);
188 __ocfs2_fill_slot(si, slot_num, OCFS2_INVALID_SLOT); 222 __ocfs2_fill_slot(si, slot_num, OCFS2_INVALID_SLOT);
189 spin_unlock(&si->si_lock); 223 spin_unlock(&osb->osb_lock);
190 224
191 return ocfs2_update_disk_slots(osb, osb->slot_info); 225 return ocfs2_update_disk_slots(osb, osb->slot_info);
192} 226}
@@ -206,7 +240,6 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb)
206 goto bail; 240 goto bail;
207 } 241 }
208 242
209 spin_lock_init(&si->si_lock);
210 si->si_num_slots = osb->max_slots; 243 si->si_num_slots = osb->max_slots;
211 si->si_size = OCFS2_MAX_SLOTS; 244 si->si_size = OCFS2_MAX_SLOTS;
212 245
@@ -235,7 +268,7 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb)
235 268
236 si->si_inode = inode; 269 si->si_inode = inode;
237 si->si_bh = bh; 270 si->si_bh = bh;
238 osb->slot_info = si; 271 osb->slot_info = (struct ocfs2_slot_info *)si;
239bail: 272bail:
240 if (status < 0 && si) 273 if (status < 0 && si)
241 __ocfs2_free_slot_info(si); 274 __ocfs2_free_slot_info(si);
@@ -261,9 +294,9 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
261 294
262 si = osb->slot_info; 295 si = osb->slot_info;
263 296
297 spin_lock(&osb->osb_lock);
264 ocfs2_update_slot_info(si); 298 ocfs2_update_slot_info(si);
265 299
266 spin_lock(&si->si_lock);
267 /* search for ourselves first and take the slot if it already 300 /* search for ourselves first and take the slot if it already
268 * exists. Perhaps we need to mark this in a variable for our 301 * exists. Perhaps we need to mark this in a variable for our
269 * own journal recovery? Possibly not, though we certainly 302 * own journal recovery? Possibly not, though we certainly
@@ -274,7 +307,7 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
274 * one. */ 307 * one. */
275 slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); 308 slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
276 if (slot == OCFS2_INVALID_SLOT) { 309 if (slot == OCFS2_INVALID_SLOT) {
277 spin_unlock(&si->si_lock); 310 spin_unlock(&osb->osb_lock);
278 mlog(ML_ERROR, "no free slots available!\n"); 311 mlog(ML_ERROR, "no free slots available!\n");
279 status = -EINVAL; 312 status = -EINVAL;
280 goto bail; 313 goto bail;
@@ -285,7 +318,7 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
285 318
286 __ocfs2_fill_slot(si, slot, osb->node_num); 319 __ocfs2_fill_slot(si, slot, osb->node_num);
287 osb->slot_num = slot; 320 osb->slot_num = slot;
288 spin_unlock(&si->si_lock); 321 spin_unlock(&osb->osb_lock);
289 322
290 mlog(0, "taking node slot %d\n", osb->slot_num); 323 mlog(0, "taking node slot %d\n", osb->slot_num);
291 324
@@ -306,12 +339,12 @@ void ocfs2_put_slot(struct ocfs2_super *osb)
306 if (!si) 339 if (!si)
307 return; 340 return;
308 341
342 spin_lock(&osb->osb_lock);
309 ocfs2_update_slot_info(si); 343 ocfs2_update_slot_info(si);
310 344
311 spin_lock(&si->si_lock);
312 __ocfs2_fill_slot(si, osb->slot_num, OCFS2_INVALID_SLOT); 345 __ocfs2_fill_slot(si, osb->slot_num, OCFS2_INVALID_SLOT);
313 osb->slot_num = OCFS2_INVALID_SLOT; 346 osb->slot_num = OCFS2_INVALID_SLOT;
314 spin_unlock(&si->si_lock); 347 spin_unlock(&osb->osb_lock);
315 348
316 status = ocfs2_update_disk_slots(osb, si); 349 status = ocfs2_update_disk_slots(osb, si);
317 if (status < 0) { 350 if (status < 0) {