1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_types.h"
21#include "xfs_bit.h"
22#include "xfs_log.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_ag.h"
26#include "xfs_mount.h"
27#include "xfs_da_btree.h"
28#include "xfs_bmap_btree.h"
29#include "xfs_dinode.h"
30#include "xfs_inode.h"
31#include "xfs_bmap.h"
32#include "xfs_dir2_format.h"
33#include "xfs_dir2_priv.h"
34#include "xfs_error.h"
35#include "xfs_trace.h"
36
37
38
39
40#ifdef DEBUG
41static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp);
42#else
43#define xfs_dir2_leaf_check(dp, bp)
44#endif
45static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp,
46 int *indexp, xfs_dabuf_t **dbpp);
47static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
48 int first, int last);
49static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
50
51
52
53
54
55int
56xfs_dir2_block_to_leaf(
57 xfs_da_args_t *args,
58 xfs_dabuf_t *dbp)
59{
60 __be16 *bestsp;
61 xfs_dablk_t blkno;
62 xfs_dir2_data_hdr_t *hdr;
63 xfs_dir2_leaf_entry_t *blp;
64 xfs_dir2_block_tail_t *btp;
65 xfs_inode_t *dp;
66 int error;
67 xfs_dabuf_t *lbp;
68 xfs_dir2_db_t ldb;
69 xfs_dir2_leaf_t *leaf;
70 xfs_dir2_leaf_tail_t *ltp;
71 xfs_mount_t *mp;
72 int needlog;
73 int needscan;
74 xfs_trans_t *tp;
75
76 trace_xfs_dir2_block_to_leaf(args);
77
78 dp = args->dp;
79 mp = dp->i_mount;
80 tp = args->trans;
81
82
83
84
85
86 if ((error = xfs_da_grow_inode(args, &blkno))) {
87 return error;
88 }
89 ldb = xfs_dir2_da_to_db(mp, blkno);
90 ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp));
91
92
93
94 if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) {
95 return error;
96 }
97 ASSERT(lbp != NULL);
98 leaf = lbp->data;
99 hdr = dbp->data;
100 xfs_dir2_data_check(dp, dbp);
101 btp = xfs_dir2_block_tail_p(mp, hdr);
102 blp = xfs_dir2_block_leaf_p(btp);
103
104
105
106 leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count));
107 leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale));
108
109
110
111
112 memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
113 xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1);
114 needscan = 0;
115 needlog = 1;
116
117
118
119
120 xfs_dir2_data_make_free(tp, dbp,
121 (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
122 (xfs_dir2_data_aoff_t)((char *)hdr + mp->m_dirblksize -
123 (char *)blp),
124 &needlog, &needscan);
125
126
127
128 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
129 if (needscan)
130 xfs_dir2_data_freescan(mp, hdr, &needlog);
131
132
133
134 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
135 ltp->bestcount = cpu_to_be32(1);
136 bestsp = xfs_dir2_leaf_bests_p(ltp);
137 bestsp[0] = hdr->bestfree[0].length;
138
139
140
141 if (needlog)
142 xfs_dir2_data_log_header(tp, dbp);
143 xfs_dir2_leaf_check(dp, lbp);
144 xfs_dir2_data_check(dp, dbp);
145 xfs_dir2_leaf_log_bests(tp, lbp, 0, 0);
146 xfs_da_buf_done(lbp);
147 return 0;
148}
149
150STATIC void
151xfs_dir2_leaf_find_stale(
152 struct xfs_dir2_leaf *leaf,
153 int index,
154 int *lowstale,
155 int *highstale)
156{
157
158
159
160 for (*lowstale = index - 1; *lowstale >= 0; --*lowstale) {
161 if (leaf->ents[*lowstale].address ==
162 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
163 break;
164 }
165
166
167
168
169
170
171 for (*highstale = index;
172 *highstale < be16_to_cpu(leaf->hdr.count);
173 ++*highstale) {
174 if (leaf->ents[*highstale].address ==
175 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
176 break;
177 if (*lowstale >= 0 && index - *lowstale <= *highstale - index)
178 break;
179 }
180}
181
182struct xfs_dir2_leaf_entry *
183xfs_dir2_leaf_find_entry(
184 xfs_dir2_leaf_t *leaf,
185 int index,
186 int compact,
187 int lowstale,
188 int highstale,
189 int *lfloglow,
190 int *lfloghigh)
191{
192 if (!leaf->hdr.stale) {
193 xfs_dir2_leaf_entry_t *lep;
194
195
196
197
198
199
200 lep = &leaf->ents[index];
201 if (index < be16_to_cpu(leaf->hdr.count))
202 memmove(lep + 1, lep,
203 (be16_to_cpu(leaf->hdr.count) - index) *
204 sizeof(*lep));
205
206
207
208
209 *lfloglow = index;
210 *lfloghigh = be16_to_cpu(leaf->hdr.count);
211 be16_add_cpu(&leaf->hdr.count, 1);
212 return lep;
213 }
214
215
216
217
218
219
220
221
222
223
224 if (compact == 0)
225 xfs_dir2_leaf_find_stale(leaf, index, &lowstale, &highstale);
226
227
228
229
230 if (lowstale >= 0 &&
231 (highstale == be16_to_cpu(leaf->hdr.count) ||
232 index - lowstale - 1 < highstale - index)) {
233 ASSERT(index - lowstale - 1 >= 0);
234 ASSERT(leaf->ents[lowstale].address ==
235 cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
236
237
238
239
240
241 if (index - lowstale - 1 > 0) {
242 memmove(&leaf->ents[lowstale],
243 &leaf->ents[lowstale + 1],
244 (index - lowstale - 1) *
245 sizeof(xfs_dir2_leaf_entry_t));
246 }
247 *lfloglow = MIN(lowstale, *lfloglow);
248 *lfloghigh = MAX(index - 1, *lfloghigh);
249 be16_add_cpu(&leaf->hdr.stale, -1);
250 return &leaf->ents[index - 1];
251 }
252
253
254
255
256 ASSERT(highstale - index >= 0);
257 ASSERT(leaf->ents[highstale].address ==
258 cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
259
260
261
262
263
264 if (highstale - index > 0) {
265 memmove(&leaf->ents[index + 1],
266 &leaf->ents[index],
267 (highstale - index) * sizeof(xfs_dir2_leaf_entry_t));
268 }
269 *lfloglow = MIN(index, *lfloglow);
270 *lfloghigh = MAX(highstale, *lfloghigh);
271 be16_add_cpu(&leaf->hdr.stale, -1);
272 return &leaf->ents[index];
273}
274
275
276
277
278int
279xfs_dir2_leaf_addname(
280 xfs_da_args_t *args)
281{
282 __be16 *bestsp;
283 int compact;
284 xfs_dir2_data_hdr_t *hdr;
285 xfs_dabuf_t *dbp;
286 xfs_dir2_data_entry_t *dep;
287 xfs_inode_t *dp;
288 xfs_dir2_data_unused_t *dup;
289 int error;
290 int grown;
291 int highstale;
292 int i;
293 int index;
294 xfs_dabuf_t *lbp;
295 xfs_dir2_leaf_t *leaf;
296 int length;
297 xfs_dir2_leaf_entry_t *lep;
298 int lfloglow;
299 int lfloghigh;
300 int lowstale;
301 xfs_dir2_leaf_tail_t *ltp;
302 xfs_mount_t *mp;
303 int needbytes;
304 int needlog;
305 int needscan;
306 __be16 *tagp;
307 xfs_trans_t *tp;
308 xfs_dir2_db_t use_block;
309
310 trace_xfs_dir2_leaf_addname(args);
311
312 dp = args->dp;
313 tp = args->trans;
314 mp = dp->i_mount;
315
316
317
318 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
319 XFS_DATA_FORK);
320 if (error) {
321 return error;
322 }
323 ASSERT(lbp != NULL);
324
325
326
327
328
329
330 index = xfs_dir2_leaf_search_hash(args, lbp);
331 leaf = lbp->data;
332 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
333 bestsp = xfs_dir2_leaf_bests_p(ltp);
334 length = xfs_dir2_data_entsize(args->namelen);
335
336
337
338
339
340
341 for (use_block = -1, lep = &leaf->ents[index];
342 index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval;
343 index++, lep++) {
344 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
345 continue;
346 i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
347 ASSERT(i < be32_to_cpu(ltp->bestcount));
348 ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF));
349 if (be16_to_cpu(bestsp[i]) >= length) {
350 use_block = i;
351 break;
352 }
353 }
354
355
356
357 if (use_block == -1) {
358 for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) {
359
360
361
362 if (bestsp[i] == cpu_to_be16(NULLDATAOFF) &&
363 use_block == -1)
364 use_block = i;
365 else if (be16_to_cpu(bestsp[i]) >= length) {
366 use_block = i;
367 break;
368 }
369 }
370 }
371
372
373
374 needbytes = 0;
375 if (!leaf->hdr.stale)
376 needbytes += sizeof(xfs_dir2_leaf_entry_t);
377 if (use_block == -1)
378 needbytes += sizeof(xfs_dir2_data_off_t);
379
380
381
382
383
384 if (use_block != -1 && bestsp[use_block] == cpu_to_be16(NULLDATAOFF))
385 use_block = -1;
386
387
388
389
390 if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <
391 needbytes && be16_to_cpu(leaf->hdr.stale) > 1) {
392 compact = 1;
393 }
394
395
396
397
398 else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(
399 leaf->hdr.count)] < needbytes) {
400
401
402
403 if ((args->op_flags & XFS_DA_OP_JUSTCHECK) ||
404 args->total == 0) {
405 xfs_da_brelse(tp, lbp);
406 return XFS_ERROR(ENOSPC);
407 }
408
409
410
411 error = xfs_dir2_leaf_to_node(args, lbp);
412 xfs_da_buf_done(lbp);
413 if (error)
414 return error;
415
416
417
418 return xfs_dir2_node_addname(args);
419 }
420
421
422
423 else
424 compact = 0;
425
426
427
428
429 if (args->op_flags & XFS_DA_OP_JUSTCHECK) {
430 xfs_da_brelse(tp, lbp);
431 return use_block == -1 ? XFS_ERROR(ENOSPC) : 0;
432 }
433
434
435
436
437 if (args->total == 0 && use_block == -1) {
438 xfs_da_brelse(tp, lbp);
439 return XFS_ERROR(ENOSPC);
440 }
441
442
443
444
445
446
447 if (compact) {
448 xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale,
449 &lfloglow, &lfloghigh);
450 }
451
452
453
454
455 else if (be16_to_cpu(leaf->hdr.stale)) {
456 lfloglow = be16_to_cpu(leaf->hdr.count);
457 lfloghigh = -1;
458 }
459
460
461
462
463 if (use_block == -1) {
464
465
466
467 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE,
468 &use_block))) {
469 xfs_da_brelse(tp, lbp);
470 return error;
471 }
472
473
474
475 if ((error = xfs_dir2_data_init(args, use_block, &dbp))) {
476 xfs_da_brelse(tp, lbp);
477 return error;
478 }
479
480
481
482
483 if (use_block >= be32_to_cpu(ltp->bestcount)) {
484 bestsp--;
485 memmove(&bestsp[0], &bestsp[1],
486 be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
487 be32_add_cpu(<p->bestcount, 1);
488 xfs_dir2_leaf_log_tail(tp, lbp);
489 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
490 }
491
492
493
494 else
495 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
496 hdr = dbp->data;
497 bestsp[use_block] = hdr->bestfree[0].length;
498 grown = 1;
499 }
500
501
502
503
504 else {
505 if ((error =
506 xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block),
507 -1, &dbp, XFS_DATA_FORK))) {
508 xfs_da_brelse(tp, lbp);
509 return error;
510 }
511 hdr = dbp->data;
512 grown = 0;
513 }
514 xfs_dir2_data_check(dp, dbp);
515
516
517
518 dup = (xfs_dir2_data_unused_t *)
519 ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset));
520 ASSERT(be16_to_cpu(dup->length) >= length);
521 needscan = needlog = 0;
522
523
524
525 xfs_dir2_data_use_free(tp, dbp, dup,
526 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
527 &needlog, &needscan);
528
529
530
531 dep = (xfs_dir2_data_entry_t *)dup;
532 dep->inumber = cpu_to_be64(args->inumber);
533 dep->namelen = args->namelen;
534 memcpy(dep->name, args->name, dep->namelen);
535 tagp = xfs_dir2_data_entry_tag_p(dep);
536 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
537
538
539
540 if (needscan)
541 xfs_dir2_data_freescan(mp, hdr, &needlog);
542
543
544
545 if (needlog)
546 xfs_dir2_data_log_header(tp, dbp);
547 xfs_dir2_data_log_entry(tp, dbp, dep);
548
549
550
551
552 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(hdr->bestfree[0].length)) {
553 bestsp[use_block] = hdr->bestfree[0].length;
554 if (!grown)
555 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
556 }
557
558 lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
559 highstale, &lfloglow, &lfloghigh);
560
561
562
563
564 lep->hashval = cpu_to_be32(args->hashval);
565 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, use_block,
566 be16_to_cpu(*tagp)));
567
568
569
570 xfs_dir2_leaf_log_header(tp, lbp);
571 xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh);
572 xfs_dir2_leaf_check(dp, lbp);
573 xfs_da_buf_done(lbp);
574 xfs_dir2_data_check(dp, dbp);
575 xfs_da_buf_done(dbp);
576 return 0;
577}
578
579#ifdef DEBUG
580
581
582
583
584STATIC void
585xfs_dir2_leaf_check(
586 xfs_inode_t *dp,
587 xfs_dabuf_t *bp)
588{
589 int i;
590 xfs_dir2_leaf_t *leaf;
591 xfs_dir2_leaf_tail_t *ltp;
592 xfs_mount_t *mp;
593 int stale;
594
595 leaf = bp->data;
596 mp = dp->i_mount;
597 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
598
599
600
601
602
603 ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp));
604 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
605
606
607
608 ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <=
609 (char *)xfs_dir2_leaf_bests_p(ltp));
610
611
612
613 for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
614 if (i + 1 < be16_to_cpu(leaf->hdr.count))
615 ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
616 be32_to_cpu(leaf->ents[i + 1].hashval));
617 if (leaf->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
618 stale++;
619 }
620 ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
621}
622#endif
623
624
625
626
627
628void
629xfs_dir2_leaf_compact(
630 xfs_da_args_t *args,
631 xfs_dabuf_t *bp)
632{
633 int from;
634 xfs_dir2_leaf_t *leaf;
635 int loglow;
636 int to;
637
638 leaf = bp->data;
639 if (!leaf->hdr.stale) {
640 return;
641 }
642
643
644
645 for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) {
646 if (leaf->ents[from].address ==
647 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
648 continue;
649
650
651
652 if (from > to) {
653 if (loglow == -1)
654 loglow = to;
655 leaf->ents[to] = leaf->ents[from];
656 }
657 to++;
658 }
659
660
661
662 ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to);
663 be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
664 leaf->hdr.stale = 0;
665 xfs_dir2_leaf_log_header(args->trans, bp);
666 if (loglow != -1)
667 xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1);
668}
669
670
671
672
673
674
675
676
677
678void
679xfs_dir2_leaf_compact_x1(
680 xfs_dabuf_t *bp,
681 int *indexp,
682 int *lowstalep,
683 int *highstalep,
684 int *lowlogp,
685 int *highlogp)
686{
687 int from;
688 int highstale;
689 int index;
690 int keepstale;
691 xfs_dir2_leaf_t *leaf;
692 int lowstale;
693 int newindex=0;
694 int to;
695
696 leaf = bp->data;
697 ASSERT(be16_to_cpu(leaf->hdr.stale) > 1);
698 index = *indexp;
699
700 xfs_dir2_leaf_find_stale(leaf, index, &lowstale, &highstale);
701
702
703
704
705 if (lowstale >= 0 &&
706 (highstale == be16_to_cpu(leaf->hdr.count) ||
707 index - lowstale <= highstale - index))
708 keepstale = lowstale;
709 else
710 keepstale = highstale;
711
712
713
714
715 for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) {
716
717
718
719 if (index == from)
720 newindex = to;
721 if (from != keepstale &&
722 leaf->ents[from].address ==
723 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) {
724 if (from == to)
725 *lowlogp = to;
726 continue;
727 }
728
729
730
731 if (from == keepstale)
732 lowstale = highstale = to;
733
734
735
736 if (from > to)
737 leaf->ents[to] = leaf->ents[from];
738 to++;
739 }
740 ASSERT(from > to);
741
742
743
744
745 if (index == from)
746 newindex = to;
747 *indexp = newindex;
748
749
750
751 be16_add_cpu(&leaf->hdr.count, -(from - to));
752 leaf->hdr.stale = cpu_to_be16(1);
753
754
755
756
757 if (lowstale >= newindex)
758 lowstale = -1;
759 else
760 highstale = be16_to_cpu(leaf->hdr.count);
761 *highlogp = be16_to_cpu(leaf->hdr.count) - 1;
762 *lowstalep = lowstale;
763 *highstalep = highstale;
764}
765
766
767
768
769
770int
771xfs_dir2_leaf_getdents(
772 xfs_inode_t *dp,
773 void *dirent,
774 size_t bufsize,
775 xfs_off_t *offset,
776 filldir_t filldir)
777{
778 xfs_dabuf_t *bp;
779 int byteoff;
780 xfs_dir2_db_t curdb;
781 xfs_dir2_off_t curoff;
782 xfs_dir2_data_hdr_t *hdr;
783 xfs_dir2_data_entry_t *dep;
784 xfs_dir2_data_unused_t *dup;
785 int error = 0;
786 int i;
787 int j;
788 int length;
789 xfs_bmbt_irec_t *map;
790 xfs_extlen_t map_blocks;
791 xfs_dablk_t map_off;
792 int map_size;
793 int map_valid;
794 xfs_mount_t *mp;
795 xfs_dir2_off_t newoff;
796 int nmap;
797 char *ptr = NULL;
798 int ra_current;
799 int ra_index;
800 int ra_offset;
801 int ra_want;
802
803
804
805
806
807 if (*offset >= XFS_DIR2_MAX_DATAPTR)
808 return 0;
809
810 mp = dp->i_mount;
811
812
813
814
815
816
817 map_size = howmany(bufsize + mp->m_dirblksize, mp->m_sb.sb_blocksize);
818 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP);
819 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0;
820 bp = NULL;
821
822
823
824
825
826 curoff = xfs_dir2_dataptr_to_byte(mp, *offset);
827
828
829
830
831
832 map_off = xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, curoff));
833
834
835
836
837 while (curoff < XFS_DIR2_LEAF_OFFSET) {
838
839
840
841
842 if (!bp || ptr >= (char *)bp->data + mp->m_dirblksize) {
843
844
845
846
847 if (bp) {
848 xfs_da_brelse(NULL, bp);
849 bp = NULL;
850 map_blocks -= mp->m_dirblkfsbs;
851
852
853
854
855 for (i = mp->m_dirblkfsbs; i > 0; ) {
856 j = MIN((int)map->br_blockcount, i);
857 map->br_blockcount -= j;
858 map->br_startblock += j;
859 map->br_startoff += j;
860
861
862
863
864 if (!map->br_blockcount && --map_valid)
865 memmove(&map[0], &map[1],
866 sizeof(map[0]) *
867 map_valid);
868 i -= j;
869 }
870 }
871
872
873
874 ra_want = howmany(bufsize + mp->m_dirblksize,
875 mp->m_sb.sb_blocksize) - 1;
876 ASSERT(ra_want >= 0);
877
878
879
880
881
882 if (1 + ra_want > map_blocks &&
883 map_off <
884 xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) {
885
886
887
888
889 nmap = map_size - map_valid;
890 error = xfs_bmapi_read(dp, map_off,
891 xfs_dir2_byte_to_da(mp,
892 XFS_DIR2_LEAF_OFFSET) - map_off,
893 &map[map_valid], &nmap, 0);
894
895
896
897
898
899
900
901 if (error)
902 break;
903
904
905
906
907
908
909 if (nmap == map_size - map_valid)
910 map_off =
911 map[map_valid + nmap - 1].br_startoff +
912 map[map_valid + nmap - 1].br_blockcount;
913 else
914 map_off =
915 xfs_dir2_byte_to_da(mp,
916 XFS_DIR2_LEAF_OFFSET);
917
918
919
920
921 for (i = map_valid; i < map_valid + nmap; ) {
922 if (map[i].br_startblock ==
923 HOLESTARTBLOCK) {
924 nmap--;
925 length = map_valid + nmap - i;
926 if (length)
927 memmove(&map[i],
928 &map[i + 1],
929 sizeof(map[i]) *
930 length);
931 } else {
932 map_blocks +=
933 map[i].br_blockcount;
934 i++;
935 }
936 }
937 map_valid += nmap;
938 }
939
940
941
942 if (!map_valid) {
943 curoff = xfs_dir2_da_to_byte(mp, map_off);
944 break;
945 }
946
947
948
949
950 curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
951 error = xfs_da_read_buf(NULL, dp, map->br_startoff,
952 map->br_blockcount >= mp->m_dirblkfsbs ?
953 XFS_FSB_TO_DADDR(mp, map->br_startblock) :
954 -1,
955 &bp, XFS_DATA_FORK);
956
957
958
959
960 if (error)
961 break;
962
963
964
965
966 if (ra_current)
967 ra_current -= mp->m_dirblkfsbs;
968
969
970
971 for (ra_index = ra_offset = i = 0;
972 ra_want > ra_current && i < map_blocks;
973 i += mp->m_dirblkfsbs) {
974 ASSERT(ra_index < map_valid);
975
976
977
978 if (i > ra_current &&
979 map[ra_index].br_blockcount >=
980 mp->m_dirblkfsbs) {
981 xfs_buf_readahead(mp->m_ddev_targp,
982 XFS_FSB_TO_DADDR(mp,
983 map[ra_index].br_startblock +
984 ra_offset),
985 (int)BTOBB(mp->m_dirblksize));
986 ra_current = i;
987 }
988
989
990
991
992
993 else if (i > ra_current) {
994 (void)xfs_da_reada_buf(NULL, dp,
995 map[ra_index].br_startoff +
996 ra_offset, XFS_DATA_FORK);
997 ra_current = i;
998 }
999
1000
1001
1002 for (j = 0; j < mp->m_dirblkfsbs; j++) {
1003
1004
1005
1006
1007 length = MIN(mp->m_dirblkfsbs,
1008 (int)(map[ra_index].br_blockcount -
1009 ra_offset));
1010 j += length;
1011 ra_offset += length;
1012
1013
1014
1015
1016 if (ra_offset ==
1017 map[ra_index].br_blockcount) {
1018 ra_offset = 0;
1019 ra_index++;
1020 }
1021 }
1022 }
1023
1024
1025
1026 newoff = xfs_dir2_db_off_to_byte(mp, curdb, 0);
1027
1028
1029
1030 if (curoff < newoff)
1031 curoff = newoff;
1032
1033
1034
1035 else if (curoff > newoff)
1036 ASSERT(xfs_dir2_byte_to_db(mp, curoff) ==
1037 curdb);
1038 hdr = bp->data;
1039 xfs_dir2_data_check(dp, bp);
1040
1041
1042
1043 ptr = (char *)(hdr + 1);
1044 byteoff = xfs_dir2_byte_to_off(mp, curoff);
1045
1046
1047
1048 if (byteoff == 0)
1049 curoff += (uint)sizeof(*hdr);
1050
1051
1052
1053 else {
1054 while ((char *)ptr - (char *)hdr < byteoff) {
1055 dup = (xfs_dir2_data_unused_t *)ptr;
1056
1057 if (be16_to_cpu(dup->freetag)
1058 == XFS_DIR2_DATA_FREE_TAG) {
1059
1060 length = be16_to_cpu(dup->length);
1061 ptr += length;
1062 continue;
1063 }
1064 dep = (xfs_dir2_data_entry_t *)ptr;
1065 length =
1066 xfs_dir2_data_entsize(dep->namelen);
1067 ptr += length;
1068 }
1069
1070
1071
1072 curoff =
1073 xfs_dir2_db_off_to_byte(mp,
1074 xfs_dir2_byte_to_db(mp, curoff),
1075 (char *)ptr - (char *)hdr);
1076 if (ptr >= (char *)hdr + mp->m_dirblksize) {
1077 continue;
1078 }
1079 }
1080 }
1081
1082
1083
1084
1085 dup = (xfs_dir2_data_unused_t *)ptr;
1086
1087
1088
1089 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
1090 length = be16_to_cpu(dup->length);
1091 ptr += length;
1092 curoff += length;
1093 continue;
1094 }
1095
1096 dep = (xfs_dir2_data_entry_t *)ptr;
1097 length = xfs_dir2_data_entsize(dep->namelen);
1098
1099 if (filldir(dirent, (char *)dep->name, dep->namelen,
1100 xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff,
1101 be64_to_cpu(dep->inumber), DT_UNKNOWN))
1102 break;
1103
1104
1105
1106
1107 ptr += length;
1108 curoff += length;
1109
1110 bufsize = bufsize > length ? bufsize - length : 0;
1111 }
1112
1113
1114
1115
1116 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
1117 *offset = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
1118 else
1119 *offset = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
1120 kmem_free(map);
1121 if (bp)
1122 xfs_da_brelse(NULL, bp);
1123 return error;
1124}
1125
1126
1127
1128
1129int
1130xfs_dir2_leaf_init(
1131 xfs_da_args_t *args,
1132 xfs_dir2_db_t bno,
1133 xfs_dabuf_t **bpp,
1134 int magic)
1135{
1136 xfs_dabuf_t *bp;
1137 xfs_inode_t *dp;
1138 int error;
1139 xfs_dir2_leaf_t *leaf;
1140 xfs_dir2_leaf_tail_t *ltp;
1141 xfs_mount_t *mp;
1142 xfs_trans_t *tp;
1143
1144 dp = args->dp;
1145 ASSERT(dp != NULL);
1146 tp = args->trans;
1147 mp = dp->i_mount;
1148 ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) &&
1149 bno < XFS_DIR2_FREE_FIRSTDB(mp));
1150
1151
1152
1153 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp,
1154 XFS_DATA_FORK);
1155 if (error) {
1156 return error;
1157 }
1158 ASSERT(bp != NULL);
1159 leaf = bp->data;
1160
1161
1162
1163 leaf->hdr.info.magic = cpu_to_be16(magic);
1164 leaf->hdr.info.forw = 0;
1165 leaf->hdr.info.back = 0;
1166 leaf->hdr.count = 0;
1167 leaf->hdr.stale = 0;
1168 xfs_dir2_leaf_log_header(tp, bp);
1169
1170
1171
1172
1173
1174 if (magic == XFS_DIR2_LEAF1_MAGIC) {
1175 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1176 ltp->bestcount = 0;
1177 xfs_dir2_leaf_log_tail(tp, bp);
1178 }
1179 *bpp = bp;
1180 return 0;
1181}
1182
1183
1184
1185
1186static void
1187xfs_dir2_leaf_log_bests(
1188 xfs_trans_t *tp,
1189 xfs_dabuf_t *bp,
1190 int first,
1191 int last)
1192{
1193 __be16 *firstb;
1194 __be16 *lastb;
1195 xfs_dir2_leaf_t *leaf;
1196 xfs_dir2_leaf_tail_t *ltp;
1197
1198 leaf = bp->data;
1199 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
1200 ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf);
1201 firstb = xfs_dir2_leaf_bests_p(ltp) + first;
1202 lastb = xfs_dir2_leaf_bests_p(ltp) + last;
1203 xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf),
1204 (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
1205}
1206
1207
1208
1209
1210void
1211xfs_dir2_leaf_log_ents(
1212 xfs_trans_t *tp,
1213 xfs_dabuf_t *bp,
1214 int first,
1215 int last)
1216{
1217 xfs_dir2_leaf_entry_t *firstlep;
1218 xfs_dir2_leaf_entry_t *lastlep;
1219 xfs_dir2_leaf_t *leaf;
1220
1221 leaf = bp->data;
1222 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1223 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1224 firstlep = &leaf->ents[first];
1225 lastlep = &leaf->ents[last];
1226 xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
1227 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
1228}
1229
1230
1231
1232
1233void
1234xfs_dir2_leaf_log_header(
1235 xfs_trans_t *tp,
1236 xfs_dabuf_t *bp)
1237{
1238 xfs_dir2_leaf_t *leaf;
1239
1240 leaf = bp->data;
1241 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1242 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1243 xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
1244 (uint)(sizeof(leaf->hdr) - 1));
1245}
1246
1247
1248
1249
1250STATIC void
1251xfs_dir2_leaf_log_tail(
1252 xfs_trans_t *tp,
1253 xfs_dabuf_t *bp)
1254{
1255 xfs_dir2_leaf_t *leaf;
1256 xfs_dir2_leaf_tail_t *ltp;
1257 xfs_mount_t *mp;
1258
1259 mp = tp->t_mountp;
1260 leaf = bp->data;
1261 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
1262 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1263 xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
1264 (uint)(mp->m_dirblksize - 1));
1265}
1266
1267
1268
1269
1270
1271
1272int
1273xfs_dir2_leaf_lookup(
1274 xfs_da_args_t *args)
1275{
1276 xfs_dabuf_t *dbp;
1277 xfs_dir2_data_entry_t *dep;
1278 xfs_inode_t *dp;
1279 int error;
1280 int index;
1281 xfs_dabuf_t *lbp;
1282 xfs_dir2_leaf_t *leaf;
1283 xfs_dir2_leaf_entry_t *lep;
1284 xfs_trans_t *tp;
1285
1286 trace_xfs_dir2_leaf_lookup(args);
1287
1288
1289
1290
1291 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
1292 return error;
1293 }
1294 tp = args->trans;
1295 dp = args->dp;
1296 xfs_dir2_leaf_check(dp, lbp);
1297 leaf = lbp->data;
1298
1299
1300
1301 lep = &leaf->ents[index];
1302
1303
1304
1305 dep = (xfs_dir2_data_entry_t *)
1306 ((char *)dbp->data +
1307 xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address)));
1308
1309
1310
1311 args->inumber = be64_to_cpu(dep->inumber);
1312 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
1313 xfs_da_brelse(tp, dbp);
1314 xfs_da_brelse(tp, lbp);
1315 return XFS_ERROR(error);
1316}
1317
1318
1319
1320
1321
1322
1323
1324static int
1325xfs_dir2_leaf_lookup_int(
1326 xfs_da_args_t *args,
1327 xfs_dabuf_t **lbpp,
1328 int *indexp,
1329 xfs_dabuf_t **dbpp)
1330{
1331 xfs_dir2_db_t curdb = -1;
1332 xfs_dabuf_t *dbp = NULL;
1333 xfs_dir2_data_entry_t *dep;
1334 xfs_inode_t *dp;
1335 int error;
1336 int index;
1337 xfs_dabuf_t *lbp;
1338 xfs_dir2_leaf_entry_t *lep;
1339 xfs_dir2_leaf_t *leaf;
1340 xfs_mount_t *mp;
1341 xfs_dir2_db_t newdb;
1342 xfs_trans_t *tp;
1343 xfs_dir2_db_t cidb = -1;
1344 enum xfs_dacmp cmp;
1345
1346 dp = args->dp;
1347 tp = args->trans;
1348 mp = dp->i_mount;
1349
1350
1351
1352 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
1353 XFS_DATA_FORK);
1354 if (error)
1355 return error;
1356 *lbpp = lbp;
1357 leaf = lbp->data;
1358 xfs_dir2_leaf_check(dp, lbp);
1359
1360
1361
1362 index = xfs_dir2_leaf_search_hash(args, lbp);
1363
1364
1365
1366
1367 for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) &&
1368 be32_to_cpu(lep->hashval) == args->hashval;
1369 lep++, index++) {
1370
1371
1372
1373 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
1374 continue;
1375
1376
1377
1378 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
1379
1380
1381
1382
1383 if (newdb != curdb) {
1384 if (dbp)
1385 xfs_da_brelse(tp, dbp);
1386 error = xfs_da_read_buf(tp, dp,
1387 xfs_dir2_db_to_da(mp, newdb),
1388 -1, &dbp, XFS_DATA_FORK);
1389 if (error) {
1390 xfs_da_brelse(tp, lbp);
1391 return error;
1392 }
1393 xfs_dir2_data_check(dp, dbp);
1394 curdb = newdb;
1395 }
1396
1397
1398
1399 dep = (xfs_dir2_data_entry_t *)((char *)dbp->data +
1400 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
1401
1402
1403
1404
1405
1406 cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen);
1407 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
1408 args->cmpresult = cmp;
1409 *indexp = index;
1410
1411 if (cmp == XFS_CMP_EXACT) {
1412 *dbpp = dbp;
1413 return 0;
1414 }
1415 cidb = curdb;
1416 }
1417 }
1418 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT);
1419
1420
1421
1422
1423
1424 if (args->cmpresult == XFS_CMP_CASE) {
1425 ASSERT(cidb != -1);
1426 if (cidb != curdb) {
1427 xfs_da_brelse(tp, dbp);
1428 error = xfs_da_read_buf(tp, dp,
1429 xfs_dir2_db_to_da(mp, cidb),
1430 -1, &dbp, XFS_DATA_FORK);
1431 if (error) {
1432 xfs_da_brelse(tp, lbp);
1433 return error;
1434 }
1435 }
1436 *dbpp = dbp;
1437 return 0;
1438 }
1439
1440
1441
1442 ASSERT(cidb == -1);
1443 if (dbp)
1444 xfs_da_brelse(tp, dbp);
1445 xfs_da_brelse(tp, lbp);
1446 return XFS_ERROR(ENOENT);
1447}
1448
1449
1450
1451
1452int
1453xfs_dir2_leaf_removename(
1454 xfs_da_args_t *args)
1455{
1456 __be16 *bestsp;
1457 xfs_dir2_data_hdr_t *hdr;
1458 xfs_dir2_db_t db;
1459 xfs_dabuf_t *dbp;
1460 xfs_dir2_data_entry_t *dep;
1461 xfs_inode_t *dp;
1462 int error;
1463 xfs_dir2_db_t i;
1464 int index;
1465 xfs_dabuf_t *lbp;
1466 xfs_dir2_leaf_t *leaf;
1467 xfs_dir2_leaf_entry_t *lep;
1468 xfs_dir2_leaf_tail_t *ltp;
1469 xfs_mount_t *mp;
1470 int needlog;
1471 int needscan;
1472 xfs_dir2_data_off_t oldbest;
1473 xfs_trans_t *tp;
1474
1475 trace_xfs_dir2_leaf_removename(args);
1476
1477
1478
1479
1480 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
1481 return error;
1482 }
1483 dp = args->dp;
1484 tp = args->trans;
1485 mp = dp->i_mount;
1486 leaf = lbp->data;
1487 hdr = dbp->data;
1488 xfs_dir2_data_check(dp, dbp);
1489
1490
1491
1492 lep = &leaf->ents[index];
1493 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
1494 dep = (xfs_dir2_data_entry_t *)
1495 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
1496 needscan = needlog = 0;
1497 oldbest = be16_to_cpu(hdr->bestfree[0].length);
1498 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1499 bestsp = xfs_dir2_leaf_bests_p(ltp);
1500 ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
1501
1502
1503
1504 xfs_dir2_data_make_free(tp, dbp,
1505 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
1506 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
1507
1508
1509
1510 be16_add_cpu(&leaf->hdr.stale, 1);
1511 xfs_dir2_leaf_log_header(tp, lbp);
1512 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1513 xfs_dir2_leaf_log_ents(tp, lbp, index, index);
1514
1515
1516
1517
1518 if (needscan)
1519 xfs_dir2_data_freescan(mp, hdr, &needlog);
1520 if (needlog)
1521 xfs_dir2_data_log_header(tp, dbp);
1522
1523
1524
1525
1526 if (be16_to_cpu(hdr->bestfree[0].length) != oldbest) {
1527 bestsp[db] = hdr->bestfree[0].length;
1528 xfs_dir2_leaf_log_bests(tp, lbp, db, db);
1529 }
1530 xfs_dir2_data_check(dp, dbp);
1531
1532
1533
1534 if (be16_to_cpu(hdr->bestfree[0].length) ==
1535 mp->m_dirblksize - (uint)sizeof(*hdr)) {
1536 ASSERT(db != mp->m_dirdatablk);
1537 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
1538
1539
1540
1541
1542
1543
1544 if (error == ENOSPC && args->total == 0) {
1545 xfs_da_buf_done(dbp);
1546 error = 0;
1547 }
1548 xfs_dir2_leaf_check(dp, lbp);
1549 xfs_da_buf_done(lbp);
1550 return error;
1551 }
1552 dbp = NULL;
1553
1554
1555
1556
1557 if (db == be32_to_cpu(ltp->bestcount) - 1) {
1558
1559
1560
1561 for (i = db - 1; i > 0; i--) {
1562 if (bestsp[i] != cpu_to_be16(NULLDATAOFF))
1563 break;
1564 }
1565
1566
1567
1568
1569 memmove(&bestsp[db - i], bestsp,
1570 (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
1571 be32_add_cpu(<p->bestcount, -(db - i));
1572 xfs_dir2_leaf_log_tail(tp, lbp);
1573 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1574 } else
1575 bestsp[db] = cpu_to_be16(NULLDATAOFF);
1576 }
1577
1578
1579
1580 else if (db != mp->m_dirdatablk && dbp != NULL) {
1581 xfs_da_buf_done(dbp);
1582 dbp = NULL;
1583 }
1584 xfs_dir2_leaf_check(dp, lbp);
1585
1586
1587
1588 return xfs_dir2_leaf_to_block(args, lbp, dbp);
1589}
1590
1591
1592
1593
1594int
1595xfs_dir2_leaf_replace(
1596 xfs_da_args_t *args)
1597{
1598 xfs_dabuf_t *dbp;
1599 xfs_dir2_data_entry_t *dep;
1600 xfs_inode_t *dp;
1601 int error;
1602 int index;
1603 xfs_dabuf_t *lbp;
1604 xfs_dir2_leaf_t *leaf;
1605 xfs_dir2_leaf_entry_t *lep;
1606 xfs_trans_t *tp;
1607
1608 trace_xfs_dir2_leaf_replace(args);
1609
1610
1611
1612
1613 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
1614 return error;
1615 }
1616 dp = args->dp;
1617 leaf = lbp->data;
1618
1619
1620
1621 lep = &leaf->ents[index];
1622
1623
1624
1625 dep = (xfs_dir2_data_entry_t *)
1626 ((char *)dbp->data +
1627 xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address)));
1628 ASSERT(args->inumber != be64_to_cpu(dep->inumber));
1629
1630
1631
1632 dep->inumber = cpu_to_be64(args->inumber);
1633 tp = args->trans;
1634 xfs_dir2_data_log_entry(tp, dbp, dep);
1635 xfs_da_buf_done(dbp);
1636 xfs_dir2_leaf_check(dp, lbp);
1637 xfs_da_brelse(tp, lbp);
1638 return 0;
1639}
1640
1641
1642
1643
1644
1645
1646int
1647xfs_dir2_leaf_search_hash(
1648 xfs_da_args_t *args,
1649 xfs_dabuf_t *lbp)
1650{
1651 xfs_dahash_t hash=0;
1652 xfs_dahash_t hashwant;
1653 int high;
1654 int low;
1655 xfs_dir2_leaf_t *leaf;
1656 xfs_dir2_leaf_entry_t *lep;
1657 int mid=0;
1658
1659 leaf = lbp->data;
1660#ifndef __KERNEL__
1661 if (!leaf->hdr.count)
1662 return 0;
1663#endif
1664
1665
1666
1667
1668 for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1,
1669 hashwant = args->hashval;
1670 low <= high; ) {
1671 mid = (low + high) >> 1;
1672 if ((hash = be32_to_cpu(lep[mid].hashval)) == hashwant)
1673 break;
1674 if (hash < hashwant)
1675 low = mid + 1;
1676 else
1677 high = mid - 1;
1678 }
1679
1680
1681
1682 if (hash == hashwant) {
1683 while (mid > 0 && be32_to_cpu(lep[mid - 1].hashval) == hashwant) {
1684 mid--;
1685 }
1686 }
1687
1688
1689
1690 else if (hash < hashwant)
1691 mid++;
1692 return mid;
1693}
1694
1695
1696
1697
1698
1699int
1700xfs_dir2_leaf_trim_data(
1701 xfs_da_args_t *args,
1702 xfs_dabuf_t *lbp,
1703 xfs_dir2_db_t db)
1704{
1705 __be16 *bestsp;
1706 xfs_dabuf_t *dbp;
1707 xfs_inode_t *dp;
1708 int error;
1709 xfs_dir2_leaf_t *leaf;
1710 xfs_dir2_leaf_tail_t *ltp;
1711 xfs_mount_t *mp;
1712 xfs_trans_t *tp;
1713
1714 dp = args->dp;
1715 mp = dp->i_mount;
1716 tp = args->trans;
1717
1718
1719
1720 if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp,
1721 XFS_DATA_FORK))) {
1722 return error;
1723 }
1724
1725 leaf = lbp->data;
1726 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1727
1728#ifdef DEBUG
1729{
1730 struct xfs_dir2_data_hdr *hdr = dbp->data;
1731
1732 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC));
1733 ASSERT(be16_to_cpu(hdr->bestfree[0].length) ==
1734 mp->m_dirblksize - (uint)sizeof(*hdr));
1735 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
1736}
1737#endif
1738
1739
1740
1741
1742 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
1743 ASSERT(error != ENOSPC);
1744 xfs_da_brelse(tp, dbp);
1745 return error;
1746 }
1747
1748
1749
1750 bestsp = xfs_dir2_leaf_bests_p(ltp);
1751 be32_add_cpu(<p->bestcount, -1);
1752 memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
1753 xfs_dir2_leaf_log_tail(tp, lbp);
1754 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1755 return 0;
1756}
1757
1758static inline size_t
1759xfs_dir2_leaf_size(
1760 struct xfs_dir2_leaf_hdr *hdr,
1761 int counts)
1762{
1763 int entries;
1764
1765 entries = be16_to_cpu(hdr->count) - be16_to_cpu(hdr->stale);
1766 return sizeof(xfs_dir2_leaf_hdr_t) +
1767 entries * sizeof(xfs_dir2_leaf_entry_t) +
1768 counts * sizeof(xfs_dir2_data_off_t) +
1769 sizeof(xfs_dir2_leaf_tail_t);
1770}
1771
1772
1773
1774
1775
1776
1777int
1778xfs_dir2_node_to_leaf(
1779 xfs_da_state_t *state)
1780{
1781 xfs_da_args_t *args;
1782 xfs_inode_t *dp;
1783 int error;
1784 xfs_dabuf_t *fbp;
1785 xfs_fileoff_t fo;
1786 xfs_dir2_free_t *free;
1787 xfs_dabuf_t *lbp;
1788 xfs_dir2_leaf_tail_t *ltp;
1789 xfs_dir2_leaf_t *leaf;
1790 xfs_mount_t *mp;
1791 int rval;
1792 xfs_trans_t *tp;
1793
1794
1795
1796
1797
1798 if (state->path.active > 1)
1799 return 0;
1800 args = state->args;
1801
1802 trace_xfs_dir2_node_to_leaf(args);
1803
1804 mp = state->mp;
1805 dp = args->dp;
1806 tp = args->trans;
1807
1808
1809
1810 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) {
1811 return error;
1812 }
1813 fo -= mp->m_dirblkfsbs;
1814
1815
1816
1817
1818
1819
1820 while (fo > mp->m_dirfreeblk) {
1821 if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) {
1822 return error;
1823 }
1824 if (rval)
1825 fo -= mp->m_dirblkfsbs;
1826 else
1827 return 0;
1828 }
1829
1830
1831
1832 if ((error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK))) {
1833 return error;
1834 }
1835
1836
1837
1838 if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize)
1839 return 0;
1840 lbp = state->path.blk[0].bp;
1841 leaf = lbp->data;
1842 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1843
1844
1845
1846 if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp,
1847 XFS_DATA_FORK))) {
1848 return error;
1849 }
1850 free = fbp->data;
1851 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
1852 ASSERT(!free->hdr.firstdb);
1853
1854
1855
1856
1857
1858 if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) >
1859 mp->m_dirblksize) {
1860 xfs_da_brelse(tp, fbp);
1861 return 0;
1862 }
1863
1864
1865
1866
1867
1868 if (be16_to_cpu(leaf->hdr.stale))
1869 xfs_dir2_leaf_compact(args, lbp);
1870 else
1871 xfs_dir2_leaf_log_header(tp, lbp);
1872 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC);
1873
1874
1875
1876 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1877 ltp->bestcount = free->hdr.nvalid;
1878
1879
1880
1881 memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests,
1882 be32_to_cpu(ltp->bestcount) * sizeof(xfs_dir2_data_off_t));
1883 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1884 xfs_dir2_leaf_log_tail(tp, lbp);
1885 xfs_dir2_leaf_check(dp, lbp);
1886
1887
1888
1889 error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp);
1890 if (error) {
1891
1892
1893
1894
1895
1896 ASSERT(error != ENOSPC);
1897 return error;
1898 }
1899 fbp = NULL;
1900
1901
1902
1903
1904
1905
1906 error = xfs_dir2_leaf_to_block(args, lbp, NULL);
1907 state->path.blk[0].bp = NULL;
1908 return error;
1909}
1910