1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#ifndef __XFS_DIR2_FORMAT_H__
20#define __XFS_DIR2_FORMAT_H__
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#define XFS_DIR2_BLOCK_MAGIC 0x58443242
36#define XFS_DIR2_DATA_MAGIC 0x58443244
37#define XFS_DIR2_FREE_MAGIC 0x58443246
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#define XFS_DIR3_BLOCK_MAGIC 0x58444233
68#define XFS_DIR3_DATA_MAGIC 0x58444433
69#define XFS_DIR3_FREE_MAGIC 0x58444633
70
71
72
73
74typedef __uint16_t xfs_dir2_data_off_t;
75#define NULLDATAOFF 0xffffU
76typedef uint xfs_dir2_data_aoff_t;
77
78
79
80
81
82typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
83
84
85
86
87typedef __uint32_t xfs_dir2_dataptr_t;
88#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff)
89#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
90
91
92
93
94typedef xfs_off_t xfs_dir2_off_t;
95
96
97
98
99typedef __uint32_t xfs_dir2_db_t;
100
101
102
103
104typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
105
106
107
108
109
110
111typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
112
113typedef union {
114 xfs_dir2_ino8_t i8;
115 xfs_dir2_ino4_t i4;
116} xfs_dir2_inou_t;
117#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
118
119
120
121
122
123
124
125
126
127
128
129
130typedef struct xfs_dir2_sf_hdr {
131 __uint8_t count;
132 __uint8_t i8count;
133 xfs_dir2_inou_t parent;
134} __arch_pack xfs_dir2_sf_hdr_t;
135
136typedef struct xfs_dir2_sf_entry {
137 __u8 namelen;
138 xfs_dir2_sf_off_t offset;
139 __u8 name[];
140
141
142
143
144} __arch_pack xfs_dir2_sf_entry_t;
145
146static inline int xfs_dir2_sf_hdr_size(int i8count)
147{
148 return sizeof(struct xfs_dir2_sf_hdr) -
149 (i8count == 0) *
150 (sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t));
151}
152
153static inline xfs_dir2_data_aoff_t
154xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
155{
156 return get_unaligned_be16(&sfep->offset.i);
157}
158
159static inline void
160xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
161{
162 put_unaligned_be16(off, &sfep->offset.i);
163}
164
165static inline int
166xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
167{
168 return sizeof(struct xfs_dir2_sf_entry) +
169 len +
170 (hdr->i8count ?
171 sizeof(xfs_dir2_ino8_t) :
172 sizeof(xfs_dir2_ino4_t));
173}
174
175static inline struct xfs_dir2_sf_entry *
176xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
177{
178 return (struct xfs_dir2_sf_entry *)
179 ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
180}
181
182static inline struct xfs_dir2_sf_entry *
183xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
184 struct xfs_dir2_sf_entry *sfep)
185{
186 return (struct xfs_dir2_sf_entry *)
187 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
188}
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215#define XFS_DIR2_DATA_ALIGN_LOG 3
216#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
217#define XFS_DIR2_DATA_FREE_TAG 0xffff
218#define XFS_DIR2_DATA_FD_COUNT 3
219
220
221
222
223
224#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
225#define XFS_DIR2_DATA_SPACE 0
226#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
227#define XFS_DIR2_DATA_FIRSTDB(mp) \
228 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
229
230
231
232
233
234
235typedef struct xfs_dir2_data_free {
236 __be16 offset;
237 __be16 length;
238} xfs_dir2_data_free_t;
239
240
241
242
243
244
245typedef struct xfs_dir2_data_hdr {
246 __be32 magic;
247
248 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
249} xfs_dir2_data_hdr_t;
250
251
252
253
254
255
256
257struct xfs_dir3_blk_hdr {
258 __be32 magic;
259 __be32 crc;
260 __be64 blkno;
261 __be64 lsn;
262 uuid_t uuid;
263 __be64 owner;
264};
265
266struct xfs_dir3_data_hdr {
267 struct xfs_dir3_blk_hdr hdr;
268 xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT];
269 __be32 pad;
270};
271
272#define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc)
273
274static inline struct xfs_dir2_data_free *
275xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
276{
277 if (hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
278 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
279 struct xfs_dir3_data_hdr *hdr3 = (struct xfs_dir3_data_hdr *)hdr;
280 return hdr3->best_free;
281 }
282 return hdr->bestfree;
283}
284
285
286
287
288
289
290
291typedef struct xfs_dir2_data_entry {
292 __be64 inumber;
293 __u8 namelen;
294 __u8 name[];
295
296} xfs_dir2_data_entry_t;
297
298
299
300
301
302
303
304typedef struct xfs_dir2_data_unused {
305 __be16 freetag;
306 __be16 length;
307
308 __be16 tag;
309} xfs_dir2_data_unused_t;
310
311
312
313
314static inline int xfs_dir2_data_entsize(int n)
315{
316 return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
317 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
318}
319
320
321
322
323static inline __be16 *
324xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
325{
326 return (__be16 *)((char *)dep +
327 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
328}
329
330
331
332
333static inline __be16 *
334xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
335{
336 return (__be16 *)((char *)dup +
337 be16_to_cpu(dup->length) - sizeof(__be16));
338}
339
340static inline size_t
341xfs_dir3_data_hdr_size(bool dir3)
342{
343 if (dir3)
344 return sizeof(struct xfs_dir3_data_hdr);
345 return sizeof(struct xfs_dir2_data_hdr);
346}
347
348static inline size_t
349xfs_dir3_data_entry_offset(struct xfs_dir2_data_hdr *hdr)
350{
351 bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
352 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
353 return xfs_dir3_data_hdr_size(dir3);
354}
355
356static inline struct xfs_dir2_data_entry *
357xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
358{
359 return (struct xfs_dir2_data_entry *)
360 ((char *)hdr + xfs_dir3_data_entry_offset(hdr));
361}
362
363static inline struct xfs_dir2_data_unused *
364xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
365{
366 return (struct xfs_dir2_data_unused *)
367 ((char *)hdr + xfs_dir3_data_entry_offset(hdr));
368}
369
370
371
372
373
374
375
376
377
378
379#define XFS_DIR3_DATA_DOT_OFFSET(mp) \
380 xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb))
381#define XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \
382 (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir2_data_entsize(1))
383#define XFS_DIR3_DATA_FIRST_OFFSET(mp) \
384 (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir2_data_entsize(2))
385
386static inline xfs_dir2_data_aoff_t
387xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr)
388{
389 return xfs_dir3_data_entry_offset(hdr);
390}
391
392static inline xfs_dir2_data_aoff_t
393xfs_dir3_data_dotdot_offset(struct xfs_dir2_data_hdr *hdr)
394{
395 return xfs_dir3_data_dot_offset(hdr) + xfs_dir2_data_entsize(1);
396}
397
398static inline xfs_dir2_data_aoff_t
399xfs_dir3_data_first_offset(struct xfs_dir2_data_hdr *hdr)
400{
401 return xfs_dir3_data_dotdot_offset(hdr) + xfs_dir2_data_entsize(2);
402}
403
404
405
406
407static inline struct xfs_dir2_data_entry *
408xfs_dir3_data_dot_entry_p(struct xfs_dir2_data_hdr *hdr)
409{
410 return (struct xfs_dir2_data_entry *)
411 ((char *)hdr + xfs_dir3_data_dot_offset(hdr));
412}
413
414static inline struct xfs_dir2_data_entry *
415xfs_dir3_data_dotdot_entry_p(struct xfs_dir2_data_hdr *hdr)
416{
417 return (struct xfs_dir2_data_entry *)
418 ((char *)hdr + xfs_dir3_data_dotdot_offset(hdr));
419}
420
421static inline struct xfs_dir2_data_entry *
422xfs_dir3_data_first_entry_p(struct xfs_dir2_data_hdr *hdr)
423{
424 return (struct xfs_dir2_data_entry *)
425 ((char *)hdr + xfs_dir3_data_first_offset(hdr));
426}
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463#define XFS_DIR2_LEAF_SPACE 1
464#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
465#define XFS_DIR2_LEAF_FIRSTDB(mp) \
466 xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
467
468
469
470
471typedef struct xfs_dir2_leaf_hdr {
472 xfs_da_blkinfo_t info;
473 __be16 count;
474 __be16 stale;
475} xfs_dir2_leaf_hdr_t;
476
477struct xfs_dir3_leaf_hdr {
478 struct xfs_da3_blkinfo info;
479 __be16 count;
480 __be16 stale;
481 __be32 pad;
482};
483
484struct xfs_dir3_icleaf_hdr {
485 __uint32_t forw;
486 __uint32_t back;
487 __uint16_t magic;
488 __uint16_t count;
489 __uint16_t stale;
490};
491
492
493
494
495typedef struct xfs_dir2_leaf_entry {
496 __be32 hashval;
497 __be32 address;
498} xfs_dir2_leaf_entry_t;
499
500
501
502
503typedef struct xfs_dir2_leaf_tail {
504 __be32 bestcount;
505} xfs_dir2_leaf_tail_t;
506
507
508
509
510typedef struct xfs_dir2_leaf {
511 xfs_dir2_leaf_hdr_t hdr;
512 xfs_dir2_leaf_entry_t __ents[];
513} xfs_dir2_leaf_t;
514
515struct xfs_dir3_leaf {
516 struct xfs_dir3_leaf_hdr hdr;
517 struct xfs_dir2_leaf_entry __ents[];
518};
519
520#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc)
521
522static inline int
523xfs_dir3_leaf_hdr_size(struct xfs_dir2_leaf *lp)
524{
525 if (lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
526 lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC))
527 return sizeof(struct xfs_dir3_leaf_hdr);
528 return sizeof(struct xfs_dir2_leaf_hdr);
529}
530
531static inline int
532xfs_dir3_max_leaf_ents(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
533{
534 return (mp->m_dirblksize - xfs_dir3_leaf_hdr_size(lp)) /
535 (uint)sizeof(struct xfs_dir2_leaf_entry);
536}
537
538
539
540
541static inline struct xfs_dir2_leaf_entry *
542xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
543{
544 if (lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
545 lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
546 struct xfs_dir3_leaf *lp3 = (struct xfs_dir3_leaf *)lp;
547 return lp3->__ents;
548 }
549 return lp->__ents;
550}
551
552
553
554
555static inline struct xfs_dir2_leaf_tail *
556xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
557{
558 return (struct xfs_dir2_leaf_tail *)
559 ((char *)lp + mp->m_dirblksize -
560 sizeof(struct xfs_dir2_leaf_tail));
561}
562
563
564
565
566static inline __be16 *
567xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
568{
569 return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
570}
571
572
573
574
575
576
577
578
579static inline xfs_dir2_off_t
580xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
581{
582 return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
583}
584
585
586
587
588static inline xfs_dir2_dataptr_t
589xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
590{
591 return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
592}
593
594
595
596
597static inline xfs_dir2_db_t
598xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
599{
600 return (xfs_dir2_db_t)
601 (by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
602}
603
604
605
606
607static inline xfs_dir2_db_t
608xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
609{
610 return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
611}
612
613
614
615
616static inline xfs_dir2_data_aoff_t
617xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
618{
619 return (xfs_dir2_data_aoff_t)(by &
620 ((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
621}
622
623
624
625
626static inline xfs_dir2_data_aoff_t
627xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
628{
629 return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
630}
631
632
633
634
635static inline xfs_dir2_off_t
636xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
637 xfs_dir2_data_aoff_t o)
638{
639 return ((xfs_dir2_off_t)db <<
640 (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
641}
642
643
644
645
646static inline xfs_dablk_t
647xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
648{
649 return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
650}
651
652
653
654
655static inline xfs_dablk_t
656xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
657{
658 return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
659}
660
661
662
663
664static inline xfs_dir2_dataptr_t
665xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
666 xfs_dir2_data_aoff_t o)
667{
668 return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
669}
670
671
672
673
674static inline xfs_dir2_db_t
675xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
676{
677 return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
678}
679
680
681
682
683static inline xfs_dir2_off_t
684xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
685{
686 return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
687}
688
689
690
691
692
693
694
695
696#define XFS_DIR2_FREE_SPACE 2
697#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
698#define XFS_DIR2_FREE_FIRSTDB(mp) \
699 xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
700
701typedef struct xfs_dir2_free_hdr {
702 __be32 magic;
703 __be32 firstdb;
704 __be32 nvalid;
705 __be32 nused;
706} xfs_dir2_free_hdr_t;
707
708typedef struct xfs_dir2_free {
709 xfs_dir2_free_hdr_t hdr;
710 __be16 bests[];
711
712} xfs_dir2_free_t;
713
714struct xfs_dir3_free_hdr {
715 struct xfs_dir3_blk_hdr hdr;
716 __be32 firstdb;
717 __be32 nvalid;
718 __be32 nused;
719 __be32 pad;
720};
721
722struct xfs_dir3_free {
723 struct xfs_dir3_free_hdr hdr;
724 __be16 bests[];
725
726};
727
728#define XFS_DIR3_FREE_CRC_OFF offsetof(struct xfs_dir3_free, hdr.hdr.crc)
729
730
731
732
733
734
735struct xfs_dir3_icfree_hdr {
736 __uint32_t magic;
737 __uint32_t firstdb;
738 __uint32_t nvalid;
739 __uint32_t nused;
740
741};
742
743void xfs_dir3_free_hdr_from_disk(struct xfs_dir3_icfree_hdr *to,
744 struct xfs_dir2_free *from);
745
746static inline int
747xfs_dir3_free_hdr_size(struct xfs_mount *mp)
748{
749 if (xfs_sb_version_hascrc(&mp->m_sb))
750 return sizeof(struct xfs_dir3_free_hdr);
751 return sizeof(struct xfs_dir2_free_hdr);
752}
753
754static inline int
755xfs_dir3_free_max_bests(struct xfs_mount *mp)
756{
757 return (mp->m_dirblksize - xfs_dir3_free_hdr_size(mp)) /
758 sizeof(xfs_dir2_data_off_t);
759}
760
761static inline __be16 *
762xfs_dir3_free_bests_p(struct xfs_mount *mp, struct xfs_dir2_free *free)
763{
764 return (__be16 *)((char *)free + xfs_dir3_free_hdr_size(mp));
765}
766
767
768
769
770static inline xfs_dir2_db_t
771xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
772{
773 return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir3_free_max_bests(mp);
774}
775
776
777
778
779static inline int
780xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
781{
782 return db % xfs_dir3_free_max_bests(mp);
783}
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811typedef struct xfs_dir2_block_tail {
812 __be32 count;
813 __be32 stale;
814} xfs_dir2_block_tail_t;
815
816
817
818
819static inline struct xfs_dir2_block_tail *
820xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
821{
822 return ((struct xfs_dir2_block_tail *)
823 ((char *)hdr + mp->m_dirblksize)) - 1;
824}
825
826
827
828
829static inline struct xfs_dir2_leaf_entry *
830xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
831{
832 return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
833}
834
835#endif
836