diff options
-rw-r--r-- | fs/ocfs2/journal.c | 24 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2.h | 1 | ||||
-rw-r--r-- | fs/ocfs2/slot_map.c | 81 | ||||
-rw-r--r-- | fs/ocfs2/slot_map.h | 25 |
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. */ |
1184 | int ocfs2_mark_dead_nodes(struct ocfs2_super *osb) | 1183 | int 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; |
1223 | bail: | 1223 | bail: |
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 | ||
181 | struct ocfs2_journal; | 181 | struct ocfs2_journal; |
182 | struct ocfs2_slot_info; | ||
182 | struct ocfs2_super | 183 | struct 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 | ||
45 | struct 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 | |||
45 | static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, | 54 | static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, |
46 | s16 global); | 55 | s16 global); |
47 | static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, | 56 | static 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 | */ | ||
52 | static void ocfs2_update_slot_info(struct ocfs2_slot_info *si) | 64 | static 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 | ||
68 | int ocfs2_refresh_slot_info(struct ocfs2_super *osb) | 77 | int 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 | ||
122 | static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, s16 preferred) | 134 | static 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 | ||
144 | s16 ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, | 157 | int 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 | |||
172 | int 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 | ||
155 | static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si) | 189 | static 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; |
239 | bail: | 272 | bail: |
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 | ||
30 | struct 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 | |||
40 | int ocfs2_init_slot_info(struct ocfs2_super *osb); | 30 | int ocfs2_init_slot_info(struct ocfs2_super *osb); |
41 | void ocfs2_free_slot_info(struct ocfs2_super *osb); | 31 | void ocfs2_free_slot_info(struct ocfs2_super *osb); |
42 | 32 | ||
@@ -45,17 +35,10 @@ void ocfs2_put_slot(struct ocfs2_super *osb); | |||
45 | 35 | ||
46 | int ocfs2_refresh_slot_info(struct ocfs2_super *osb); | 36 | int ocfs2_refresh_slot_info(struct ocfs2_super *osb); |
47 | 37 | ||
48 | s16 ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, | 38 | int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num); |
49 | s16 global); | 39 | int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num, |
50 | int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num); | 40 | unsigned int *node_num); |
51 | 41 | ||
52 | static inline int ocfs2_is_empty_slot(struct ocfs2_slot_info *si, | 42 | int 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 |