1
2
3
4
5
6
7#include "xfs.h"
8#include "xfs_fs.h"
9#include "xfs_format.h"
10#include "xfs_log_format.h"
11#include "xfs_trans_resv.h"
12#include "xfs_mount.h"
13#include "xfs_da_format.h"
14#include "xfs_da_btree.h"
15#include "xfs_inode.h"
16#include "xfs_bmap.h"
17#include "xfs_dir2.h"
18#include "xfs_dir2_priv.h"
19#include "xfs_error.h"
20#include "xfs_trace.h"
21#include "xfs_trans.h"
22#include "xfs_buf_item.h"
23#include "xfs_cksum.h"
24#include "xfs_log.h"
25
26
27
28
29static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args,
30 int index);
31static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state,
32 xfs_da_state_blk_t *blk1,
33 xfs_da_state_blk_t *blk2);
34static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp,
35 int index, xfs_da_state_blk_t *dblk,
36 int *rval);
37static int xfs_dir2_node_addname_int(xfs_da_args_t *args,
38 xfs_da_state_blk_t *fblk);
39
40
41
42
43#ifdef DEBUG
44static xfs_failaddr_t
45xfs_dir3_leafn_check(
46 struct xfs_inode *dp,
47 struct xfs_buf *bp)
48{
49 struct xfs_dir2_leaf *leaf = bp->b_addr;
50 struct xfs_dir3_icleaf_hdr leafhdr;
51
52 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
53
54 if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) {
55 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
56 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
57 return __this_address;
58 } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC)
59 return __this_address;
60
61 return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf);
62}
63
64static inline void
65xfs_dir3_leaf_check(
66 struct xfs_inode *dp,
67 struct xfs_buf *bp)
68{
69 xfs_failaddr_t fa;
70
71 fa = xfs_dir3_leafn_check(dp, bp);
72 if (!fa)
73 return;
74 xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, dp->i_mount,
75 bp->b_addr, BBTOB(bp->b_length), __FILE__, __LINE__,
76 fa);
77 ASSERT(0);
78}
79#else
80#define xfs_dir3_leaf_check(dp, bp)
81#endif
82
83static xfs_failaddr_t
84xfs_dir3_free_verify(
85 struct xfs_buf *bp)
86{
87 struct xfs_mount *mp = bp->b_target->bt_mount;
88 struct xfs_dir2_free_hdr *hdr = bp->b_addr;
89
90 if (xfs_sb_version_hascrc(&mp->m_sb)) {
91 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
92
93 if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC))
94 return __this_address;
95 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
96 return __this_address;
97 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
98 return __this_address;
99 if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
100 return __this_address;
101 } else {
102 if (hdr->magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC))
103 return __this_address;
104 }
105
106
107
108 return NULL;
109}
110
111static void
112xfs_dir3_free_read_verify(
113 struct xfs_buf *bp)
114{
115 struct xfs_mount *mp = bp->b_target->bt_mount;
116 xfs_failaddr_t fa;
117
118 if (xfs_sb_version_hascrc(&mp->m_sb) &&
119 !xfs_buf_verify_cksum(bp, XFS_DIR3_FREE_CRC_OFF))
120 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
121 else {
122 fa = xfs_dir3_free_verify(bp);
123 if (fa)
124 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
125 }
126}
127
128static void
129xfs_dir3_free_write_verify(
130 struct xfs_buf *bp)
131{
132 struct xfs_mount *mp = bp->b_target->bt_mount;
133 struct xfs_buf_log_item *bip = bp->b_log_item;
134 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
135 xfs_failaddr_t fa;
136
137 fa = xfs_dir3_free_verify(bp);
138 if (fa) {
139 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
140 return;
141 }
142
143 if (!xfs_sb_version_hascrc(&mp->m_sb))
144 return;
145
146 if (bip)
147 hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
148
149 xfs_buf_update_cksum(bp, XFS_DIR3_FREE_CRC_OFF);
150}
151
152const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
153 .name = "xfs_dir3_free",
154 .verify_read = xfs_dir3_free_read_verify,
155 .verify_write = xfs_dir3_free_write_verify,
156 .verify_struct = xfs_dir3_free_verify,
157};
158
159
160static xfs_failaddr_t
161xfs_dir3_free_header_check(
162 struct xfs_inode *dp,
163 xfs_dablk_t fbno,
164 struct xfs_buf *bp)
165{
166 struct xfs_mount *mp = dp->i_mount;
167 unsigned int firstdb;
168 int maxbests;
169
170 maxbests = dp->d_ops->free_max_bests(mp->m_dir_geo);
171 firstdb = (xfs_dir2_da_to_db(mp->m_dir_geo, fbno) -
172 xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) *
173 maxbests;
174 if (xfs_sb_version_hascrc(&mp->m_sb)) {
175 struct xfs_dir3_free_hdr *hdr3 = bp->b_addr;
176
177 if (be32_to_cpu(hdr3->firstdb) != firstdb)
178 return __this_address;
179 if (be32_to_cpu(hdr3->nvalid) > maxbests)
180 return __this_address;
181 if (be32_to_cpu(hdr3->nvalid) < be32_to_cpu(hdr3->nused))
182 return __this_address;
183 } else {
184 struct xfs_dir2_free_hdr *hdr = bp->b_addr;
185
186 if (be32_to_cpu(hdr->firstdb) != firstdb)
187 return __this_address;
188 if (be32_to_cpu(hdr->nvalid) > maxbests)
189 return __this_address;
190 if (be32_to_cpu(hdr->nvalid) < be32_to_cpu(hdr->nused))
191 return __this_address;
192 }
193 return NULL;
194}
195
196static int
197__xfs_dir3_free_read(
198 struct xfs_trans *tp,
199 struct xfs_inode *dp,
200 xfs_dablk_t fbno,
201 xfs_daddr_t mappedbno,
202 struct xfs_buf **bpp)
203{
204 xfs_failaddr_t fa;
205 int err;
206
207 err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
208 XFS_DATA_FORK, &xfs_dir3_free_buf_ops);
209 if (err || !*bpp)
210 return err;
211
212
213 fa = xfs_dir3_free_header_check(dp, fbno, *bpp);
214 if (fa) {
215 xfs_verifier_error(*bpp, -EFSCORRUPTED, fa);
216 xfs_trans_brelse(tp, *bpp);
217 return -EFSCORRUPTED;
218 }
219
220
221 if (tp)
222 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_FREE_BUF);
223
224 return 0;
225}
226
227int
228xfs_dir2_free_read(
229 struct xfs_trans *tp,
230 struct xfs_inode *dp,
231 xfs_dablk_t fbno,
232 struct xfs_buf **bpp)
233{
234 return __xfs_dir3_free_read(tp, dp, fbno, -1, bpp);
235}
236
237static int
238xfs_dir2_free_try_read(
239 struct xfs_trans *tp,
240 struct xfs_inode *dp,
241 xfs_dablk_t fbno,
242 struct xfs_buf **bpp)
243{
244 return __xfs_dir3_free_read(tp, dp, fbno, -2, bpp);
245}
246
247static int
248xfs_dir3_free_get_buf(
249 xfs_da_args_t *args,
250 xfs_dir2_db_t fbno,
251 struct xfs_buf **bpp)
252{
253 struct xfs_trans *tp = args->trans;
254 struct xfs_inode *dp = args->dp;
255 struct xfs_mount *mp = dp->i_mount;
256 struct xfs_buf *bp;
257 int error;
258 struct xfs_dir3_icfree_hdr hdr;
259
260 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, fbno),
261 -1, &bp, XFS_DATA_FORK);
262 if (error)
263 return error;
264
265 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_FREE_BUF);
266 bp->b_ops = &xfs_dir3_free_buf_ops;
267
268
269
270
271
272 memset(bp->b_addr, 0, sizeof(struct xfs_dir3_free_hdr));
273 memset(&hdr, 0, sizeof(hdr));
274
275 if (xfs_sb_version_hascrc(&mp->m_sb)) {
276 struct xfs_dir3_free_hdr *hdr3 = bp->b_addr;
277
278 hdr.magic = XFS_DIR3_FREE_MAGIC;
279
280 hdr3->hdr.blkno = cpu_to_be64(bp->b_bn);
281 hdr3->hdr.owner = cpu_to_be64(dp->i_ino);
282 uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid);
283 } else
284 hdr.magic = XFS_DIR2_FREE_MAGIC;
285 dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr);
286 *bpp = bp;
287 return 0;
288}
289
290
291
292
293STATIC void
294xfs_dir2_free_log_bests(
295 struct xfs_da_args *args,
296 struct xfs_buf *bp,
297 int first,
298 int last)
299{
300 xfs_dir2_free_t *free;
301 __be16 *bests;
302
303 free = bp->b_addr;
304 bests = args->dp->d_ops->free_bests_p(free);
305 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
306 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
307 xfs_trans_log_buf(args->trans, bp,
308 (uint)((char *)&bests[first] - (char *)free),
309 (uint)((char *)&bests[last] - (char *)free +
310 sizeof(bests[0]) - 1));
311}
312
313
314
315
316static void
317xfs_dir2_free_log_header(
318 struct xfs_da_args *args,
319 struct xfs_buf *bp)
320{
321#ifdef DEBUG
322 xfs_dir2_free_t *free;
323
324 free = bp->b_addr;
325 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
326 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
327#endif
328 xfs_trans_log_buf(args->trans, bp, 0,
329 args->dp->d_ops->free_hdr_size - 1);
330}
331
332
333
334
335
336
337int
338xfs_dir2_leaf_to_node(
339 xfs_da_args_t *args,
340 struct xfs_buf *lbp)
341{
342 xfs_inode_t *dp;
343 int error;
344 struct xfs_buf *fbp;
345 xfs_dir2_db_t fdb;
346 xfs_dir2_free_t *free;
347 __be16 *from;
348 int i;
349 xfs_dir2_leaf_t *leaf;
350 xfs_dir2_leaf_tail_t *ltp;
351 int n;
352 xfs_dir2_data_off_t off;
353 __be16 *to;
354 xfs_trans_t *tp;
355 struct xfs_dir3_icfree_hdr freehdr;
356
357 trace_xfs_dir2_leaf_to_node(args);
358
359 dp = args->dp;
360 tp = args->trans;
361
362
363
364 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {
365 return error;
366 }
367 ASSERT(fdb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
368
369
370
371 error = xfs_dir3_free_get_buf(args, fdb, &fbp);
372 if (error)
373 return error;
374
375 free = fbp->b_addr;
376 dp->d_ops->free_hdr_from_disk(&freehdr, free);
377 leaf = lbp->b_addr;
378 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
379 if (be32_to_cpu(ltp->bestcount) >
380 (uint)dp->i_d.di_size / args->geo->blksize)
381 return -EFSCORRUPTED;
382
383
384
385
386
387 from = xfs_dir2_leaf_bests_p(ltp);
388 to = dp->d_ops->free_bests_p(free);
389 for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) {
390 if ((off = be16_to_cpu(*from)) != NULLDATAOFF)
391 n++;
392 *to = cpu_to_be16(off);
393 }
394
395
396
397
398 freehdr.nused = n;
399 freehdr.nvalid = be32_to_cpu(ltp->bestcount);
400
401 dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
402 xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
403 xfs_dir2_free_log_header(args, fbp);
404
405
406
407
408
409
410
411 if (leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC))
412 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
413 else
414 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
415 lbp->b_ops = &xfs_dir3_leafn_buf_ops;
416 xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF);
417 xfs_dir3_leaf_log_header(args, lbp);
418 xfs_dir3_leaf_check(dp, lbp);
419 return 0;
420}
421
422
423
424
425
426static int
427xfs_dir2_leafn_add(
428 struct xfs_buf *bp,
429 xfs_da_args_t *args,
430 int index)
431{
432 int compact;
433 xfs_inode_t *dp;
434 int highstale;
435 xfs_dir2_leaf_t *leaf;
436 xfs_dir2_leaf_entry_t *lep;
437 int lfloghigh;
438 int lfloglow;
439 int lowstale;
440 struct xfs_dir3_icleaf_hdr leafhdr;
441 struct xfs_dir2_leaf_entry *ents;
442
443 trace_xfs_dir2_leafn_add(args, index);
444
445 dp = args->dp;
446 leaf = bp->b_addr;
447 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
448 ents = dp->d_ops->leaf_ents_p(leaf);
449
450
451
452
453
454 if (index < 0)
455 return -EFSCORRUPTED;
456
457
458
459
460
461
462
463
464 if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) {
465 if (!leafhdr.stale)
466 return -ENOSPC;
467 compact = leafhdr.stale > 1;
468 } else
469 compact = 0;
470 ASSERT(index == 0 || be32_to_cpu(ents[index - 1].hashval) <= args->hashval);
471 ASSERT(index == leafhdr.count ||
472 be32_to_cpu(ents[index].hashval) >= args->hashval);
473
474 if (args->op_flags & XFS_DA_OP_JUSTCHECK)
475 return 0;
476
477
478
479
480
481 if (compact)
482 xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale,
483 &highstale, &lfloglow, &lfloghigh);
484 else if (leafhdr.stale) {
485
486
487
488 lfloglow = leafhdr.count;
489 lfloghigh = -1;
490 }
491
492
493
494
495 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
496 highstale, &lfloglow, &lfloghigh);
497
498 lep->hashval = cpu_to_be32(args->hashval);
499 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo,
500 args->blkno, args->index));
501
502 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
503 xfs_dir3_leaf_log_header(args, bp);
504 xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh);
505 xfs_dir3_leaf_check(dp, bp);
506 return 0;
507}
508
509#ifdef DEBUG
510static void
511xfs_dir2_free_hdr_check(
512 struct xfs_inode *dp,
513 struct xfs_buf *bp,
514 xfs_dir2_db_t db)
515{
516 struct xfs_dir3_icfree_hdr hdr;
517
518 dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr);
519
520 ASSERT((hdr.firstdb %
521 dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0);
522 ASSERT(hdr.firstdb <= db);
523 ASSERT(db < hdr.firstdb + hdr.nvalid);
524}
525#else
526#define xfs_dir2_free_hdr_check(dp, bp, db)
527#endif
528
529
530
531
532
533xfs_dahash_t
534xfs_dir2_leaf_lasthash(
535 struct xfs_inode *dp,
536 struct xfs_buf *bp,
537 int *count)
538{
539 struct xfs_dir2_leaf *leaf = bp->b_addr;
540 struct xfs_dir2_leaf_entry *ents;
541 struct xfs_dir3_icleaf_hdr leafhdr;
542
543 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
544
545 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
546 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC ||
547 leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
548 leafhdr.magic == XFS_DIR3_LEAF1_MAGIC);
549
550 if (count)
551 *count = leafhdr.count;
552 if (!leafhdr.count)
553 return 0;
554
555 ents = dp->d_ops->leaf_ents_p(leaf);
556 return be32_to_cpu(ents[leafhdr.count - 1].hashval);
557}
558
559
560
561
562
563STATIC int
564xfs_dir2_leafn_lookup_for_addname(
565 struct xfs_buf *bp,
566 xfs_da_args_t *args,
567 int *indexp,
568 xfs_da_state_t *state)
569{
570 struct xfs_buf *curbp = NULL;
571 xfs_dir2_db_t curdb = -1;
572 xfs_dir2_db_t curfdb = -1;
573 xfs_inode_t *dp;
574 int error;
575 int fi;
576 xfs_dir2_free_t *free = NULL;
577 int index;
578 xfs_dir2_leaf_t *leaf;
579 int length;
580 xfs_dir2_leaf_entry_t *lep;
581 xfs_mount_t *mp;
582 xfs_dir2_db_t newdb;
583 xfs_dir2_db_t newfdb;
584 xfs_trans_t *tp;
585 struct xfs_dir2_leaf_entry *ents;
586 struct xfs_dir3_icleaf_hdr leafhdr;
587
588 dp = args->dp;
589 tp = args->trans;
590 mp = dp->i_mount;
591 leaf = bp->b_addr;
592 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
593 ents = dp->d_ops->leaf_ents_p(leaf);
594
595 xfs_dir3_leaf_check(dp, bp);
596 ASSERT(leafhdr.count > 0);
597
598
599
600
601 index = xfs_dir2_leaf_search_hash(args, bp);
602
603
604
605 if (state->extravalid) {
606
607 curbp = state->extrablk.bp;
608 curfdb = state->extrablk.blkno;
609 free = curbp->b_addr;
610 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
611 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
612 }
613 length = dp->d_ops->data_entsize(args->namelen);
614
615
616
617 for (lep = &ents[index];
618 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
619 lep++, index++) {
620
621
622
623 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
624 continue;
625
626
627
628 newdb = xfs_dir2_dataptr_to_db(args->geo,
629 be32_to_cpu(lep->address));
630
631
632
633
634
635
636
637
638 if (newdb != curdb) {
639 __be16 *bests;
640
641 curdb = newdb;
642
643
644
645
646 newfdb = dp->d_ops->db_to_fdb(args->geo, newdb);
647
648
649
650 if (newfdb != curfdb) {
651
652
653
654 if (curbp)
655 xfs_trans_brelse(tp, curbp);
656
657 error = xfs_dir2_free_read(tp, dp,
658 xfs_dir2_db_to_da(args->geo,
659 newfdb),
660 &curbp);
661 if (error)
662 return error;
663 free = curbp->b_addr;
664
665 xfs_dir2_free_hdr_check(dp, curbp, curdb);
666 }
667
668
669
670 fi = dp->d_ops->db_to_fdindex(args->geo, curdb);
671
672
673
674 bests = dp->d_ops->free_bests_p(free);
675 if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) {
676 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
677 XFS_ERRLEVEL_LOW, mp);
678 if (curfdb != newfdb)
679 xfs_trans_brelse(tp, curbp);
680 return -EFSCORRUPTED;
681 }
682 curfdb = newfdb;
683 if (be16_to_cpu(bests[fi]) >= length)
684 goto out;
685 }
686 }
687
688 fi = -1;
689out:
690 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT);
691 if (curbp) {
692
693 state->extravalid = 1;
694 state->extrablk.bp = curbp;
695 state->extrablk.index = fi;
696 state->extrablk.blkno = curfdb;
697
698
699
700
701
702
703 state->extrablk.magic = XFS_DIR2_FREE_MAGIC;
704 } else {
705 state->extravalid = 0;
706 }
707
708
709
710 *indexp = index;
711 return -ENOENT;
712}
713
714
715
716
717
718STATIC int
719xfs_dir2_leafn_lookup_for_entry(
720 struct xfs_buf *bp,
721 xfs_da_args_t *args,
722 int *indexp,
723 xfs_da_state_t *state)
724{
725 struct xfs_buf *curbp = NULL;
726 xfs_dir2_db_t curdb = -1;
727 xfs_dir2_data_entry_t *dep;
728 xfs_inode_t *dp;
729 int error;
730 int index;
731 xfs_dir2_leaf_t *leaf;
732 xfs_dir2_leaf_entry_t *lep;
733 xfs_mount_t *mp;
734 xfs_dir2_db_t newdb;
735 xfs_trans_t *tp;
736 enum xfs_dacmp cmp;
737 struct xfs_dir2_leaf_entry *ents;
738 struct xfs_dir3_icleaf_hdr leafhdr;
739
740 dp = args->dp;
741 tp = args->trans;
742 mp = dp->i_mount;
743 leaf = bp->b_addr;
744 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
745 ents = dp->d_ops->leaf_ents_p(leaf);
746
747 xfs_dir3_leaf_check(dp, bp);
748 ASSERT(leafhdr.count > 0);
749
750
751
752
753 index = xfs_dir2_leaf_search_hash(args, bp);
754
755
756
757 if (state->extravalid) {
758 curbp = state->extrablk.bp;
759 curdb = state->extrablk.blkno;
760 }
761
762
763
764 for (lep = &ents[index];
765 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
766 lep++, index++) {
767
768
769
770 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
771 continue;
772
773
774
775 newdb = xfs_dir2_dataptr_to_db(args->geo,
776 be32_to_cpu(lep->address));
777
778
779
780
781
782
783 if (newdb != curdb) {
784
785
786
787
788 if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT ||
789 curdb != state->extrablk.blkno))
790 xfs_trans_brelse(tp, curbp);
791
792
793
794
795 if (args->cmpresult != XFS_CMP_DIFFERENT &&
796 newdb == state->extrablk.blkno) {
797 ASSERT(state->extravalid);
798 curbp = state->extrablk.bp;
799 } else {
800 error = xfs_dir3_data_read(tp, dp,
801 xfs_dir2_db_to_da(args->geo,
802 newdb),
803 -1, &curbp);
804 if (error)
805 return error;
806 }
807 xfs_dir3_data_check(dp, curbp);
808 curdb = newdb;
809 }
810
811
812
813 dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr +
814 xfs_dir2_dataptr_to_off(args->geo,
815 be32_to_cpu(lep->address)));
816
817
818
819
820
821 cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen);
822 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
823
824 if (args->cmpresult != XFS_CMP_DIFFERENT &&
825 curdb != state->extrablk.blkno)
826 xfs_trans_brelse(tp, state->extrablk.bp);
827 args->cmpresult = cmp;
828 args->inumber = be64_to_cpu(dep->inumber);
829 args->filetype = dp->d_ops->data_get_ftype(dep);
830 *indexp = index;
831 state->extravalid = 1;
832 state->extrablk.bp = curbp;
833 state->extrablk.blkno = curdb;
834 state->extrablk.index = (int)((char *)dep -
835 (char *)curbp->b_addr);
836 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
837 curbp->b_ops = &xfs_dir3_data_buf_ops;
838 xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF);
839 if (cmp == XFS_CMP_EXACT)
840 return -EEXIST;
841 }
842 }
843 ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT));
844 if (curbp) {
845 if (args->cmpresult == XFS_CMP_DIFFERENT) {
846
847 state->extravalid = 1;
848 state->extrablk.bp = curbp;
849 state->extrablk.index = -1;
850 state->extrablk.blkno = curdb;
851 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
852 curbp->b_ops = &xfs_dir3_data_buf_ops;
853 xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF);
854 } else {
855
856 if (state->extrablk.bp != curbp)
857 xfs_trans_brelse(tp, curbp);
858 }
859 } else {
860 state->extravalid = 0;
861 }
862 *indexp = index;
863 return -ENOENT;
864}
865
866
867
868
869
870
871int
872xfs_dir2_leafn_lookup_int(
873 struct xfs_buf *bp,
874 xfs_da_args_t *args,
875 int *indexp,
876 xfs_da_state_t *state)
877{
878 if (args->op_flags & XFS_DA_OP_ADDNAME)
879 return xfs_dir2_leafn_lookup_for_addname(bp, args, indexp,
880 state);
881 return xfs_dir2_leafn_lookup_for_entry(bp, args, indexp, state);
882}
883
884
885
886
887
888static void
889xfs_dir3_leafn_moveents(
890 xfs_da_args_t *args,
891 struct xfs_buf *bp_s,
892 struct xfs_dir3_icleaf_hdr *shdr,
893 struct xfs_dir2_leaf_entry *sents,
894 int start_s,
895 struct xfs_buf *bp_d,
896 struct xfs_dir3_icleaf_hdr *dhdr,
897 struct xfs_dir2_leaf_entry *dents,
898 int start_d,
899 int count)
900{
901 int stale;
902
903 trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count);
904
905
906
907
908 if (count == 0)
909 return;
910
911
912
913
914
915
916 if (start_d < dhdr->count) {
917 memmove(&dents[start_d + count], &dents[start_d],
918 (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
919 xfs_dir3_leaf_log_ents(args, bp_d, start_d + count,
920 count + dhdr->count - 1);
921 }
922
923
924
925
926 if (shdr->stale) {
927 int i;
928
929 for (i = start_s, stale = 0; i < start_s + count; i++) {
930 if (sents[i].address ==
931 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
932 stale++;
933 }
934 } else
935 stale = 0;
936
937
938
939 memcpy(&dents[start_d], &sents[start_s],
940 count * sizeof(xfs_dir2_leaf_entry_t));
941 xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1);
942
943
944
945
946
947 if (start_s + count < shdr->count) {
948 memmove(&sents[start_s], &sents[start_s + count],
949 count * sizeof(xfs_dir2_leaf_entry_t));
950 xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1);
951 }
952
953
954
955
956 shdr->count -= count;
957 shdr->stale -= stale;
958 dhdr->count += count;
959 dhdr->stale += stale;
960}
961
962
963
964
965
966int
967xfs_dir2_leafn_order(
968 struct xfs_inode *dp,
969 struct xfs_buf *leaf1_bp,
970 struct xfs_buf *leaf2_bp)
971{
972 struct xfs_dir2_leaf *leaf1 = leaf1_bp->b_addr;
973 struct xfs_dir2_leaf *leaf2 = leaf2_bp->b_addr;
974 struct xfs_dir2_leaf_entry *ents1;
975 struct xfs_dir2_leaf_entry *ents2;
976 struct xfs_dir3_icleaf_hdr hdr1;
977 struct xfs_dir3_icleaf_hdr hdr2;
978
979 dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1);
980 dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2);
981 ents1 = dp->d_ops->leaf_ents_p(leaf1);
982 ents2 = dp->d_ops->leaf_ents_p(leaf2);
983
984 if (hdr1.count > 0 && hdr2.count > 0 &&
985 (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) ||
986 be32_to_cpu(ents2[hdr2.count - 1].hashval) <
987 be32_to_cpu(ents1[hdr1.count - 1].hashval)))
988 return 1;
989 return 0;
990}
991
992
993
994
995
996
997
998
999static void
1000xfs_dir2_leafn_rebalance(
1001 xfs_da_state_t *state,
1002 xfs_da_state_blk_t *blk1,
1003 xfs_da_state_blk_t *blk2)
1004{
1005 xfs_da_args_t *args;
1006 int count;
1007 int isleft;
1008 xfs_dir2_leaf_t *leaf1;
1009 xfs_dir2_leaf_t *leaf2;
1010 int mid;
1011#if defined(DEBUG) || defined(XFS_WARN)
1012 int oldstale;
1013#endif
1014 int oldsum;
1015 int swap;
1016 struct xfs_dir2_leaf_entry *ents1;
1017 struct xfs_dir2_leaf_entry *ents2;
1018 struct xfs_dir3_icleaf_hdr hdr1;
1019 struct xfs_dir3_icleaf_hdr hdr2;
1020 struct xfs_inode *dp = state->args->dp;
1021
1022 args = state->args;
1023
1024
1025
1026 if ((swap = xfs_dir2_leafn_order(dp, blk1->bp, blk2->bp))) {
1027 xfs_da_state_blk_t *tmp;
1028
1029 tmp = blk1;
1030 blk1 = blk2;
1031 blk2 = tmp;
1032 }
1033 leaf1 = blk1->bp->b_addr;
1034 leaf2 = blk2->bp->b_addr;
1035 dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1);
1036 dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2);
1037 ents1 = dp->d_ops->leaf_ents_p(leaf1);
1038 ents2 = dp->d_ops->leaf_ents_p(leaf2);
1039
1040 oldsum = hdr1.count + hdr2.count;
1041#if defined(DEBUG) || defined(XFS_WARN)
1042 oldstale = hdr1.stale + hdr2.stale;
1043#endif
1044 mid = oldsum >> 1;
1045
1046
1047
1048
1049
1050 if (oldsum & 1) {
1051 xfs_dahash_t midhash;
1052
1053 if (mid >= hdr1.count)
1054 midhash = be32_to_cpu(ents2[mid - hdr1.count].hashval);
1055 else
1056 midhash = be32_to_cpu(ents1[mid].hashval);
1057 isleft = args->hashval <= midhash;
1058 }
1059
1060
1061
1062
1063
1064 else
1065 isleft = 1;
1066
1067
1068
1069
1070 count = hdr1.count - mid + (isleft == 0);
1071 if (count > 0)
1072 xfs_dir3_leafn_moveents(args, blk1->bp, &hdr1, ents1,
1073 hdr1.count - count, blk2->bp,
1074 &hdr2, ents2, 0, count);
1075 else if (count < 0)
1076 xfs_dir3_leafn_moveents(args, blk2->bp, &hdr2, ents2, 0,
1077 blk1->bp, &hdr1, ents1,
1078 hdr1.count, count);
1079
1080 ASSERT(hdr1.count + hdr2.count == oldsum);
1081 ASSERT(hdr1.stale + hdr2.stale == oldstale);
1082
1083
1084 dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1);
1085 dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2);
1086 xfs_dir3_leaf_log_header(args, blk1->bp);
1087 xfs_dir3_leaf_log_header(args, blk2->bp);
1088
1089 xfs_dir3_leaf_check(dp, blk1->bp);
1090 xfs_dir3_leaf_check(dp, blk2->bp);
1091
1092
1093
1094
1095 if (hdr1.count < hdr2.count)
1096 state->inleaf = swap;
1097 else if (hdr1.count > hdr2.count)
1098 state->inleaf = !swap;
1099 else
1100 state->inleaf = swap ^ (blk1->index <= hdr1.count);
1101
1102
1103
1104 if (!state->inleaf)
1105 blk2->index = blk1->index - hdr1.count;
1106
1107
1108
1109
1110
1111 if (blk2->index < 0) {
1112 state->inleaf = 1;
1113 blk2->index = 0;
1114 xfs_alert(dp->i_mount,
1115 "%s: picked the wrong leaf? reverting original leaf: blk1->index %d",
1116 __func__, blk1->index);
1117 }
1118}
1119
1120static int
1121xfs_dir3_data_block_free(
1122 xfs_da_args_t *args,
1123 struct xfs_dir2_data_hdr *hdr,
1124 struct xfs_dir2_free *free,
1125 xfs_dir2_db_t fdb,
1126 int findex,
1127 struct xfs_buf *fbp,
1128 int longest)
1129{
1130 int logfree = 0;
1131 __be16 *bests;
1132 struct xfs_dir3_icfree_hdr freehdr;
1133 struct xfs_inode *dp = args->dp;
1134
1135 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1136 bests = dp->d_ops->free_bests_p(free);
1137 if (hdr) {
1138
1139
1140
1141
1142 bests[findex] = cpu_to_be16(longest);
1143 xfs_dir2_free_log_bests(args, fbp, findex, findex);
1144 return 0;
1145 }
1146
1147
1148 freehdr.nused--;
1149
1150
1151
1152
1153
1154
1155 if (findex == freehdr.nvalid - 1) {
1156 int i;
1157
1158 for (i = findex - 1; i >= 0; i--) {
1159 if (bests[i] != cpu_to_be16(NULLDATAOFF))
1160 break;
1161 }
1162 freehdr.nvalid = i + 1;
1163 logfree = 0;
1164 } else {
1165
1166 bests[findex] = cpu_to_be16(NULLDATAOFF);
1167 logfree = 1;
1168 }
1169
1170 dp->d_ops->free_hdr_to_disk(free, &freehdr);
1171 xfs_dir2_free_log_header(args, fbp);
1172
1173
1174
1175
1176
1177 if (!freehdr.nused) {
1178 int error;
1179
1180 error = xfs_dir2_shrink_inode(args, fdb, fbp);
1181 if (error == 0) {
1182 fbp = NULL;
1183 logfree = 0;
1184 } else if (error != -ENOSPC || args->total != 0)
1185 return error;
1186
1187
1188
1189
1190
1191 }
1192
1193
1194 if (logfree)
1195 xfs_dir2_free_log_bests(args, fbp, findex, findex);
1196 return 0;
1197}
1198
1199
1200
1201
1202
1203
1204static int
1205xfs_dir2_leafn_remove(
1206 xfs_da_args_t *args,
1207 struct xfs_buf *bp,
1208 int index,
1209 xfs_da_state_blk_t *dblk,
1210 int *rval)
1211{
1212 xfs_dir2_data_hdr_t *hdr;
1213 xfs_dir2_db_t db;
1214 struct xfs_buf *dbp;
1215 xfs_dir2_data_entry_t *dep;
1216 xfs_inode_t *dp;
1217 xfs_dir2_leaf_t *leaf;
1218 xfs_dir2_leaf_entry_t *lep;
1219 int longest;
1220 int off;
1221 int needlog;
1222 int needscan;
1223 xfs_trans_t *tp;
1224 struct xfs_dir2_data_free *bf;
1225 struct xfs_dir3_icleaf_hdr leafhdr;
1226 struct xfs_dir2_leaf_entry *ents;
1227
1228 trace_xfs_dir2_leafn_remove(args, index);
1229
1230 dp = args->dp;
1231 tp = args->trans;
1232 leaf = bp->b_addr;
1233 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
1234 ents = dp->d_ops->leaf_ents_p(leaf);
1235
1236
1237
1238
1239 lep = &ents[index];
1240
1241
1242
1243
1244 db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
1245 ASSERT(dblk->blkno == db);
1246 off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address));
1247 ASSERT(dblk->index == off);
1248
1249
1250
1251
1252
1253 leafhdr.stale++;
1254 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
1255 xfs_dir3_leaf_log_header(args, bp);
1256
1257 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1258 xfs_dir3_leaf_log_ents(args, bp, index, index);
1259
1260
1261
1262
1263
1264 dbp = dblk->bp;
1265 hdr = dbp->b_addr;
1266 dep = (xfs_dir2_data_entry_t *)((char *)hdr + off);
1267 bf = dp->d_ops->data_bestfree_p(hdr);
1268 longest = be16_to_cpu(bf[0].length);
1269 needlog = needscan = 0;
1270 xfs_dir2_data_make_free(args, dbp, off,
1271 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
1272
1273
1274
1275
1276 if (needscan)
1277 xfs_dir2_data_freescan(dp, hdr, &needlog);
1278 if (needlog)
1279 xfs_dir2_data_log_header(args, dbp);
1280 xfs_dir3_data_check(dp, dbp);
1281
1282
1283
1284
1285 if (longest < be16_to_cpu(bf[0].length)) {
1286 int error;
1287 struct xfs_buf *fbp;
1288 xfs_dir2_db_t fdb;
1289 int findex;
1290 xfs_dir2_free_t *free;
1291
1292
1293
1294
1295
1296 fdb = dp->d_ops->db_to_fdb(args->geo, db);
1297 error = xfs_dir2_free_read(tp, dp,
1298 xfs_dir2_db_to_da(args->geo, fdb),
1299 &fbp);
1300 if (error)
1301 return error;
1302 free = fbp->b_addr;
1303#ifdef DEBUG
1304 {
1305 struct xfs_dir3_icfree_hdr freehdr;
1306 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1307 ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
1308 (fdb - xfs_dir2_byte_to_db(args->geo,
1309 XFS_DIR2_FREE_OFFSET)));
1310 }
1311#endif
1312
1313
1314
1315 findex = dp->d_ops->db_to_fdindex(args->geo, db);
1316 longest = be16_to_cpu(bf[0].length);
1317
1318
1319
1320
1321 if (longest == args->geo->blksize -
1322 dp->d_ops->data_entry_offset) {
1323
1324
1325
1326 error = xfs_dir2_shrink_inode(args, db, dbp);
1327 if (error == 0) {
1328 dblk->bp = NULL;
1329 hdr = NULL;
1330 }
1331
1332
1333
1334
1335
1336 else if (!(error == -ENOSPC && args->total == 0))
1337 return error;
1338 }
1339
1340
1341
1342
1343 error = xfs_dir3_data_block_free(args, hdr, free,
1344 fdb, findex, fbp, longest);
1345 if (error)
1346 return error;
1347 }
1348
1349 xfs_dir3_leaf_check(dp, bp);
1350
1351
1352
1353
1354 *rval = (dp->d_ops->leaf_hdr_size +
1355 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
1356 args->geo->magicpct;
1357 return 0;
1358}
1359
1360
1361
1362
1363int
1364xfs_dir2_leafn_split(
1365 xfs_da_state_t *state,
1366 xfs_da_state_blk_t *oldblk,
1367 xfs_da_state_blk_t *newblk)
1368{
1369 xfs_da_args_t *args;
1370 xfs_dablk_t blkno;
1371 int error;
1372 struct xfs_inode *dp;
1373
1374
1375
1376
1377 args = state->args;
1378 dp = args->dp;
1379 ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC);
1380 error = xfs_da_grow_inode(args, &blkno);
1381 if (error) {
1382 return error;
1383 }
1384
1385
1386
1387 error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(args->geo, blkno),
1388 &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
1389 if (error)
1390 return error;
1391
1392 newblk->blkno = blkno;
1393 newblk->magic = XFS_DIR2_LEAFN_MAGIC;
1394
1395
1396
1397
1398 xfs_dir2_leafn_rebalance(state, oldblk, newblk);
1399 error = xfs_da3_blk_link(state, oldblk, newblk);
1400 if (error) {
1401 return error;
1402 }
1403
1404
1405
1406 if (state->inleaf)
1407 error = xfs_dir2_leafn_add(oldblk->bp, args, oldblk->index);
1408 else
1409 error = xfs_dir2_leafn_add(newblk->bp, args, newblk->index);
1410
1411
1412
1413 oldblk->hashval = xfs_dir2_leaf_lasthash(dp, oldblk->bp, NULL);
1414 newblk->hashval = xfs_dir2_leaf_lasthash(dp, newblk->bp, NULL);
1415 xfs_dir3_leaf_check(dp, oldblk->bp);
1416 xfs_dir3_leaf_check(dp, newblk->bp);
1417 return error;
1418}
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429int
1430xfs_dir2_leafn_toosmall(
1431 xfs_da_state_t *state,
1432 int *action)
1433{
1434 xfs_da_state_blk_t *blk;
1435 xfs_dablk_t blkno;
1436 struct xfs_buf *bp;
1437 int bytes;
1438 int count;
1439 int error;
1440 int forward;
1441 int i;
1442 xfs_dir2_leaf_t *leaf;
1443 int rval;
1444 struct xfs_dir3_icleaf_hdr leafhdr;
1445 struct xfs_dir2_leaf_entry *ents;
1446 struct xfs_inode *dp = state->args->dp;
1447
1448
1449
1450
1451
1452
1453 blk = &state->path.blk[state->path.active - 1];
1454 leaf = blk->bp->b_addr;
1455 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
1456 ents = dp->d_ops->leaf_ents_p(leaf);
1457 xfs_dir3_leaf_check(dp, blk->bp);
1458
1459 count = leafhdr.count - leafhdr.stale;
1460 bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]);
1461 if (bytes > (state->args->geo->blksize >> 1)) {
1462
1463
1464
1465 *action = 0;
1466 return 0;
1467 }
1468
1469
1470
1471
1472
1473
1474 if (count == 0) {
1475
1476
1477
1478
1479 forward = (leafhdr.forw != 0);
1480 memcpy(&state->altpath, &state->path, sizeof(state->path));
1481 error = xfs_da3_path_shift(state, &state->altpath, forward, 0,
1482 &rval);
1483 if (error)
1484 return error;
1485 *action = rval ? 2 : 0;
1486 return 0;
1487 }
1488
1489
1490
1491
1492
1493
1494
1495 forward = leafhdr.forw < leafhdr.back;
1496 for (i = 0, bp = NULL; i < 2; forward = !forward, i++) {
1497 struct xfs_dir3_icleaf_hdr hdr2;
1498
1499 blkno = forward ? leafhdr.forw : leafhdr.back;
1500 if (blkno == 0)
1501 continue;
1502
1503
1504
1505 error = xfs_dir3_leafn_read(state->args->trans, dp,
1506 blkno, -1, &bp);
1507 if (error)
1508 return error;
1509
1510
1511
1512
1513 count = leafhdr.count - leafhdr.stale;
1514 bytes = state->args->geo->blksize -
1515 (state->args->geo->blksize >> 2);
1516
1517 leaf = bp->b_addr;
1518 dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf);
1519 ents = dp->d_ops->leaf_ents_p(leaf);
1520 count += hdr2.count - hdr2.stale;
1521 bytes -= count * sizeof(ents[0]);
1522
1523
1524
1525
1526 if (bytes >= 0)
1527 break;
1528 xfs_trans_brelse(state->args->trans, bp);
1529 }
1530
1531
1532
1533 if (i >= 2) {
1534 *action = 0;
1535 return 0;
1536 }
1537
1538
1539
1540
1541
1542 memcpy(&state->altpath, &state->path, sizeof(state->path));
1543 if (blkno < blk->blkno)
1544 error = xfs_da3_path_shift(state, &state->altpath, forward, 0,
1545 &rval);
1546 else
1547 error = xfs_da3_path_shift(state, &state->path, forward, 0,
1548 &rval);
1549 if (error) {
1550 return error;
1551 }
1552 *action = rval ? 0 : 1;
1553 return 0;
1554}
1555
1556
1557
1558
1559
1560void
1561xfs_dir2_leafn_unbalance(
1562 xfs_da_state_t *state,
1563 xfs_da_state_blk_t *drop_blk,
1564 xfs_da_state_blk_t *save_blk)
1565{
1566 xfs_da_args_t *args;
1567 xfs_dir2_leaf_t *drop_leaf;
1568 xfs_dir2_leaf_t *save_leaf;
1569 struct xfs_dir3_icleaf_hdr savehdr;
1570 struct xfs_dir3_icleaf_hdr drophdr;
1571 struct xfs_dir2_leaf_entry *sents;
1572 struct xfs_dir2_leaf_entry *dents;
1573 struct xfs_inode *dp = state->args->dp;
1574
1575 args = state->args;
1576 ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1577 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1578 drop_leaf = drop_blk->bp->b_addr;
1579 save_leaf = save_blk->bp->b_addr;
1580
1581 dp->d_ops->leaf_hdr_from_disk(&savehdr, save_leaf);
1582 dp->d_ops->leaf_hdr_from_disk(&drophdr, drop_leaf);
1583 sents = dp->d_ops->leaf_ents_p(save_leaf);
1584 dents = dp->d_ops->leaf_ents_p(drop_leaf);
1585
1586
1587
1588
1589
1590 if (drophdr.stale)
1591 xfs_dir3_leaf_compact(args, &drophdr, drop_blk->bp);
1592 if (savehdr.stale)
1593 xfs_dir3_leaf_compact(args, &savehdr, save_blk->bp);
1594
1595
1596
1597
1598 drop_blk->hashval = be32_to_cpu(dents[drophdr.count - 1].hashval);
1599 if (xfs_dir2_leafn_order(dp, save_blk->bp, drop_blk->bp))
1600 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
1601 save_blk->bp, &savehdr, sents, 0,
1602 drophdr.count);
1603 else
1604 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
1605 save_blk->bp, &savehdr, sents,
1606 savehdr.count, drophdr.count);
1607 save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval);
1608
1609
1610 dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr);
1611 dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr);
1612 xfs_dir3_leaf_log_header(args, save_blk->bp);
1613 xfs_dir3_leaf_log_header(args, drop_blk->bp);
1614
1615 xfs_dir3_leaf_check(dp, save_blk->bp);
1616 xfs_dir3_leaf_check(dp, drop_blk->bp);
1617}
1618
1619
1620
1621
1622int
1623xfs_dir2_node_addname(
1624 xfs_da_args_t *args)
1625{
1626 xfs_da_state_blk_t *blk;
1627 int error;
1628 int rval;
1629 xfs_da_state_t *state;
1630
1631 trace_xfs_dir2_node_addname(args);
1632
1633
1634
1635
1636 state = xfs_da_state_alloc();
1637 state->args = args;
1638 state->mp = args->dp->i_mount;
1639
1640
1641
1642
1643 error = xfs_da3_node_lookup_int(state, &rval);
1644 if (error)
1645 rval = error;
1646 if (rval != -ENOENT) {
1647 goto done;
1648 }
1649
1650
1651
1652
1653 rval = xfs_dir2_node_addname_int(args,
1654 state->extravalid ? &state->extrablk : NULL);
1655 if (rval) {
1656 goto done;
1657 }
1658 blk = &state->path.blk[state->path.active - 1];
1659 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
1660
1661
1662
1663 rval = xfs_dir2_leafn_add(blk->bp, args, blk->index);
1664 if (rval == 0) {
1665
1666
1667
1668 if (!(args->op_flags & XFS_DA_OP_JUSTCHECK))
1669 xfs_da3_fixhashpath(state, &state->path);
1670 } else {
1671
1672
1673
1674 if (args->total == 0) {
1675 ASSERT(rval == -ENOSPC);
1676 goto done;
1677 }
1678
1679
1680
1681 rval = xfs_da3_split(state);
1682 }
1683done:
1684 xfs_da_state_free(state);
1685 return rval;
1686}
1687
1688
1689
1690
1691
1692
1693static int
1694xfs_dir2_node_addname_int(
1695 xfs_da_args_t *args,
1696 xfs_da_state_blk_t *fblk)
1697{
1698 xfs_dir2_data_hdr_t *hdr;
1699 xfs_dir2_db_t dbno;
1700 struct xfs_buf *dbp;
1701 xfs_dir2_data_entry_t *dep;
1702 xfs_inode_t *dp;
1703 xfs_dir2_data_unused_t *dup;
1704 int error;
1705 xfs_dir2_db_t fbno;
1706 struct xfs_buf *fbp;
1707 int findex;
1708 xfs_dir2_free_t *free=NULL;
1709 xfs_dir2_db_t ifbno;
1710 xfs_dir2_db_t lastfbno=0;
1711 int length;
1712 int logfree;
1713 xfs_mount_t *mp;
1714 int needlog;
1715 int needscan;
1716 __be16 *tagp;
1717 xfs_trans_t *tp;
1718 __be16 *bests;
1719 struct xfs_dir3_icfree_hdr freehdr;
1720 struct xfs_dir2_data_free *bf;
1721 xfs_dir2_data_aoff_t aoff;
1722
1723 dp = args->dp;
1724 mp = dp->i_mount;
1725 tp = args->trans;
1726 length = dp->d_ops->data_entsize(args->namelen);
1727
1728
1729
1730
1731
1732 if (fblk) {
1733 fbp = fblk->bp;
1734
1735
1736
1737 ifbno = fblk->blkno;
1738 free = fbp->b_addr;
1739 findex = fblk->index;
1740 bests = dp->d_ops->free_bests_p(free);
1741 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1742
1743
1744
1745
1746
1747
1748 if (findex >= 0) {
1749 ASSERT(findex < freehdr.nvalid);
1750 ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
1751 ASSERT(be16_to_cpu(bests[findex]) >= length);
1752 dbno = freehdr.firstdb + findex;
1753 } else {
1754
1755
1756
1757
1758 dbno = -1;
1759 findex = 0;
1760 }
1761 } else {
1762
1763
1764
1765 ifbno = dbno = -1;
1766 fbp = NULL;
1767 findex = 0;
1768 }
1769
1770
1771
1772
1773
1774
1775 if (dbno == -1) {
1776 xfs_fileoff_t fo;
1777
1778 if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK)))
1779 return error;
1780 lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
1781 fbno = ifbno;
1782 }
1783
1784
1785
1786
1787
1788 while (dbno == -1) {
1789
1790
1791
1792 if (fbp == NULL) {
1793
1794
1795
1796
1797 if (++fbno == 0)
1798 fbno = xfs_dir2_byte_to_db(args->geo,
1799 XFS_DIR2_FREE_OFFSET);
1800
1801
1802
1803 if (fbno == ifbno)
1804 fbno++;
1805
1806
1807
1808 if (fbno >= lastfbno)
1809 break;
1810
1811
1812
1813
1814
1815
1816 error = xfs_dir2_free_try_read(tp, dp,
1817 xfs_dir2_db_to_da(args->geo, fbno),
1818 &fbp);
1819 if (error)
1820 return error;
1821 if (!fbp)
1822 continue;
1823 free = fbp->b_addr;
1824 findex = 0;
1825 }
1826
1827
1828
1829
1830
1831
1832
1833
1834 bests = dp->d_ops->free_bests_p(free);
1835 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1836 if (be16_to_cpu(bests[findex]) != NULLDATAOFF &&
1837 be16_to_cpu(bests[findex]) >= length)
1838 dbno = freehdr.firstdb + findex;
1839 else {
1840
1841
1842
1843 if (++findex == freehdr.nvalid) {
1844
1845
1846
1847 xfs_trans_brelse(tp, fbp);
1848 fbp = NULL;
1849 if (fblk && fblk->bp)
1850 fblk->bp = NULL;
1851 }
1852 }
1853 }
1854
1855
1856
1857
1858 if (unlikely(dbno == -1)) {
1859
1860
1861
1862 if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0)
1863 return -ENOSPC;
1864
1865
1866
1867
1868 if (unlikely((error = xfs_dir2_grow_inode(args,
1869 XFS_DIR2_DATA_SPACE,
1870 &dbno)) ||
1871 (error = xfs_dir3_data_init(args, dbno, &dbp))))
1872 return error;
1873
1874
1875
1876
1877 if (fbp)
1878 xfs_trans_brelse(tp, fbp);
1879 if (fblk && fblk->bp)
1880 fblk->bp = NULL;
1881
1882
1883
1884
1885
1886 fbno = dp->d_ops->db_to_fdb(args->geo, dbno);
1887 error = xfs_dir2_free_try_read(tp, dp,
1888 xfs_dir2_db_to_da(args->geo, fbno),
1889 &fbp);
1890 if (error)
1891 return error;
1892
1893
1894
1895
1896
1897 if (!fbp) {
1898 error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
1899 &fbno);
1900 if (error)
1901 return error;
1902
1903 if (dp->d_ops->db_to_fdb(args->geo, dbno) != fbno) {
1904 xfs_alert(mp,
1905"%s: dir ino %llu needed freesp block %lld for data block %lld, got %lld ifbno %llu lastfbno %d",
1906 __func__, (unsigned long long)dp->i_ino,
1907 (long long)dp->d_ops->db_to_fdb(
1908 args->geo, dbno),
1909 (long long)dbno, (long long)fbno,
1910 (unsigned long long)ifbno, lastfbno);
1911 if (fblk) {
1912 xfs_alert(mp,
1913 " fblk "PTR_FMT" blkno %llu index %d magic 0x%x",
1914 fblk,
1915 (unsigned long long)fblk->blkno,
1916 fblk->index,
1917 fblk->magic);
1918 } else {
1919 xfs_alert(mp, " ... fblk is NULL");
1920 }
1921 XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
1922 XFS_ERRLEVEL_LOW, mp);
1923 return -EFSCORRUPTED;
1924 }
1925
1926
1927
1928
1929 error = xfs_dir3_free_get_buf(args, fbno, &fbp);
1930 if (error)
1931 return error;
1932 free = fbp->b_addr;
1933 bests = dp->d_ops->free_bests_p(free);
1934 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1935
1936
1937
1938
1939 freehdr.firstdb =
1940 (fbno - xfs_dir2_byte_to_db(args->geo,
1941 XFS_DIR2_FREE_OFFSET)) *
1942 dp->d_ops->free_max_bests(args->geo);
1943 } else {
1944 free = fbp->b_addr;
1945 bests = dp->d_ops->free_bests_p(free);
1946 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1947 }
1948
1949
1950
1951
1952 findex = dp->d_ops->db_to_fdindex(args->geo, dbno);
1953
1954
1955
1956
1957 if (findex >= freehdr.nvalid) {
1958 ASSERT(findex < dp->d_ops->free_max_bests(args->geo));
1959 freehdr.nvalid = findex + 1;
1960
1961
1962
1963 bests[findex] = cpu_to_be16(NULLDATAOFF);
1964 }
1965
1966
1967
1968
1969 if (bests[findex] == cpu_to_be16(NULLDATAOFF)) {
1970 freehdr.nused++;
1971 dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
1972 xfs_dir2_free_log_header(args, fbp);
1973 }
1974
1975
1976
1977
1978
1979 hdr = dbp->b_addr;
1980 bf = dp->d_ops->data_bestfree_p(hdr);
1981 bests[findex] = bf[0].length;
1982 logfree = 1;
1983 }
1984
1985
1986
1987 else {
1988
1989
1990
1991 if (args->op_flags & XFS_DA_OP_JUSTCHECK)
1992 return 0;
1993
1994
1995
1996
1997 error = xfs_dir3_data_read(tp, dp,
1998 xfs_dir2_db_to_da(args->geo, dbno),
1999 -1, &dbp);
2000 if (error)
2001 return error;
2002 hdr = dbp->b_addr;
2003 bf = dp->d_ops->data_bestfree_p(hdr);
2004 logfree = 0;
2005 }
2006 ASSERT(be16_to_cpu(bf[0].length) >= length);
2007
2008
2009
2010 dup = (xfs_dir2_data_unused_t *)
2011 ((char *)hdr + be16_to_cpu(bf[0].offset));
2012 needscan = needlog = 0;
2013
2014
2015
2016 aoff = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
2017 error = xfs_dir2_data_use_free(args, dbp, dup, aoff, length,
2018 &needlog, &needscan);
2019 if (error) {
2020 xfs_trans_brelse(tp, dbp);
2021 return error;
2022 }
2023
2024
2025
2026 dep = (xfs_dir2_data_entry_t *)dup;
2027 dep->inumber = cpu_to_be64(args->inumber);
2028 dep->namelen = args->namelen;
2029 memcpy(dep->name, args->name, dep->namelen);
2030 dp->d_ops->data_put_ftype(dep, args->filetype);
2031 tagp = dp->d_ops->data_entry_tag_p(dep);
2032 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
2033 xfs_dir2_data_log_entry(args, dbp, dep);
2034
2035
2036
2037 if (needscan)
2038 xfs_dir2_data_freescan(dp, hdr, &needlog);
2039
2040
2041
2042 if (needlog)
2043 xfs_dir2_data_log_header(args, dbp);
2044
2045
2046
2047 bests = dp->d_ops->free_bests_p(free);
2048 if (be16_to_cpu(bests[findex]) != be16_to_cpu(bf[0].length)) {
2049 bests[findex] = bf[0].length;
2050 logfree = 1;
2051 }
2052
2053
2054
2055 if (logfree)
2056 xfs_dir2_free_log_bests(args, fbp, findex, findex);
2057
2058
2059
2060 args->blkno = (xfs_dablk_t)dbno;
2061 args->index = be16_to_cpu(*tagp);
2062 return 0;
2063}
2064
2065
2066
2067
2068
2069
2070int
2071xfs_dir2_node_lookup(
2072 xfs_da_args_t *args)
2073{
2074 int error;
2075 int i;
2076 int rval;
2077 xfs_da_state_t *state;
2078
2079 trace_xfs_dir2_node_lookup(args);
2080
2081
2082
2083
2084 state = xfs_da_state_alloc();
2085 state->args = args;
2086 state->mp = args->dp->i_mount;
2087
2088
2089
2090 error = xfs_da3_node_lookup_int(state, &rval);
2091 if (error)
2092 rval = error;
2093 else if (rval == -ENOENT && args->cmpresult == XFS_CMP_CASE) {
2094
2095 xfs_dir2_data_entry_t *dep;
2096
2097 dep = (xfs_dir2_data_entry_t *)
2098 ((char *)state->extrablk.bp->b_addr +
2099 state->extrablk.index);
2100 rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
2101 }
2102
2103
2104
2105 for (i = 0; i < state->path.active; i++) {
2106 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
2107 state->path.blk[i].bp = NULL;
2108 }
2109
2110
2111
2112 if (state->extravalid && state->extrablk.bp) {
2113 xfs_trans_brelse(args->trans, state->extrablk.bp);
2114 state->extrablk.bp = NULL;
2115 }
2116 xfs_da_state_free(state);
2117 return rval;
2118}
2119
2120
2121
2122
2123int
2124xfs_dir2_node_removename(
2125 struct xfs_da_args *args)
2126{
2127 struct xfs_da_state_blk *blk;
2128 int error;
2129 int rval;
2130 struct xfs_da_state *state;
2131
2132 trace_xfs_dir2_node_removename(args);
2133
2134
2135
2136
2137 state = xfs_da_state_alloc();
2138 state->args = args;
2139 state->mp = args->dp->i_mount;
2140
2141
2142 error = xfs_da3_node_lookup_int(state, &rval);
2143 if (error)
2144 goto out_free;
2145
2146
2147 if (rval != -EEXIST) {
2148 error = rval;
2149 goto out_free;
2150 }
2151
2152 blk = &state->path.blk[state->path.active - 1];
2153 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
2154 ASSERT(state->extravalid);
2155
2156
2157
2158
2159 error = xfs_dir2_leafn_remove(args, blk->bp, blk->index,
2160 &state->extrablk, &rval);
2161 if (error)
2162 goto out_free;
2163
2164
2165
2166 xfs_da3_fixhashpath(state, &state->path);
2167
2168
2169
2170 if (rval && state->path.active > 1)
2171 error = xfs_da3_join(state);
2172
2173
2174
2175 if (!error)
2176 error = xfs_dir2_node_to_leaf(state);
2177out_free:
2178 xfs_da_state_free(state);
2179 return error;
2180}
2181
2182
2183
2184
2185int
2186xfs_dir2_node_replace(
2187 xfs_da_args_t *args)
2188{
2189 xfs_da_state_blk_t *blk;
2190 xfs_dir2_data_hdr_t *hdr;
2191 xfs_dir2_data_entry_t *dep;
2192 int error;
2193 int i;
2194 xfs_ino_t inum;
2195 int ftype;
2196 xfs_dir2_leaf_t *leaf;
2197 xfs_dir2_leaf_entry_t *lep;
2198 int rval;
2199 xfs_da_state_t *state;
2200
2201 trace_xfs_dir2_node_replace(args);
2202
2203
2204
2205
2206 state = xfs_da_state_alloc();
2207 state->args = args;
2208 state->mp = args->dp->i_mount;
2209
2210
2211
2212
2213
2214 inum = args->inumber;
2215 ftype = args->filetype;
2216
2217
2218
2219
2220 error = xfs_da3_node_lookup_int(state, &rval);
2221 if (error) {
2222 rval = error;
2223 }
2224
2225
2226
2227
2228 if (rval == -EEXIST) {
2229 struct xfs_dir2_leaf_entry *ents;
2230
2231
2232
2233 blk = &state->path.blk[state->path.active - 1];
2234 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
2235 leaf = blk->bp->b_addr;
2236 ents = args->dp->d_ops->leaf_ents_p(leaf);
2237 lep = &ents[blk->index];
2238 ASSERT(state->extravalid);
2239
2240
2241
2242 hdr = state->extrablk.bp->b_addr;
2243 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
2244 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
2245 dep = (xfs_dir2_data_entry_t *)
2246 ((char *)hdr +
2247 xfs_dir2_dataptr_to_off(args->geo,
2248 be32_to_cpu(lep->address)));
2249 ASSERT(inum != be64_to_cpu(dep->inumber));
2250
2251
2252
2253 dep->inumber = cpu_to_be64(inum);
2254 args->dp->d_ops->data_put_ftype(dep, ftype);
2255 xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);
2256 rval = 0;
2257 }
2258
2259
2260
2261 else if (state->extravalid) {
2262 xfs_trans_brelse(args->trans, state->extrablk.bp);
2263 state->extrablk.bp = NULL;
2264 }
2265
2266
2267
2268 for (i = 0; i < state->path.active; i++) {
2269 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
2270 state->path.blk[i].bp = NULL;
2271 }
2272 xfs_da_state_free(state);
2273 return rval;
2274}
2275
2276
2277
2278
2279
2280int
2281xfs_dir2_node_trim_free(
2282 xfs_da_args_t *args,
2283 xfs_fileoff_t fo,
2284 int *rvalp)
2285{
2286 struct xfs_buf *bp;
2287 xfs_inode_t *dp;
2288 int error;
2289 xfs_dir2_free_t *free;
2290 xfs_trans_t *tp;
2291 struct xfs_dir3_icfree_hdr freehdr;
2292
2293 dp = args->dp;
2294 tp = args->trans;
2295
2296 *rvalp = 0;
2297
2298
2299
2300
2301 error = xfs_dir2_free_try_read(tp, dp, fo, &bp);
2302 if (error)
2303 return error;
2304
2305
2306
2307
2308 if (!bp)
2309 return 0;
2310 free = bp->b_addr;
2311 dp->d_ops->free_hdr_from_disk(&freehdr, free);
2312
2313
2314
2315
2316 if (freehdr.nused > 0) {
2317 xfs_trans_brelse(tp, bp);
2318 return 0;
2319 }
2320
2321
2322
2323 error = xfs_dir2_shrink_inode(args,
2324 xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo), bp);
2325 if (error) {
2326
2327
2328
2329
2330
2331 ASSERT(error != -ENOSPC);
2332 xfs_trans_brelse(tp, bp);
2333 return error;
2334 }
2335
2336
2337
2338 *rvalp = 1;
2339 return 0;
2340}
2341