aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_dir2_leaf.c217
-rw-r--r--fs/xfs/xfs_dir2_leaf.h3
-rw-r--r--fs/xfs/xfs_dir2_node.c84
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
155struct xfs_dir2_leaf_entry *
156xfs_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);
249extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, 249extern 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);
251extern xfs_dir2_leaf_entry_t *xfs_dir2_leaf_find_entry(xfs_dir2_leaf_t *, int,
252 int, int, int,
253 int *, int *);
251extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); 254extern 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));