]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/xfs_dir2_leaf.c
cmd/xfs/bmap/Makefile 1.8 Renamed to cmd/xfsprogs/bmap/Makefile
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_dir2_leaf.c
1 /*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 /*
34 * xfs_dir2_leaf.c
35 * XFS directory version 2 implementation - single leaf form
36 * see xfs_dir2_leaf.h for data structures.
37 * These directories have multiple XFS_DIR2_DATA blocks and one
38 * XFS_DIR2_LEAF1 block containing the hash table and freespace map.
39 */
40
41 #include <xfs.h>
42
43
44 /*
45 * Convert a block form directory to a leaf form directory.
46 */
47 int /* error */
48 xfs_dir2_block_to_leaf(
49 xfs_da_args_t *args, /* operation arguments */
50 xfs_dabuf_t *dbp) /* input block's buffer */
51 {
52 xfs_dir2_data_off_t *bestsp; /* leaf's bestsp entries */
53 xfs_dablk_t blkno; /* leaf block's bno */
54 xfs_dir2_block_t *block; /* block structure */
55 xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */
56 xfs_dir2_block_tail_t *btp; /* block's tail */
57 xfs_inode_t *dp; /* incore directory inode */
58 int error; /* error return code */
59 xfs_dabuf_t *lbp; /* leaf block's buffer */
60 xfs_dir2_db_t ldb; /* leaf block's bno */
61 xfs_dir2_leaf_t *leaf; /* leaf structure */
62 xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */
63 xfs_mount_t *mp; /* filesystem mount point */
64 int needlog; /* need to log block header */
65 int needscan; /* need to rescan bestfree */
66 xfs_trans_t *tp; /* transaction pointer */
67
68 xfs_dir2_trace_args_b("block_to_leaf", args, dbp);
69 dp = args->dp;
70 mp = dp->i_mount;
71 tp = args->trans;
72 /*
73 * Add the leaf block to the inode.
74 * This interface will only put blocks in the leaf/node range.
75 * Since that's empty now, we'll get the root (block 0 in range).
76 */
77 if (error = xfs_da_grow_inode(args, &blkno)) {
78 #pragma mips_frequency_hint NEVER
79 return error;
80 }
81 ldb = XFS_DIR2_DA_TO_DB(mp, blkno);
82 ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp));
83 /*
84 * Initialize the leaf block, get a buffer for it.
85 */
86 if (error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC)) {
87 #pragma mips_frequency_hint NEVER
88 return error;
89 }
90 ASSERT(lbp != NULL);
91 leaf = lbp->data;
92 block = dbp->data;
93 xfs_dir2_data_check(dp, dbp);
94 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
95 blp = XFS_DIR2_BLOCK_LEAF_P_ARCH(btp, ARCH_CONVERT);
96 /*
97 * Set the counts in the leaf header.
98 */
99 INT_COPY(leaf->hdr.count, btp->count, ARCH_CONVERT); /* INT_: type change */
100 INT_COPY(leaf->hdr.stale, btp->stale, ARCH_CONVERT); /* INT_: type change */
101 /*
102 * Could compact these but I think we always do the conversion
103 * after squeezing out stale entries.
104 */
105 bcopy(blp, leaf->ents, INT_GET(btp->count, ARCH_CONVERT) * sizeof(xfs_dir2_leaf_entry_t));
106 xfs_dir2_leaf_log_ents(tp, lbp, 0, INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1);
107 needscan = 0;
108 needlog = 1;
109 /*
110 * Make the space formerly occupied by the leaf entries and block
111 * tail be free.
112 */
113 xfs_dir2_data_make_free(tp, dbp,
114 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
115 (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize -
116 (char *)blp),
117 &needlog, &needscan);
118 /*
119 * Fix up the block header, make it a data block.
120 */
121 INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC);
122 if (needscan)
123 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
124 NULL);
125 /*
126 * Set up leaf tail and bests table.
127 */
128 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
129 INT_SET(ltp->bestcount, ARCH_CONVERT, 1);
130 bestsp = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT);
131 INT_COPY(bestsp[0], block->hdr.bestfree[0].length, ARCH_CONVERT);
132 /*
133 * Log the data header and leaf bests table.
134 */
135 if (needlog)
136 xfs_dir2_data_log_header(tp, dbp);
137 xfs_dir2_leaf_check(dp, lbp);
138 xfs_dir2_data_check(dp, dbp);
139 xfs_dir2_leaf_log_bests(tp, lbp, 0, 0);
140 xfs_da_buf_done(lbp);
141 return 0;
142 }
143
144 /*
145 * Add an entry to a leaf form directory.
146 */
147 int /* error */
148 xfs_dir2_leaf_addname(
149 xfs_da_args_t *args) /* operation arguments */
150 {
151 xfs_dir2_data_off_t *bestsp; /* freespace table in leaf */
152 int compact; /* need to compact leaves */
153 xfs_dir2_data_t *data; /* data block structure */
154 xfs_dabuf_t *dbp; /* data block buffer */
155 xfs_dir2_data_entry_t *dep; /* data block entry */
156 xfs_inode_t *dp; /* incore directory inode */
157 xfs_dir2_data_unused_t *dup; /* data unused entry */
158 int error; /* error return value */
159 int grown; /* allocated new data block */
160 int highstale; /* index of next stale leaf */
161 int i; /* temporary, index */
162 int index; /* leaf table position */
163 xfs_dabuf_t *lbp; /* leaf's buffer */
164 xfs_dir2_leaf_t *leaf; /* leaf structure */
165 int length; /* length of new entry */
166 xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */
167 int lfloglow; /* low leaf logging index */
168 int lfloghigh; /* high leaf logging index */
169 int lowstale; /* index of prev stale leaf */
170 xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
171 xfs_mount_t *mp; /* filesystem mount point */
172 int needbytes; /* leaf block bytes needed */
173 int needlog; /* need to log data header */
174 int needscan; /* need to rescan data free */
175 xfs_dir2_data_off_t *tagp; /* end of data entry */
176 xfs_trans_t *tp; /* transaction pointer */
177 xfs_dir2_db_t use_block; /* data block number */
178
179 xfs_dir2_trace_args("leaf_addname", args);
180 dp = args->dp;
181 tp = args->trans;
182 mp = dp->i_mount;
183 /*
184 * Read the leaf block.
185 */
186 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
187 XFS_DATA_FORK);
188 if (error) {
189 #pragma mips_frequency_hint NEVER
190 return error;
191 }
192 ASSERT(lbp != NULL);
193 /*
194 * Look up the entry by hash value and name.
195 * We know it's not there, our caller has already done a lookup.
196 * So the index is of the entry to insert in front of.
197 * But if there are dup hash values the index is of the first of those.
198 */
199 index = xfs_dir2_leaf_search_hash(args, lbp);
200 leaf = lbp->data;
201 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
202 bestsp = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT);
203 length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
204 /*
205 * See if there are any entries with the same hash value
206 * and space in their block for the new entry.
207 * This is good because it puts multiple same-hash value entries
208 * in a data block, improving the lookup of those entries.
209 */
210 for (use_block = -1, lep = &leaf->ents[index];
211 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
212 index++, lep++) {
213 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
214 continue;
215 i = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
216 ASSERT(i < INT_GET(ltp->bestcount, ARCH_CONVERT));
217 ASSERT(INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF);
218 if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) {
219 use_block = i;
220 break;
221 }
222 }
223 /*
224 * Didn't find a block yet, linear search all the data blocks.
225 */
226 if (use_block == -1) {
227 for (i = 0; i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) {
228 /*
229 * Remember a block we see that's missing.
230 */
231 if (INT_GET(bestsp[i], ARCH_CONVERT) == NULLDATAOFF && use_block == -1)
232 use_block = i;
233 else if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) {
234 use_block = i;
235 break;
236 }
237 }
238 }
239 /*
240 * How many bytes do we need in the leaf block?
241 */
242 needbytes =
243 (INT_GET(leaf->hdr.stale, ARCH_CONVERT) != 0 ? 0 : (uint)sizeof(leaf->ents[0])) +
244 (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0]));
245 /*
246 * Now kill use_block if it refers to a missing block, so we
247 * can use it as an indication of allocation needed.
248 */
249 if (use_block != -1 && INT_GET(bestsp[use_block], ARCH_CONVERT) == NULLDATAOFF)
250 use_block = -1;
251 /*
252 * If we don't have enough free bytes but we can make enough
253 * by compacting out stale entries, we'll do that.
254 */
255 if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] < needbytes &&
256 INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1) {
257 #pragma mips_frequency_hint NEVER
258 compact = 1;
259 }
260 /*
261 * Otherwise if we don't have enough free bytes we need to
262 * convert to node form.
263 */
264 else if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <
265 needbytes) {
266 #pragma mips_frequency_hint NEVER
267 /*
268 * Just checking or no space reservation, give up.
269 */
270 if (args->justcheck || args->total == 0) {
271 xfs_da_brelse(tp, lbp);
272 return XFS_ERROR(ENOSPC);
273 }
274 /*
275 * Convert to node form.
276 */
277 error = xfs_dir2_leaf_to_node(args, lbp);
278 xfs_da_buf_done(lbp);
279 if (error)
280 return error;
281 /*
282 * Then add the new entry.
283 */
284 return xfs_dir2_node_addname(args);
285 }
286 /*
287 * Otherwise it will fit without compaction.
288 */
289 else
290 compact = 0;
291 /*
292 * If just checking, then it will fit unless we needed to allocate
293 * a new data block.
294 */
295 if (args->justcheck) {
296 xfs_da_brelse(tp, lbp);
297 return use_block == -1 ? XFS_ERROR(ENOSPC) : 0;
298 }
299 /*
300 * If no allocations are allowed, return now before we've
301 * changed anything.
302 */
303 if (args->total == 0 && use_block == -1) {
304 #pragma mips_frequency_hint NEVER
305 xfs_da_brelse(tp, lbp);
306 return XFS_ERROR(ENOSPC);
307 }
308 /*
309 * Need to compact the leaf entries, removing stale ones.
310 * Leave one stale entry behind - the one closest to our
311 * insertion index - and we'll shift that one to our insertion
312 * point later.
313 */
314 if (compact) {
315 #pragma mips_frequency_hint NEVER
316 xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale,
317 &lfloglow, &lfloghigh);
318 }
319 /*
320 * There are stale entries, so we'll need log-low and log-high
321 * impossibly bad values later.
322 */
323 else if (INT_GET(leaf->hdr.stale, ARCH_CONVERT)) {
324 lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT);
325 lfloghigh = -1;
326 }
327 /*
328 * If there was no data block space found, we need to allocate
329 * a new one.
330 */
331 if (use_block == -1) {
332 #pragma mips_frequency_hint NEVER
333 /*
334 * Add the new data block.
335 */
336 if (error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE,
337 &use_block)) {
338 xfs_da_brelse(tp, lbp);
339 return error;
340 }
341 /*
342 * Initialize the block.
343 */
344 if (error = xfs_dir2_data_init(args, use_block, &dbp)) {
345 xfs_da_brelse(tp, lbp);
346 return error;
347 }
348 /*
349 * If we're adding a new data block on the end we need to
350 * extend the bests table. Copy it up one entry.
351 */
352 if (use_block >= INT_GET(ltp->bestcount, ARCH_CONVERT)) {
353 bestsp--;
354 ovbcopy(&bestsp[1], &bestsp[0],
355 INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(bestsp[0]));
356 INT_MOD(ltp->bestcount, ARCH_CONVERT, +1);
357 xfs_dir2_leaf_log_tail(tp, lbp);
358 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
359 }
360 /*
361 * If we're filling in a previously empty block just log it.
362 */
363 else
364 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
365 data = dbp->data;
366 INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT);
367 grown = 1;
368 }
369 /*
370 * Already had space in some data block.
371 * Just read that one in.
372 */
373 else {
374 if (error =
375 xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, use_block),
376 -1, &dbp, XFS_DATA_FORK)) {
377 #pragma mips_frequency_hint NEVER
378 xfs_da_brelse(tp, lbp);
379 return error;
380 }
381 data = dbp->data;
382 grown = 0;
383 }
384 xfs_dir2_data_check(dp, dbp);
385 /*
386 * Point to the biggest freespace in our data block.
387 */
388 dup = (xfs_dir2_data_unused_t *)
389 ((char *)data + INT_GET(data->hdr.bestfree[0].offset, ARCH_CONVERT));
390 ASSERT(INT_GET(dup->length, ARCH_CONVERT) >= length);
391 needscan = needlog = 0;
392 /*
393 * Mark the initial part of our freespace in use for the new entry.
394 */
395 xfs_dir2_data_use_free(tp, dbp, dup,
396 (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length,
397 &needlog, &needscan);
398 /*
399 * Initialize our new entry (at last).
400 */
401 dep = (xfs_dir2_data_entry_t *)dup;
402 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
403 dep->namelen = args->namelen;
404 bcopy(args->name, dep->name, dep->namelen);
405 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
406 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data));
407 /*
408 * Need to scan fix up the bestfree table.
409 */
410 if (needscan)
411 xfs_dir2_data_freescan(mp, data, &needlog, NULL);
412 /*
413 * Need to log the data block's header.
414 */
415 if (needlog)
416 xfs_dir2_data_log_header(tp, dbp);
417 xfs_dir2_data_log_entry(tp, dbp, dep);
418 /*
419 * If the bests table needs to be changed, do it.
420 * Log the change unless we've already done that.
421 */
422 if (INT_GET(bestsp[use_block], ARCH_CONVERT) != INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) {
423 INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT);
424 if (!grown)
425 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
426 }
427 /*
428 * Now we need to make room to insert the leaf entry.
429 * If there are no stale entries, we just insert a hole at index.
430 */
431 if (INT_GET(leaf->hdr.stale, ARCH_CONVERT) == 0) {
432 /*
433 * lep is still good as the index leaf entry.
434 */
435 if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT))
436 ovbcopy(lep, lep + 1,
437 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep));
438 /*
439 * Record low and high logging indices for the leaf.
440 */
441 lfloglow = index;
442 lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT);
443 INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1);
444 }
445 /*
446 * There are stale entries.
447 * We will use one of them for the new entry.
448 * It's probably not at the right location, so we'll have to
449 * shift some up or down first.
450 */
451 else {
452 /*
453 * If we didn't compact before, we need to find the nearest
454 * stale entries before and after our insertion point.
455 */
456 if (compact == 0) {
457 /*
458 * Find the first stale entry before the insertion
459 * point, if any.
460 */
461 for (lowstale = index - 1;
462 lowstale >= 0 &&
463 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) !=
464 XFS_DIR2_NULL_DATAPTR;
465 lowstale--)
466 continue;
467 /*
468 * Find the next stale entry at or after the insertion
469 * point, if any. Stop if we go so far that the
470 * lowstale entry would be better.
471 */
472 for (highstale = index;
473 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
474 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) !=
475 XFS_DIR2_NULL_DATAPTR &&
476 (lowstale < 0 ||
477 index - lowstale - 1 >= highstale - index);
478 highstale++)
479 continue;
480 }
481 /*
482 * If the low one is better, use it.
483 */
484 if (lowstale >= 0 &&
485 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
486 index - lowstale - 1 < highstale - index)) {
487 ASSERT(index - lowstale - 1 >= 0);
488 ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) ==
489 XFS_DIR2_NULL_DATAPTR);
490 /*
491 * Copy entries up to cover the stale entry
492 * and make room for the new entry.
493 */
494 if (index - lowstale - 1 > 0)
495 ovbcopy(&leaf->ents[lowstale + 1],
496 &leaf->ents[lowstale],
497 (index - lowstale - 1) * sizeof(*lep));
498 lep = &leaf->ents[index - 1];
499 lfloglow = MIN(lowstale, lfloglow);
500 lfloghigh = MAX(index - 1, lfloghigh);
501 }
502 /*
503 * The high one is better, so use that one.
504 */
505 else {
506 ASSERT(highstale - index >= 0);
507 ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) ==
508 XFS_DIR2_NULL_DATAPTR);
509 /*
510 * Copy entries down to copver the stale entry
511 * and make room for the new entry.
512 */
513 if (highstale - index > 0)
514 ovbcopy(&leaf->ents[index],
515 &leaf->ents[index + 1],
516 (highstale - index) * sizeof(*lep));
517 lep = &leaf->ents[index];
518 lfloglow = MIN(index, lfloglow);
519 lfloghigh = MAX(highstale, lfloghigh);
520 }
521 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1);
522 }
523 /*
524 * Fill in the new leaf entry.
525 */
526 INT_SET(lep->hashval, ARCH_CONVERT, args->hashval);
527 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block, INT_GET(*tagp, ARCH_CONVERT)));
528 /*
529 * Log the leaf fields and give up the buffers.
530 */
531 xfs_dir2_leaf_log_header(tp, lbp);
532 xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh);
533 xfs_dir2_leaf_check(dp, lbp);
534 xfs_da_buf_done(lbp);
535 xfs_dir2_data_check(dp, dbp);
536 xfs_da_buf_done(dbp);
537 return 0;
538 }
539
540
541 #ifdef DEBUG
542 /*
543 * Check the internal consistency of a leaf1 block.
544 * Pop an assert if something is wrong.
545 */
546 void
547 xfs_dir2_leaf_check(
548 xfs_inode_t *dp, /* incore directory inode */
549 xfs_dabuf_t *bp) /* leaf's buffer */
550 {
551 int i; /* leaf index */
552 xfs_dir2_leaf_t *leaf; /* leaf structure */
553 xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
554 xfs_mount_t *mp; /* filesystem mount point */
555 int stale; /* count of stale leaves */
556
557 leaf = bp->data;
558 mp = dp->i_mount;
559 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
560 /*
561 * This value is not restrictive enough.
562 * Should factor in the size of the bests table as well.
563 * We can deduce a value for that from di_size.
564 */
565 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
566 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
567 /*
568 * Leaves and bests don't overlap.
569 */
570 ASSERT((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <=
571 (char *)XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT));
572 /*
573 * Check hash value order, count stale entries.
574 */
575 for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) {
576 if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT))
577 ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <=
578 INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT));
579 if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
580 stale++;
581 }
582 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale);
583 }
584 #endif /* DEBUG */
585
586 /*
587 * Compact out any stale entries in the leaf.
588 * Log the header and changed leaf entries, if any.
589 */
590 void
591 xfs_dir2_leaf_compact(
592 xfs_da_args_t *args, /* operation arguments */
593 xfs_dabuf_t *bp) /* leaf buffer */
594 {
595 int from; /* source leaf index */
596 xfs_dir2_leaf_t *leaf; /* leaf structure */
597 int loglow; /* first leaf entry to log */
598 int to; /* target leaf index */
599
600 leaf = bp->data;
601 if (INT_GET(leaf->hdr.stale, ARCH_CONVERT) == 0) {
602 #pragma mips_frequency_hint NEVER
603 return;
604 }
605 /*
606 * Compress out the stale entries in place.
607 */
608 for (from = to = 0, loglow = -1; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
609 if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
610 continue;
611 /*
612 * Only actually copy the entries that are different.
613 */
614 if (from > to) {
615 if (loglow == -1)
616 loglow = to;
617 leaf->ents[to] = leaf->ents[from];
618 }
619 to++;
620 }
621 /*
622 * Update and log the header, log the leaf entries.
623 */
624 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == from - to);
625 INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(INT_GET(leaf->hdr.stale, ARCH_CONVERT)));
626 INT_SET(leaf->hdr.stale, ARCH_CONVERT, 0);
627 xfs_dir2_leaf_log_header(args->trans, bp);
628 if (loglow != -1)
629 xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1);
630 }
631
632 /*
633 * Compact the leaf entries, removing stale ones.
634 * Leave one stale entry behind - the one closest to our
635 * insertion index - and the caller will shift that one to our insertion
636 * point later.
637 * Return new insertion index, where the remaining stale entry is,
638 * and leaf logging indices.
639 */
640 void
641 xfs_dir2_leaf_compact_x1(
642 xfs_dabuf_t *bp, /* leaf buffer */
643 int *indexp, /* insertion index */
644 int *lowstalep, /* out: stale entry before us */
645 int *highstalep, /* out: stale entry after us */
646 int *lowlogp, /* out: low log index */
647 int *highlogp) /* out: high log index */
648 {
649 int from; /* source copy index */
650 int highstale; /* stale entry at/after index */
651 int index; /* insertion index */
652 int keepstale; /* source index of kept stale */
653 xfs_dir2_leaf_t *leaf; /* leaf structure */
654 int lowstale; /* stale entry before index */
655 int newindex; /* new insertion index */
656 int to; /* destination copy index */
657
658 leaf = bp->data;
659 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1);
660 index = *indexp;
661 /*
662 * Find the first stale entry before our index, if any.
663 */
664 for (lowstale = index - 1;
665 lowstale >= 0 &&
666 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR;
667 lowstale--)
668 continue;
669 /*
670 * Find the first stale entry at or after our index, if any.
671 * Stop if the answer would be worse than lowstale.
672 */
673 for (highstale = index;
674 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
675 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR &&
676 (lowstale < 0 || index - lowstale > highstale - index);
677 highstale++)
678 continue;
679 /*
680 * Pick the better of lowstale and highstale.
681 */
682 if (lowstale >= 0 &&
683 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
684 index - lowstale <= highstale - index))
685 keepstale = lowstale;
686 else
687 keepstale = highstale;
688 /*
689 * Copy the entries in place, removing all the stale entries
690 * except keepstale.
691 */
692 for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
693 /*
694 * Notice the new value of index.
695 */
696 if (index == from)
697 newindex = to;
698 if (from != keepstale &&
699 INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) {
700 if (from == to)
701 *lowlogp = to;
702 continue;
703 }
704 /*
705 * Record the new keepstale value for the insertion.
706 */
707 if (from == keepstale)
708 lowstale = highstale = to;
709 /*
710 * Copy only the entries that have moved.
711 */
712 if (from > to)
713 leaf->ents[to] = leaf->ents[from];
714 to++;
715 }
716 ASSERT(from > to);
717 /*
718 * If the insertion point was past the last entry,
719 * set the new insertion point accordingly.
720 */
721 if (index == from)
722 newindex = to;
723 *indexp = newindex;
724 /*
725 * Adjust the leaf header values.
726 */
727 INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(from - to));
728 INT_SET(leaf->hdr.stale, ARCH_CONVERT, 1);
729 /*
730 * Remember the low/high stale value only in the "right"
731 * direction.
732 */
733 if (lowstale >= newindex)
734 lowstale = -1;
735 else
736 highstale = INT_GET(leaf->hdr.count, ARCH_CONVERT);
737 *highlogp = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;
738 *lowstalep = lowstale;
739 *highstalep = highstale;
740 }
741
742 /*
743 * Initialize a new leaf block, leaf1 or leafn magic accepted.
744 */
745 int
746 xfs_dir2_leaf_init(
747 xfs_da_args_t *args, /* operation arguments */
748 xfs_dir2_db_t bno, /* directory block number */
749 xfs_dabuf_t **bpp, /* out: leaf buffer */
750 int magic) /* magic number for block */
751 {
752 xfs_dabuf_t *bp; /* leaf buffer */
753 xfs_inode_t *dp; /* incore directory inode */
754 int error; /* error return code */
755 xfs_dir2_leaf_t *leaf; /* leaf structure */
756 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
757 xfs_mount_t *mp; /* filesystem mount point */
758 xfs_trans_t *tp; /* transaction pointer */
759
760 dp = args->dp;
761 ASSERT(dp != NULL);
762 tp = args->trans;
763 mp = dp->i_mount;
764 ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) &&
765 bno < XFS_DIR2_FREE_FIRSTDB(mp));
766 /*
767 * Get the buffer for the block.
768 */
769 error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, bno), -1, &bp,
770 XFS_DATA_FORK);
771 if (error) {
772 #pragma mips_frequency_hint NEVER
773 return error;
774 }
775 ASSERT(bp != NULL);
776 leaf = bp->data;
777 /*
778 * Initialize the header.
779 */
780 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, magic);
781 INT_ZERO(leaf->hdr.info.forw, ARCH_CONVERT);
782 INT_ZERO(leaf->hdr.info.back, ARCH_CONVERT);
783 INT_ZERO(leaf->hdr.count, ARCH_CONVERT);
784 INT_ZERO(leaf->hdr.stale, ARCH_CONVERT);
785 xfs_dir2_leaf_log_header(tp, bp);
786 /*
787 * If it's a leaf-format directory initialize the tail.
788 * In this case our caller has the real bests table to copy into
789 * the block.
790 */
791 if (magic == XFS_DIR2_LEAF1_MAGIC) {
792 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
793 INT_SET(ltp->bestcount, ARCH_CONVERT, 0);
794 xfs_dir2_leaf_log_tail(tp, bp);
795 }
796 *bpp = bp;
797 return 0;
798 }
799
800 /*
801 * Log the bests entries indicated from a leaf1 block.
802 */
803 void
804 xfs_dir2_leaf_log_bests(
805 xfs_trans_t *tp, /* transaction pointer */
806 xfs_dabuf_t *bp, /* leaf buffer */
807 int first, /* first entry to log */
808 int last) /* last entry to log */
809 {
810 xfs_dir2_data_off_t *firstb; /* pointer to first entry */
811 xfs_dir2_data_off_t *lastb; /* pointer to last entry */
812 xfs_dir2_leaf_t *leaf; /* leaf structure */
813 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
814
815 leaf = bp->data;
816 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
817 ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf);
818 firstb = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT) + first;
819 lastb = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT) + last;
820 xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf),
821 (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
822 }
823
824 /*
825 * Log the leaf entries indicated from a leaf1 or leafn block.
826 */
827 void
828 xfs_dir2_leaf_log_ents(
829 xfs_trans_t *tp, /* transaction pointer */
830 xfs_dabuf_t *bp, /* leaf buffer */
831 int first, /* first entry to log */
832 int last) /* last entry to log */
833 {
834 xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */
835 xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */
836 xfs_dir2_leaf_t *leaf; /* leaf structure */
837
838 leaf = bp->data;
839 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC ||
840 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
841 firstlep = &leaf->ents[first];
842 lastlep = &leaf->ents[last];
843 xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
844 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
845 }
846
847 /*
848 * Log the header of the leaf1 or leafn block.
849 */
850 void
851 xfs_dir2_leaf_log_header(
852 xfs_trans_t *tp, /* transaction pointer */
853 xfs_dabuf_t *bp) /* leaf buffer */
854 {
855 xfs_dir2_leaf_t *leaf; /* leaf structure */
856
857 leaf = bp->data;
858 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC ||
859 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
860 xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
861 (uint)(sizeof(leaf->hdr) - 1));
862 }
863
864 /*
865 * Log the tail of the leaf1 block.
866 */
867 void
868 xfs_dir2_leaf_log_tail(
869 xfs_trans_t *tp, /* transaction pointer */
870 xfs_dabuf_t *bp) /* leaf buffer */
871 {
872 xfs_dir2_leaf_t *leaf; /* leaf structure */
873 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
874 xfs_mount_t *mp; /* filesystem mount point */
875
876 mp = tp->t_mountp;
877 leaf = bp->data;
878 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
879 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
880 xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
881 (uint)(mp->m_dirblksize - 1));
882 }
883
884 /*
885 * Look up the entry referred to by args in the leaf format directory.
886 * Most of the work is done by the xfs_dir2_leaf_lookup_int routine which
887 * is also used by the node-format code.
888 */
889 int
890 xfs_dir2_leaf_lookup(
891 xfs_da_args_t *args) /* operation arguments */
892 {
893 xfs_dabuf_t *dbp; /* data block buffer */
894 xfs_dir2_data_entry_t *dep; /* data block entry */
895 xfs_inode_t *dp; /* incore directory inode */
896 int error; /* error return code */
897 int index; /* found entry index */
898 xfs_dabuf_t *lbp; /* leaf buffer */
899 xfs_dir2_leaf_t *leaf; /* leaf structure */
900 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
901 xfs_trans_t *tp; /* transaction pointer */
902
903 xfs_dir2_trace_args("leaf_lookup", args);
904 /*
905 * Look up name in the leaf block, returning both buffers and index.
906 */
907 if (error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp)) {
908 #pragma mips_frequency_hint NEVER
909 return error;
910 }
911 tp = args->trans;
912 dp = args->dp;
913 xfs_dir2_leaf_check(dp, lbp);
914 leaf = lbp->data;
915 /*
916 * Get to the leaf entry and contained data entry address.
917 */
918 lep = &leaf->ents[index];
919 /*
920 * Point to the data entry.
921 */
922 dep = (xfs_dir2_data_entry_t *)
923 ((char *)dbp->data +
924 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT)));
925 /*
926 * Return the found inode number.
927 */
928 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
929 xfs_da_brelse(tp, dbp);
930 xfs_da_brelse(tp, lbp);
931 return XFS_ERROR(EEXIST);
932 }
933
934 /*
935 * Look up name/hash in the leaf block.
936 * Fill in indexp with the found index, and dbpp with the data buffer.
937 * If not found dbpp will be NULL, and ENOENT comes back.
938 * lbpp will always be filled in with the leaf buffer unless there's an error.
939 */
940 STATIC int /* error */
941 xfs_dir2_leaf_lookup_int(
942 xfs_da_args_t *args, /* operation arguments */
943 xfs_dabuf_t **lbpp, /* out: leaf buffer */
944 int *indexp, /* out: index in leaf block */
945 xfs_dabuf_t **dbpp) /* out: data buffer */
946 {
947 xfs_dir2_db_t curdb; /* current data block number */
948 xfs_dabuf_t *dbp; /* data buffer */
949 xfs_dir2_data_entry_t *dep; /* data entry */
950 xfs_inode_t *dp; /* incore directory inode */
951 int error; /* error return code */
952 int index; /* index in leaf block */
953 xfs_dabuf_t *lbp; /* leaf buffer */
954 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
955 xfs_dir2_leaf_t *leaf; /* leaf structure */
956 xfs_mount_t *mp; /* filesystem mount point */
957 xfs_dir2_db_t newdb; /* new data block number */
958 xfs_trans_t *tp; /* transaction pointer */
959
960 dp = args->dp;
961 tp = args->trans;
962 mp = dp->i_mount;
963 /*
964 * Read the leaf block into the buffer.
965 */
966 if (error =
967 xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
968 XFS_DATA_FORK)) {
969 #pragma mips_frequency_hint NEVER
970 return error;
971 }
972 *lbpp = lbp;
973 leaf = lbp->data;
974 xfs_dir2_leaf_check(dp, lbp);
975 /*
976 * Look for the first leaf entry with our hash value.
977 */
978 index = xfs_dir2_leaf_search_hash(args, lbp);
979 /*
980 * Loop over all the entries with the right hash value
981 * looking to match the name.
982 */
983 for (lep = &leaf->ents[index], dbp = NULL, curdb = -1;
984 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
985 lep++, index++) {
986 /*
987 * Skip over stale leaf entries.
988 */
989 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
990 continue;
991 /*
992 * Get the new data block number.
993 */
994 newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
995 /*
996 * If it's not the same as the old data block number,
997 * need to pitch the old one and read the new one.
998 */
999 if (newdb != curdb) {
1000 if (dbp)
1001 xfs_da_brelse(tp, dbp);
1002 if (error =
1003 xfs_da_read_buf(tp, dp,
1004 XFS_DIR2_DB_TO_DA(mp, newdb), -1, &dbp,
1005 XFS_DATA_FORK)) {
1006 #pragma mips_frequency_hint NEVER
1007 xfs_da_brelse(tp, lbp);
1008 return error;
1009 }
1010 xfs_dir2_data_check(dp, dbp);
1011 curdb = newdb;
1012 }
1013 /*
1014 * Point to the data entry.
1015 */
1016 dep = (xfs_dir2_data_entry_t *)
1017 ((char *)dbp->data +
1018 XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
1019 /*
1020 * If it matches then return it.
1021 */
1022 if (dep->namelen == args->namelen &&
1023 dep->name[0] == args->name[0] &&
1024 bcmp(dep->name, args->name, args->namelen) == 0) {
1025 *dbpp = dbp;
1026 *indexp = index;
1027 return 0;
1028 }
1029 }
1030 /*
1031 * No match found, return ENOENT.
1032 */
1033 ASSERT(args->oknoent);
1034 if (dbp)
1035 xfs_da_brelse(tp, dbp);
1036 xfs_da_brelse(tp, lbp);
1037 return XFS_ERROR(ENOENT);
1038 }
1039
1040 /*
1041 * Remove an entry from a leaf format directory.
1042 */
1043 int /* error */
1044 xfs_dir2_leaf_removename(
1045 xfs_da_args_t *args) /* operation arguments */
1046 {
1047 xfs_dir2_data_off_t *bestsp; /* leaf block best freespace */
1048 xfs_dir2_data_t *data; /* data block structure */
1049 xfs_dir2_db_t db; /* data block number */
1050 xfs_dabuf_t *dbp; /* data block buffer */
1051 xfs_dir2_data_entry_t *dep; /* data entry structure */
1052 xfs_inode_t *dp; /* incore directory inode */
1053 int error; /* error return code */
1054 xfs_dir2_db_t i; /* temporary data block # */
1055 int index; /* index into leaf entries */
1056 xfs_dabuf_t *lbp; /* leaf buffer */
1057 xfs_dir2_leaf_t *leaf; /* leaf structure */
1058 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1059 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1060 xfs_mount_t *mp; /* filesystem mount point */
1061 int needlog; /* need to log data header */
1062 int needscan; /* need to rescan data frees */
1063 xfs_dir2_data_off_t oldbest; /* old value of best free */
1064 xfs_trans_t *tp; /* transaction pointer */
1065
1066 xfs_dir2_trace_args("leaf_removename", args);
1067 /*
1068 * Lookup the leaf entry, get the leaf and data blocks read in.
1069 */
1070 if (error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp)) {
1071 #pragma mips_frequency_hint NEVER
1072 return error;
1073 }
1074 dp = args->dp;
1075 tp = args->trans;
1076 mp = dp->i_mount;
1077 leaf = lbp->data;
1078 data = dbp->data;
1079 xfs_dir2_data_check(dp, dbp);
1080 /*
1081 * Point to the leaf entry, use that to point to the data entry.
1082 */
1083 lep = &leaf->ents[index];
1084 db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
1085 dep = (xfs_dir2_data_entry_t *)
1086 ((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
1087 needscan = needlog = 0;
1088 oldbest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT);
1089 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1090 bestsp = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT);
1091 ASSERT(INT_GET(bestsp[db], ARCH_CONVERT) == oldbest);
1092 /*
1093 * Mark the former data entry unused.
1094 */
1095 xfs_dir2_data_make_free(tp, dbp,
1096 (xfs_dir2_data_aoff_t)((char *)dep - (char *)data),
1097 XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
1098 /*
1099 * We just mark the leaf entry stale by putting a null in it.
1100 */
1101 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1);
1102 xfs_dir2_leaf_log_header(tp, lbp);
1103 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR);
1104 xfs_dir2_leaf_log_ents(tp, lbp, index, index);
1105 /*
1106 * Scan the freespace in the data block again if necessary,
1107 * log the data block header if necessary.
1108 */
1109 if (needscan)
1110 xfs_dir2_data_freescan(mp, data, &needlog, NULL);
1111 if (needlog)
1112 xfs_dir2_data_log_header(tp, dbp);
1113 /*
1114 * If the longest freespace in the data block has changed,
1115 * put the new value in the bests table and log that.
1116 */
1117 if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) != oldbest) {
1118 INT_COPY(bestsp[db], data->hdr.bestfree[0].length, ARCH_CONVERT);
1119 xfs_dir2_leaf_log_bests(tp, lbp, db, db);
1120 }
1121 xfs_dir2_data_check(dp, dbp);
1122 /*
1123 * If the data block is now empty then get rid of the data block.
1124 */
1125 if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) ==
1126 mp->m_dirblksize - (uint)sizeof(data->hdr)) {
1127 #pragma mips_frequency_hint NEVER
1128 ASSERT(db != mp->m_dirdatablk);
1129 if (error = xfs_dir2_shrink_inode(args, db, dbp)) {
1130 /*
1131 * Nope, can't get rid of it because it caused
1132 * allocation of a bmap btree block to do so.
1133 * Just go on, returning success, leaving the
1134 * empty block in place.
1135 */
1136 if (error == ENOSPC && args->total == 0) {
1137 xfs_da_buf_done(dbp);
1138 error = 0;
1139 }
1140 xfs_dir2_leaf_check(dp, lbp);
1141 xfs_da_buf_done(lbp);
1142 return error;
1143 }
1144 dbp = NULL;
1145 /*
1146 * If this is the last data block then compact the
1147 * bests table by getting rid of entries.
1148 */
1149 if (db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1) {
1150 /*
1151 * Look for the last active entry (i).
1152 */
1153 for (i = db - 1; i > 0; i--) {
1154 if (INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF)
1155 break;
1156 }
1157 /*
1158 * Copy the table down so inactive entries at the
1159 * end are removed.
1160 */
1161 ovbcopy(bestsp, &bestsp[db - i],
1162 (INT_GET(ltp->bestcount, ARCH_CONVERT) - (db - i)) * sizeof(*bestsp));
1163 INT_MOD(ltp->bestcount, ARCH_CONVERT, -(db - i));
1164 xfs_dir2_leaf_log_tail(tp, lbp);
1165 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1166 } else
1167 INT_SET(bestsp[db], ARCH_CONVERT, NULLDATAOFF);
1168 }
1169 /*
1170 * If the data block was not the first one, drop it.
1171 */
1172 else if (db != mp->m_dirdatablk && dbp != NULL) {
1173 xfs_da_buf_done(dbp);
1174 dbp = NULL;
1175 }
1176 xfs_dir2_leaf_check(dp, lbp);
1177 /*
1178 * See if we can convert to block form.
1179 */
1180 return xfs_dir2_leaf_to_block(args, lbp, dbp);
1181 }
1182
1183 /*
1184 * Replace the inode number in a leaf format directory entry.
1185 */
1186 int /* error */
1187 xfs_dir2_leaf_replace(
1188 xfs_da_args_t *args) /* operation arguments */
1189 {
1190 xfs_dabuf_t *dbp; /* data block buffer */
1191 xfs_dir2_data_entry_t *dep; /* data block entry */
1192 xfs_inode_t *dp; /* incore directory inode */
1193 int error; /* error return code */
1194 int index; /* index of leaf entry */
1195 xfs_dabuf_t *lbp; /* leaf buffer */
1196 xfs_dir2_leaf_t *leaf; /* leaf structure */
1197 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1198 xfs_trans_t *tp; /* transaction pointer */
1199
1200 xfs_dir2_trace_args("leaf_replace", args);
1201 /*
1202 * Look up the entry.
1203 */
1204 if (error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp)) {
1205 #pragma mips_frequency_hint NEVER
1206 return error;
1207 }
1208 dp = args->dp;
1209 leaf = lbp->data;
1210 /*
1211 * Point to the leaf entry, get data address from it.
1212 */
1213 lep = &leaf->ents[index];
1214 /*
1215 * Point to the data entry.
1216 */
1217 dep = (xfs_dir2_data_entry_t *)
1218 ((char *)dbp->data +
1219 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT)));
1220 ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT));
1221 /*
1222 * Put the new inode number in, log it.
1223 */
1224 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
1225 tp = args->trans;
1226 xfs_dir2_data_log_entry(tp, dbp, dep);
1227 xfs_da_buf_done(dbp);
1228 xfs_dir2_leaf_check(dp, lbp);
1229 xfs_da_brelse(tp, lbp);
1230 return 0;
1231 }
1232
1233 /*
1234 * Return index in the leaf block (lbp) which is either the first
1235 * one with this hash value, or if there are none, the insert point
1236 * for that hash value.
1237 */
1238 int /* index value */
1239 xfs_dir2_leaf_search_hash(
1240 xfs_da_args_t *args, /* operation arguments */
1241 xfs_dabuf_t *lbp) /* leaf buffer */
1242 {
1243 xfs_dahash_t hash; /* hash from this entry */
1244 xfs_dahash_t hashwant; /* hash value looking for */
1245 int high; /* high leaf index */
1246 int low; /* low leaf index */
1247 xfs_dir2_leaf_t *leaf; /* leaf structure */
1248 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1249 int mid; /* current leaf index */
1250
1251 leaf = lbp->data;
1252 #ifndef __KERNEL__
1253 if (INT_GET(leaf->hdr.count, ARCH_CONVERT) == 0)
1254 return 0;
1255 #endif
1256 /*
1257 * Note, the table cannot be empty, so we have to go through the loop.
1258 * Binary search the leaf entries looking for our hash value.
1259 */
1260 for (lep = leaf->ents, low = 0, high = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1,
1261 hashwant = args->hashval;
1262 low <= high; ) {
1263 mid = (low + high) >> 1;
1264 if ((hash = INT_GET(lep[mid].hashval, ARCH_CONVERT)) == hashwant)
1265 break;
1266 if (hash < hashwant)
1267 low = mid + 1;
1268 else
1269 high = mid - 1;
1270 }
1271 /*
1272 * Found one, back up through all the equal hash values.
1273 */
1274 if (hash == hashwant) {
1275 while (mid > 0 && INT_GET(lep[mid - 1].hashval, ARCH_CONVERT) == hashwant) {
1276 #pragma mips_frequency_hint NEVER
1277 mid--;
1278 }
1279 }
1280 /*
1281 * Need to point to an entry higher than ours.
1282 */
1283 else if (hash < hashwant)
1284 mid++;
1285 return mid;
1286 }
1287
1288 /*
1289 * Trim off a trailing data block. We know it's empty since the leaf
1290 * freespace table says so.
1291 */
1292 int /* error */
1293 xfs_dir2_leaf_trim_data(
1294 xfs_da_args_t *args, /* operation arguments */
1295 xfs_dabuf_t *lbp, /* leaf buffer */
1296 xfs_dir2_db_t db) /* data block number */
1297 {
1298 xfs_dir2_data_off_t *bestsp; /* leaf bests table */
1299 #ifdef DEBUG
1300 xfs_dir2_data_t *data; /* data block structure */
1301 #endif
1302 xfs_dabuf_t *dbp; /* data block buffer */
1303 xfs_inode_t *dp; /* incore directory inode */
1304 int error; /* error return value */
1305 xfs_dir2_leaf_t *leaf; /* leaf structure */
1306 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1307 xfs_mount_t *mp; /* filesystem mount point */
1308 xfs_trans_t *tp; /* transaction pointer */
1309
1310 dp = args->dp;
1311 mp = dp->i_mount;
1312 tp = args->trans;
1313 /*
1314 * Read the offending data block. We need its buffer.
1315 */
1316 if (error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, db), -1, &dbp,
1317 XFS_DATA_FORK)) {
1318 #pragma mips_frequency_hint NEVER
1319 return error;
1320 }
1321 #ifdef DEBUG
1322 data = dbp->data;
1323 ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC);
1324 #endif
1325 /* this seems to be an error
1326 * data is only valid if DEBUG is defined?
1327 * RMC 09/08/1999
1328 */
1329
1330 leaf = lbp->data;
1331 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1332 ASSERT(INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) ==
1333 mp->m_dirblksize - (uint)sizeof(data->hdr));
1334 ASSERT(db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1335 /*
1336 * Get rid of the data block.
1337 */
1338 if (error = xfs_dir2_shrink_inode(args, db, dbp)) {
1339 #pragma mips_frequency_hint NEVER
1340 ASSERT(error != ENOSPC);
1341 xfs_da_brelse(tp, dbp);
1342 return error;
1343 }
1344 /*
1345 * Eliminate the last bests entry from the table.
1346 */
1347 bestsp = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT);
1348 INT_MOD(ltp->bestcount, ARCH_CONVERT, -1);
1349 ovbcopy(&bestsp[0], &bestsp[1], INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(*bestsp));
1350 xfs_dir2_leaf_log_tail(tp, lbp);
1351 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1352 return 0;
1353 }
1354
1355 /*
1356 * Convert node form directory to leaf form directory.
1357 * The root of the node form dir needs to already be a LEAFN block.
1358 * Just return if we can't do anything.
1359 */
1360 int /* error */
1361 xfs_dir2_node_to_leaf(
1362 xfs_da_state_t *state) /* directory operation state */
1363 {
1364 xfs_da_args_t *args; /* operation arguments */
1365 xfs_inode_t *dp; /* incore directory inode */
1366 int error; /* error return code */
1367 xfs_dabuf_t *fbp; /* buffer for freespace block */
1368 xfs_fileoff_t fo; /* freespace file offset */
1369 xfs_dir2_free_t *free; /* freespace structure */
1370 xfs_dabuf_t *lbp; /* buffer for leaf block */
1371 xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */
1372 xfs_dir2_leaf_t *leaf; /* leaf structure */
1373 xfs_mount_t *mp; /* filesystem mount point */
1374 int rval; /* successful free trim? */
1375 xfs_trans_t *tp; /* transaction pointer */
1376
1377 /*
1378 * There's more than a leaf level in the btree, so there must
1379 * be multiple leafn blocks. Give up.
1380 */
1381 if (state->path.active > 1)
1382 return 0;
1383 args = state->args;
1384 xfs_dir2_trace_args("node_to_leaf", args);
1385 mp = state->mp;
1386 dp = args->dp;
1387 tp = args->trans;
1388 /*
1389 * Get the last offset in the file.
1390 */
1391 if (error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK)) {
1392 #pragma mips_frequency_hint NEVER
1393 return error;
1394 }
1395 fo -= mp->m_dirblkfsbs;
1396 /*
1397 * If there are freespace blocks other than the first one,
1398 * take this opportunity to remove trailing empty freespace blocks
1399 * that may have been left behind during no-space-reservation
1400 * operations.
1401 */
1402 while (fo > mp->m_dirfreeblk) {
1403 if (error = xfs_dir2_node_trim_free(args, fo, &rval)) {
1404 #pragma mips_frequency_hint NEVER
1405 return error;
1406 }
1407 if (rval)
1408 fo -= mp->m_dirblkfsbs;
1409 else
1410 return 0;
1411 }
1412 /*
1413 * Now find the block just before the freespace block.
1414 */
1415 if (error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK)) {
1416 #pragma mips_frequency_hint NEVER
1417 return error;
1418 }
1419 /*
1420 * If it's not the single leaf block, give up.
1421 */
1422 if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize)
1423 return 0;
1424 lbp = state->path.blk[0].bp;
1425 leaf = lbp->data;
1426 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1427 /*
1428 * Read the freespace block.
1429 */
1430 if (error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp,
1431 XFS_DATA_FORK)) {
1432 #pragma mips_frequency_hint NEVER
1433 return error;
1434 }
1435 free = fbp->data;
1436 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
1437 ASSERT(INT_ISZERO(free->hdr.firstdb, ARCH_CONVERT));
1438 /*
1439 * Now see if the leafn and free data will fit in a leaf1.
1440 * If not, release the buffer and give up.
1441 */
1442 if ((uint)sizeof(leaf->hdr) +
1443 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)) * (uint)sizeof(leaf->ents[0]) +
1444 INT_GET(free->hdr.nvalid, ARCH_CONVERT) * (uint)sizeof(leaf->bests[0]) +
1445 (uint)sizeof(leaf->tail) >
1446 mp->m_dirblksize) {
1447 xfs_da_brelse(tp, fbp);
1448 return 0;
1449 }
1450 /*
1451 * If the leaf has any stale entries in it, compress them out.
1452 * The compact routine will log the header.
1453 */
1454 if (INT_GET(leaf->hdr.stale, ARCH_CONVERT))
1455 xfs_dir2_leaf_compact(args, lbp);
1456 else
1457 xfs_dir2_leaf_log_header(tp, lbp);
1458 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAF1_MAGIC);
1459 /*
1460 * Set up the leaf tail from the freespace block.
1461 */
1462 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1463 INT_COPY(ltp->bestcount, free->hdr.nvalid, ARCH_CONVERT);
1464 /*
1465 * Set up the leaf bests table.
1466 */
1467 bcopy(free->bests, XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT),
1468 INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(leaf->bests[0]));
1469 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1470 xfs_dir2_leaf_log_tail(tp, lbp);
1471 xfs_dir2_leaf_check(dp, lbp);
1472 /*
1473 * Get rid of the freespace block.
1474 */
1475 error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp);
1476 if (error) {
1477 #pragma mips_frequency_hint NEVER
1478 /*
1479 * This can't fail here because it can only happen when
1480 * punching out the middle of an extent, and this is an
1481 * isolated block.
1482 */
1483 ASSERT(error != ENOSPC);
1484 return error;
1485 }
1486 fbp = NULL;
1487 /*
1488 * Now see if we can convert the single-leaf directory
1489 * down to a block form directory.
1490 * This routine always kills the dabuf for the leaf, so
1491 * eliminate it from the path.
1492 */
1493 error = xfs_dir2_leaf_to_block(args, lbp, NULL);
1494 state->path.blk[0].bp = NULL;
1495 return error;
1496 }