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