diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 217 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_node.c | 84 |
3 files changed, 128 insertions, 176 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index ae891223be90..7f7769ea2be8 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -152,6 +152,123 @@ xfs_dir2_block_to_leaf( | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | struct xfs_dir2_leaf_entry * | ||
156 | xfs_dir2_leaf_find_entry( | ||
157 | xfs_dir2_leaf_t *leaf, /* leaf structure */ | ||
158 | int index, /* leaf table position */ | ||
159 | int compact, /* need to compact leaves */ | ||
160 | int lowstale, /* index of prev stale leaf */ | ||
161 | int highstale, /* index of next stale leaf */ | ||
162 | int *lfloglow, /* low leaf logging index */ | ||
163 | int *lfloghigh) /* high leaf logging index */ | ||
164 | { | ||
165 | if (!leaf->hdr.stale) { | ||
166 | xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ | ||
167 | |||
168 | /* | ||
169 | * Now we need to make room to insert the leaf entry. | ||
170 | * | ||
171 | * If there are no stale entries, just insert a hole at index. | ||
172 | */ | ||
173 | lep = &leaf->ents[index]; | ||
174 | if (index < be16_to_cpu(leaf->hdr.count)) | ||
175 | memmove(lep + 1, lep, | ||
176 | (be16_to_cpu(leaf->hdr.count) - index) * | ||
177 | sizeof(*lep)); | ||
178 | |||
179 | /* | ||
180 | * Record low and high logging indices for the leaf. | ||
181 | */ | ||
182 | *lfloglow = index; | ||
183 | *lfloghigh = be16_to_cpu(leaf->hdr.count); | ||
184 | be16_add_cpu(&leaf->hdr.count, 1); | ||
185 | return lep; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * There are stale entries. | ||
190 | * | ||
191 | * We will use one of them for the new entry. It's probably not at | ||
192 | * the right location, so we'll have to shift some up or down first. | ||
193 | * | ||
194 | * If we didn't compact before, we need to find the nearest stale | ||
195 | * entries before and after our insertion point. | ||
196 | */ | ||
197 | if (compact == 0) { | ||
198 | /* | ||
199 | * Find the first stale entry before the insertion point, | ||
200 | * if any. | ||
201 | */ | ||
202 | for (lowstale = index - 1; | ||
203 | lowstale >= 0 && | ||
204 | be32_to_cpu(leaf->ents[lowstale].address) != | ||
205 | XFS_DIR2_NULL_DATAPTR; | ||
206 | lowstale--) | ||
207 | continue; | ||
208 | |||
209 | /* | ||
210 | * Find the next stale entry at or after the insertion point, | ||
211 | * if any. Stop if we go so far that the lowstale entry | ||
212 | * would be better. | ||
213 | */ | ||
214 | for (highstale = index; | ||
215 | highstale < be16_to_cpu(leaf->hdr.count) && | ||
216 | be32_to_cpu(leaf->ents[highstale].address) != | ||
217 | XFS_DIR2_NULL_DATAPTR && | ||
218 | (lowstale < 0 || | ||
219 | index - lowstale - 1 >= highstale - index); | ||
220 | highstale++) | ||
221 | continue; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * If the low one is better, use it. | ||
226 | */ | ||
227 | if (lowstale >= 0 && | ||
228 | (highstale == be16_to_cpu(leaf->hdr.count) || | ||
229 | index - lowstale - 1 < highstale - index)) { | ||
230 | ASSERT(index - lowstale - 1 >= 0); | ||
231 | ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == | ||
232 | XFS_DIR2_NULL_DATAPTR); | ||
233 | |||
234 | /* | ||
235 | * Copy entries up to cover the stale entry and make room | ||
236 | * for the new entry. | ||
237 | */ | ||
238 | if (index - lowstale - 1 > 0) { | ||
239 | memmove(&leaf->ents[lowstale], | ||
240 | &leaf->ents[lowstale + 1], | ||
241 | (index - lowstale - 1) * | ||
242 | sizeof(xfs_dir2_leaf_entry_t)); | ||
243 | } | ||
244 | *lfloglow = MIN(lowstale, *lfloglow); | ||
245 | *lfloghigh = MAX(index - 1, *lfloghigh); | ||
246 | be16_add_cpu(&leaf->hdr.stale, -1); | ||
247 | return &leaf->ents[index - 1]; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * The high one is better, so use that one. | ||
252 | */ | ||
253 | ASSERT(highstale - index >= 0); | ||
254 | ASSERT(be32_to_cpu(leaf->ents[highstale].address) == | ||
255 | XFS_DIR2_NULL_DATAPTR); | ||
256 | |||
257 | /* | ||
258 | * Copy entries down to cover the stale entry and make room for the | ||
259 | * new entry. | ||
260 | */ | ||
261 | if (highstale - index > 0) { | ||
262 | memmove(&leaf->ents[index + 1], | ||
263 | &leaf->ents[index], | ||
264 | (highstale - index) * sizeof(xfs_dir2_leaf_entry_t)); | ||
265 | } | ||
266 | *lfloglow = MIN(index, *lfloglow); | ||
267 | *lfloghigh = MAX(highstale, *lfloghigh); | ||
268 | be16_add_cpu(&leaf->hdr.stale, -1); | ||
269 | return &leaf->ents[index]; | ||
270 | } | ||
271 | |||
155 | /* | 272 | /* |
156 | * Add an entry to a leaf form directory. | 273 | * Add an entry to a leaf form directory. |
157 | */ | 274 | */ |
@@ -430,102 +547,10 @@ xfs_dir2_leaf_addname( | |||
430 | if (!grown) | 547 | if (!grown) |
431 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); | 548 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); |
432 | } | 549 | } |
433 | /* | 550 | |
434 | * Now we need to make room to insert the leaf entry. | 551 | lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale, |
435 | * If there are no stale entries, we just insert a hole at index. | 552 | highstale, &lfloglow, &lfloghigh); |
436 | */ | 553 | |
437 | if (!leaf->hdr.stale) { | ||
438 | /* | ||
439 | * lep is still good as the index leaf entry. | ||
440 | */ | ||
441 | if (index < be16_to_cpu(leaf->hdr.count)) | ||
442 | memmove(lep + 1, lep, | ||
443 | (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); | ||
444 | /* | ||
445 | * Record low and high logging indices for the leaf. | ||
446 | */ | ||
447 | lfloglow = index; | ||
448 | lfloghigh = be16_to_cpu(leaf->hdr.count); | ||
449 | be16_add_cpu(&leaf->hdr.count, 1); | ||
450 | } | ||
451 | /* | ||
452 | * There are stale entries. | ||
453 | * We will use one of them for the new entry. | ||
454 | * It's probably not at the right location, so we'll have to | ||
455 | * shift some up or down first. | ||
456 | */ | ||
457 | else { | ||
458 | /* | ||
459 | * If we didn't compact before, we need to find the nearest | ||
460 | * stale entries before and after our insertion point. | ||
461 | */ | ||
462 | if (compact == 0) { | ||
463 | /* | ||
464 | * Find the first stale entry before the insertion | ||
465 | * point, if any. | ||
466 | */ | ||
467 | for (lowstale = index - 1; | ||
468 | lowstale >= 0 && | ||
469 | be32_to_cpu(leaf->ents[lowstale].address) != | ||
470 | XFS_DIR2_NULL_DATAPTR; | ||
471 | lowstale--) | ||
472 | continue; | ||
473 | /* | ||
474 | * Find the next stale entry at or after the insertion | ||
475 | * point, if any. Stop if we go so far that the | ||
476 | * lowstale entry would be better. | ||
477 | */ | ||
478 | for (highstale = index; | ||
479 | highstale < be16_to_cpu(leaf->hdr.count) && | ||
480 | be32_to_cpu(leaf->ents[highstale].address) != | ||
481 | XFS_DIR2_NULL_DATAPTR && | ||
482 | (lowstale < 0 || | ||
483 | index - lowstale - 1 >= highstale - index); | ||
484 | highstale++) | ||
485 | continue; | ||
486 | } | ||
487 | /* | ||
488 | * If the low one is better, use it. | ||
489 | */ | ||
490 | if (lowstale >= 0 && | ||
491 | (highstale == be16_to_cpu(leaf->hdr.count) || | ||
492 | index - lowstale - 1 < highstale - index)) { | ||
493 | ASSERT(index - lowstale - 1 >= 0); | ||
494 | ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == | ||
495 | XFS_DIR2_NULL_DATAPTR); | ||
496 | /* | ||
497 | * Copy entries up to cover the stale entry | ||
498 | * and make room for the new entry. | ||
499 | */ | ||
500 | if (index - lowstale - 1 > 0) | ||
501 | memmove(&leaf->ents[lowstale], | ||
502 | &leaf->ents[lowstale + 1], | ||
503 | (index - lowstale - 1) * sizeof(*lep)); | ||
504 | lep = &leaf->ents[index - 1]; | ||
505 | lfloglow = MIN(lowstale, lfloglow); | ||
506 | lfloghigh = MAX(index - 1, lfloghigh); | ||
507 | } | ||
508 | /* | ||
509 | * The high one is better, so use that one. | ||
510 | */ | ||
511 | else { | ||
512 | ASSERT(highstale - index >= 0); | ||
513 | ASSERT(be32_to_cpu(leaf->ents[highstale].address) == | ||
514 | XFS_DIR2_NULL_DATAPTR); | ||
515 | /* | ||
516 | * Copy entries down to cover the stale entry | ||
517 | * and make room for the new entry. | ||
518 | */ | ||
519 | if (highstale - index > 0) | ||
520 | memmove(&leaf->ents[index + 1], | ||
521 | &leaf->ents[index], | ||
522 | (highstale - index) * sizeof(*lep)); | ||
523 | lep = &leaf->ents[index]; | ||
524 | lfloglow = MIN(index, lfloglow); | ||
525 | lfloghigh = MAX(highstale, lfloghigh); | ||
526 | } | ||
527 | be16_add_cpu(&leaf->hdr.stale, -1); | ||
528 | } | ||
529 | /* | 554 | /* |
530 | * Fill in the new leaf entry. | 555 | * Fill in the new leaf entry. |
531 | */ | 556 | */ |
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h index 6c9539f06987..bc620622c342 100644 --- a/fs/xfs/xfs_dir2_leaf.h +++ b/fs/xfs/xfs_dir2_leaf.h | |||
@@ -248,6 +248,9 @@ extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args, | |||
248 | struct xfs_dabuf *lbp); | 248 | struct xfs_dabuf *lbp); |
249 | extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, | 249 | extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, |
250 | struct xfs_dabuf *lbp, xfs_dir2_db_t db); | 250 | struct xfs_dabuf *lbp, xfs_dir2_db_t db); |
251 | extern xfs_dir2_leaf_entry_t *xfs_dir2_leaf_find_entry(xfs_dir2_leaf_t *, int, | ||
252 | int, int, int, | ||
253 | int *, int *); | ||
251 | extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); | 254 | extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); |
252 | 255 | ||
253 | #endif /* __XFS_DIR2_LEAF_H__ */ | 256 | #endif /* __XFS_DIR2_LEAF_H__ */ |
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index a0aab7d3294f..02da7b7a005a 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c | |||
@@ -244,89 +244,13 @@ xfs_dir2_leafn_add( | |||
244 | lfloglow = be16_to_cpu(leaf->hdr.count); | 244 | lfloglow = be16_to_cpu(leaf->hdr.count); |
245 | lfloghigh = -1; | 245 | lfloghigh = -1; |
246 | } | 246 | } |
247 | /* | 247 | |
248 | * No stale entries, just insert a space for the new entry. | ||
249 | */ | ||
250 | if (!leaf->hdr.stale) { | ||
251 | lep = &leaf->ents[index]; | ||
252 | if (index < be16_to_cpu(leaf->hdr.count)) | ||
253 | memmove(lep + 1, lep, | ||
254 | (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); | ||
255 | lfloglow = index; | ||
256 | lfloghigh = be16_to_cpu(leaf->hdr.count); | ||
257 | be16_add_cpu(&leaf->hdr.count, 1); | ||
258 | } | ||
259 | /* | ||
260 | * There are stale entries. We'll use one for the new entry. | ||
261 | */ | ||
262 | else { | ||
263 | /* | ||
264 | * If we didn't do a compact then we need to figure out | ||
265 | * which stale entry will be used. | ||
266 | */ | ||
267 | if (compact == 0) { | ||
268 | /* | ||
269 | * Find first stale entry before our insertion point. | ||
270 | */ | ||
271 | for (lowstale = index - 1; | ||
272 | lowstale >= 0 && | ||
273 | be32_to_cpu(leaf->ents[lowstale].address) != | ||
274 | XFS_DIR2_NULL_DATAPTR; | ||
275 | lowstale--) | ||
276 | continue; | ||
277 | /* | ||
278 | * Find next stale entry after insertion point. | ||
279 | * Stop looking if the answer would be worse than | ||
280 | * lowstale already found. | ||
281 | */ | ||
282 | for (highstale = index; | ||
283 | highstale < be16_to_cpu(leaf->hdr.count) && | ||
284 | be32_to_cpu(leaf->ents[highstale].address) != | ||
285 | XFS_DIR2_NULL_DATAPTR && | ||
286 | (lowstale < 0 || | ||
287 | index - lowstale - 1 >= highstale - index); | ||
288 | highstale++) | ||
289 | continue; | ||
290 | } | ||
291 | /* | ||
292 | * Using the low stale entry. | ||
293 | * Shift entries up toward the stale slot. | ||
294 | */ | ||
295 | if (lowstale >= 0 && | ||
296 | (highstale == be16_to_cpu(leaf->hdr.count) || | ||
297 | index - lowstale - 1 < highstale - index)) { | ||
298 | ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == | ||
299 | XFS_DIR2_NULL_DATAPTR); | ||
300 | ASSERT(index - lowstale - 1 >= 0); | ||
301 | if (index - lowstale - 1 > 0) | ||
302 | memmove(&leaf->ents[lowstale], | ||
303 | &leaf->ents[lowstale + 1], | ||
304 | (index - lowstale - 1) * sizeof(*lep)); | ||
305 | lep = &leaf->ents[index - 1]; | ||
306 | lfloglow = MIN(lowstale, lfloglow); | ||
307 | lfloghigh = MAX(index - 1, lfloghigh); | ||
308 | } | ||
309 | /* | ||
310 | * Using the high stale entry. | ||
311 | * Shift entries down toward the stale slot. | ||
312 | */ | ||
313 | else { | ||
314 | ASSERT(be32_to_cpu(leaf->ents[highstale].address) == | ||
315 | XFS_DIR2_NULL_DATAPTR); | ||
316 | ASSERT(highstale - index >= 0); | ||
317 | if (highstale - index > 0) | ||
318 | memmove(&leaf->ents[index + 1], | ||
319 | &leaf->ents[index], | ||
320 | (highstale - index) * sizeof(*lep)); | ||
321 | lep = &leaf->ents[index]; | ||
322 | lfloglow = MIN(index, lfloglow); | ||
323 | lfloghigh = MAX(highstale, lfloghigh); | ||
324 | } | ||
325 | be16_add_cpu(&leaf->hdr.stale, -1); | ||
326 | } | ||
327 | /* | 248 | /* |
328 | * Insert the new entry, log everything. | 249 | * Insert the new entry, log everything. |
329 | */ | 250 | */ |
251 | lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale, | ||
252 | highstale, &lfloglow, &lfloghigh); | ||
253 | |||
330 | lep->hashval = cpu_to_be32(args->hashval); | 254 | lep->hashval = cpu_to_be32(args->hashval); |
331 | lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, | 255 | lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, |
332 | args->blkno, args->index)); | 256 | args->blkno, args->index)); |