aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/journal.c24
-rw-r--r--fs/ocfs2/ocfs2.h1
-rw-r--r--fs/ocfs2/slot_map.c81
-rw-r--r--fs/ocfs2/slot_map.h25
4 files changed, 74 insertions, 57 deletions
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index c2e654ee703a..ed0c6d0850d7 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -1079,7 +1079,6 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
1079{ 1079{
1080 int status = 0; 1080 int status = 0;
1081 int slot_num; 1081 int slot_num;
1082 struct ocfs2_slot_info *si = osb->slot_info;
1083 struct ocfs2_dinode *la_copy = NULL; 1082 struct ocfs2_dinode *la_copy = NULL;
1084 struct ocfs2_dinode *tl_copy = NULL; 1083 struct ocfs2_dinode *tl_copy = NULL;
1085 1084
@@ -1092,8 +1091,8 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
1092 * case we should've called ocfs2_journal_load instead. */ 1091 * case we should've called ocfs2_journal_load instead. */
1093 BUG_ON(osb->node_num == node_num); 1092 BUG_ON(osb->node_num == node_num);
1094 1093
1095 slot_num = ocfs2_node_num_to_slot(si, node_num); 1094 slot_num = ocfs2_node_num_to_slot(osb, node_num);
1096 if (slot_num == OCFS2_INVALID_SLOT) { 1095 if (slot_num == -ENOENT) {
1097 status = 0; 1096 status = 0;
1098 mlog(0, "no slot for this node, so no recovery required.\n"); 1097 mlog(0, "no slot for this node, so no recovery required.\n");
1099 goto done; 1098 goto done;
@@ -1183,23 +1182,24 @@ bail:
1183 * slot info struct has been updated from disk. */ 1182 * slot info struct has been updated from disk. */
1184int ocfs2_mark_dead_nodes(struct ocfs2_super *osb) 1183int ocfs2_mark_dead_nodes(struct ocfs2_super *osb)
1185{ 1184{
1186 int status, i, node_num; 1185 unsigned int node_num;
1187 struct ocfs2_slot_info *si = osb->slot_info; 1186 int status, i;
1188 1187
1189 /* This is called with the super block cluster lock, so we 1188 /* This is called with the super block cluster lock, so we
1190 * know that the slot map can't change underneath us. */ 1189 * know that the slot map can't change underneath us. */
1191 1190
1192 spin_lock(&si->si_lock); 1191 spin_lock(&osb->osb_lock);
1193 for(i = 0; i < si->si_num_slots; i++) { 1192 for (i = 0; i < osb->max_slots; i++) {
1194 if (i == osb->slot_num) 1193 if (i == osb->slot_num)
1195 continue; 1194 continue;
1196 if (ocfs2_is_empty_slot(si, i)) 1195
1196 status = ocfs2_slot_to_node_num_locked(osb, i, &node_num);
1197 if (status == -ENOENT)
1197 continue; 1198 continue;
1198 1199
1199 node_num = si->si_global_node_nums[i];
1200 if (ocfs2_node_map_test_bit(osb, &osb->recovery_map, node_num)) 1200 if (ocfs2_node_map_test_bit(osb, &osb->recovery_map, node_num))
1201 continue; 1201 continue;
1202 spin_unlock(&si->si_lock); 1202 spin_unlock(&osb->osb_lock);
1203 1203
1204 /* Ok, we have a slot occupied by another node which 1204 /* Ok, we have a slot occupied by another node which
1205 * is not in the recovery map. We trylock his journal 1205 * is not in the recovery map. We trylock his journal
@@ -1215,9 +1215,9 @@ int ocfs2_mark_dead_nodes(struct ocfs2_super *osb)
1215 goto bail; 1215 goto bail;
1216 } 1216 }
1217 1217
1218 spin_lock(&si->si_lock); 1218 spin_lock(&osb->osb_lock);
1219 } 1219 }
1220 spin_unlock(&si->si_lock); 1220 spin_unlock(&osb->osb_lock);
1221 1221
1222 status = 0; 1222 status = 0;
1223bail: 1223bail:
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 6546cef212e3..ee3f675a4210 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -179,6 +179,7 @@ enum ocfs2_mount_options
179#define OCFS2_DEFAULT_ATIME_QUANTUM 60 179#define OCFS2_DEFAULT_ATIME_QUANTUM 60
180 180
181struct ocfs2_journal; 181struct ocfs2_journal;
182struct ocfs2_slot_info;
182struct ocfs2_super 183struct ocfs2_super
183{ 184{
184 struct task_struct *commit_task; 185 struct task_struct *commit_task;
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) {
diff --git a/fs/ocfs2/slot_map.h b/fs/ocfs2/slot_map.h
index b029ffdc8ea5..5118e89c84eb 100644
--- a/fs/ocfs2/slot_map.h
+++ b/fs/ocfs2/slot_map.h
@@ -27,16 +27,6 @@
27#ifndef SLOTMAP_H 27#ifndef SLOTMAP_H
28#define SLOTMAP_H 28#define SLOTMAP_H
29 29
30struct ocfs2_slot_info {
31 spinlock_t si_lock;
32
33 struct inode *si_inode;
34 struct buffer_head *si_bh;
35 unsigned int si_num_slots;
36 unsigned int si_size;
37 s16 si_global_node_nums[OCFS2_MAX_SLOTS];
38};
39
40int ocfs2_init_slot_info(struct ocfs2_super *osb); 30int ocfs2_init_slot_info(struct ocfs2_super *osb);
41void ocfs2_free_slot_info(struct ocfs2_super *osb); 31void ocfs2_free_slot_info(struct ocfs2_super *osb);
42 32
@@ -45,17 +35,10 @@ void ocfs2_put_slot(struct ocfs2_super *osb);
45 35
46int ocfs2_refresh_slot_info(struct ocfs2_super *osb); 36int ocfs2_refresh_slot_info(struct ocfs2_super *osb);
47 37
48s16 ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 38int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num);
49 s16 global); 39int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num,
50int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num); 40 unsigned int *node_num);
51 41
52static inline int ocfs2_is_empty_slot(struct ocfs2_slot_info *si, 42int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num);
53 int slot_num)
54{
55 BUG_ON(slot_num == OCFS2_INVALID_SLOT);
56 assert_spin_locked(&si->si_lock);
57
58 return si->si_global_node_nums[slot_num] == OCFS2_INVALID_SLOT;
59}
60 43
61#endif 44#endif