]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/xfs_da_format.c
libxfs: refactor manage_zones()
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_da_format.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
4 * Copyright (c) 2013 Red Hat, Inc.
5 * All Rights Reserved.
6 */
7 #include "libxfs_priv.h"
8 #include "xfs_fs.h"
9 #include "xfs_shared.h"
10 #include "xfs_format.h"
11 #include "xfs_log_format.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_da_format.h"
15 #include "xfs_da_btree.h"
16 #include "xfs_inode.h"
17 #include "xfs_dir2.h"
18 #include "xfs_dir2_priv.h"
19
20 /*
21 * Shortform directory ops
22 */
23 static int
24 xfs_dir2_sf_entsize(
25 struct xfs_dir2_sf_hdr *hdr,
26 int len)
27 {
28 int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */
29
30 count += len; /* name */
31 count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */
32 return count;
33 }
34
35 static int
36 xfs_dir3_sf_entsize(
37 struct xfs_dir2_sf_hdr *hdr,
38 int len)
39 {
40 return xfs_dir2_sf_entsize(hdr, len) + sizeof(uint8_t);
41 }
42
43 static struct xfs_dir2_sf_entry *
44 xfs_dir2_sf_nextentry(
45 struct xfs_dir2_sf_hdr *hdr,
46 struct xfs_dir2_sf_entry *sfep)
47 {
48 return (struct xfs_dir2_sf_entry *)
49 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
50 }
51
52 static struct xfs_dir2_sf_entry *
53 xfs_dir3_sf_nextentry(
54 struct xfs_dir2_sf_hdr *hdr,
55 struct xfs_dir2_sf_entry *sfep)
56 {
57 return (struct xfs_dir2_sf_entry *)
58 ((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen));
59 }
60
61
62 /*
63 * For filetype enabled shortform directories, the file type field is stored at
64 * the end of the name. Because it's only a single byte, endian conversion is
65 * not necessary. For non-filetype enable directories, the type is always
66 * unknown and we never store the value.
67 */
68 static uint8_t
69 xfs_dir2_sfe_get_ftype(
70 struct xfs_dir2_sf_entry *sfep)
71 {
72 return XFS_DIR3_FT_UNKNOWN;
73 }
74
75 static void
76 xfs_dir2_sfe_put_ftype(
77 struct xfs_dir2_sf_entry *sfep,
78 uint8_t ftype)
79 {
80 ASSERT(ftype < XFS_DIR3_FT_MAX);
81 }
82
83 static uint8_t
84 xfs_dir3_sfe_get_ftype(
85 struct xfs_dir2_sf_entry *sfep)
86 {
87 uint8_t ftype;
88
89 ftype = sfep->name[sfep->namelen];
90 if (ftype >= XFS_DIR3_FT_MAX)
91 return XFS_DIR3_FT_UNKNOWN;
92 return ftype;
93 }
94
95 static void
96 xfs_dir3_sfe_put_ftype(
97 struct xfs_dir2_sf_entry *sfep,
98 uint8_t ftype)
99 {
100 ASSERT(ftype < XFS_DIR3_FT_MAX);
101
102 sfep->name[sfep->namelen] = ftype;
103 }
104
105 /*
106 * Inode numbers in short-form directories can come in two versions,
107 * either 4 bytes or 8 bytes wide. These helpers deal with the
108 * two forms transparently by looking at the headers i8count field.
109 *
110 * For 64-bit inode number the most significant byte must be zero.
111 */
112 static xfs_ino_t
113 xfs_dir2_sf_get_ino(
114 struct xfs_dir2_sf_hdr *hdr,
115 uint8_t *from)
116 {
117 if (hdr->i8count)
118 return get_unaligned_be64(from) & 0x00ffffffffffffffULL;
119 else
120 return get_unaligned_be32(from);
121 }
122
123 static void
124 xfs_dir2_sf_put_ino(
125 struct xfs_dir2_sf_hdr *hdr,
126 uint8_t *to,
127 xfs_ino_t ino)
128 {
129 ASSERT((ino & 0xff00000000000000ULL) == 0);
130
131 if (hdr->i8count)
132 put_unaligned_be64(ino, to);
133 else
134 put_unaligned_be32(ino, to);
135 }
136
137 static xfs_ino_t
138 xfs_dir2_sf_get_parent_ino(
139 struct xfs_dir2_sf_hdr *hdr)
140 {
141 return xfs_dir2_sf_get_ino(hdr, hdr->parent);
142 }
143
144 static void
145 xfs_dir2_sf_put_parent_ino(
146 struct xfs_dir2_sf_hdr *hdr,
147 xfs_ino_t ino)
148 {
149 xfs_dir2_sf_put_ino(hdr, hdr->parent, ino);
150 }
151
152 /*
153 * In short-form directory entries the inode numbers are stored at variable
154 * offset behind the entry name. If the entry stores a filetype value, then it
155 * sits between the name and the inode number. Hence the inode numbers may only
156 * be accessed through the helpers below.
157 */
158 static xfs_ino_t
159 xfs_dir2_sfe_get_ino(
160 struct xfs_dir2_sf_hdr *hdr,
161 struct xfs_dir2_sf_entry *sfep)
162 {
163 return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen]);
164 }
165
166 static void
167 xfs_dir2_sfe_put_ino(
168 struct xfs_dir2_sf_hdr *hdr,
169 struct xfs_dir2_sf_entry *sfep,
170 xfs_ino_t ino)
171 {
172 xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen], ino);
173 }
174
175 static xfs_ino_t
176 xfs_dir3_sfe_get_ino(
177 struct xfs_dir2_sf_hdr *hdr,
178 struct xfs_dir2_sf_entry *sfep)
179 {
180 return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen + 1]);
181 }
182
183 static void
184 xfs_dir3_sfe_put_ino(
185 struct xfs_dir2_sf_hdr *hdr,
186 struct xfs_dir2_sf_entry *sfep,
187 xfs_ino_t ino)
188 {
189 xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen + 1], ino);
190 }
191
192
193 /*
194 * Directory data block operations
195 */
196
197 /*
198 * For special situations, the dirent size ends up fixed because we always know
199 * what the size of the entry is. That's true for the "." and "..", and
200 * therefore we know that they are a fixed size and hence their offsets are
201 * constant, as is the first entry.
202 *
203 * Hence, this calculation is written as a macro to be able to be calculated at
204 * compile time and so certain offsets can be calculated directly in the
205 * structure initaliser via the macro. There are two macros - one for dirents
206 * with ftype and without so there are no unresolvable conditionals in the
207 * calculations. We also use round_up() as XFS_DIR2_DATA_ALIGN is always a power
208 * of 2 and the compiler doesn't reject it (unlike roundup()).
209 */
210 #define XFS_DIR2_DATA_ENTSIZE(n) \
211 round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \
212 sizeof(xfs_dir2_data_off_t)), XFS_DIR2_DATA_ALIGN)
213
214 #define XFS_DIR3_DATA_ENTSIZE(n) \
215 round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \
216 sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)), \
217 XFS_DIR2_DATA_ALIGN)
218
219 static int
220 xfs_dir2_data_entsize(
221 int n)
222 {
223 return XFS_DIR2_DATA_ENTSIZE(n);
224 }
225
226 static int
227 xfs_dir3_data_entsize(
228 int n)
229 {
230 return XFS_DIR3_DATA_ENTSIZE(n);
231 }
232
233 static uint8_t
234 xfs_dir2_data_get_ftype(
235 struct xfs_dir2_data_entry *dep)
236 {
237 return XFS_DIR3_FT_UNKNOWN;
238 }
239
240 static void
241 xfs_dir2_data_put_ftype(
242 struct xfs_dir2_data_entry *dep,
243 uint8_t ftype)
244 {
245 ASSERT(ftype < XFS_DIR3_FT_MAX);
246 }
247
248 static uint8_t
249 xfs_dir3_data_get_ftype(
250 struct xfs_dir2_data_entry *dep)
251 {
252 uint8_t ftype = dep->name[dep->namelen];
253
254 if (ftype >= XFS_DIR3_FT_MAX)
255 return XFS_DIR3_FT_UNKNOWN;
256 return ftype;
257 }
258
259 static void
260 xfs_dir3_data_put_ftype(
261 struct xfs_dir2_data_entry *dep,
262 uint8_t type)
263 {
264 ASSERT(type < XFS_DIR3_FT_MAX);
265 ASSERT(dep->namelen != 0);
266
267 dep->name[dep->namelen] = type;
268 }
269
270 /*
271 * Pointer to an entry's tag word.
272 */
273 static __be16 *
274 xfs_dir2_data_entry_tag_p(
275 struct xfs_dir2_data_entry *dep)
276 {
277 return (__be16 *)((char *)dep +
278 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
279 }
280
281 static __be16 *
282 xfs_dir3_data_entry_tag_p(
283 struct xfs_dir2_data_entry *dep)
284 {
285 return (__be16 *)((char *)dep +
286 xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
287 }
288
289 /*
290 * location of . and .. in data space (always block 0)
291 */
292 static struct xfs_dir2_data_entry *
293 xfs_dir2_data_dot_entry_p(
294 struct xfs_dir2_data_hdr *hdr)
295 {
296 return (struct xfs_dir2_data_entry *)
297 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
298 }
299
300 static struct xfs_dir2_data_entry *
301 xfs_dir2_data_dotdot_entry_p(
302 struct xfs_dir2_data_hdr *hdr)
303 {
304 return (struct xfs_dir2_data_entry *)
305 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
306 XFS_DIR2_DATA_ENTSIZE(1));
307 }
308
309 static struct xfs_dir2_data_entry *
310 xfs_dir2_data_first_entry_p(
311 struct xfs_dir2_data_hdr *hdr)
312 {
313 return (struct xfs_dir2_data_entry *)
314 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
315 XFS_DIR2_DATA_ENTSIZE(1) +
316 XFS_DIR2_DATA_ENTSIZE(2));
317 }
318
319 static struct xfs_dir2_data_entry *
320 xfs_dir2_ftype_data_dotdot_entry_p(
321 struct xfs_dir2_data_hdr *hdr)
322 {
323 return (struct xfs_dir2_data_entry *)
324 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
325 XFS_DIR3_DATA_ENTSIZE(1));
326 }
327
328 static struct xfs_dir2_data_entry *
329 xfs_dir2_ftype_data_first_entry_p(
330 struct xfs_dir2_data_hdr *hdr)
331 {
332 return (struct xfs_dir2_data_entry *)
333 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
334 XFS_DIR3_DATA_ENTSIZE(1) +
335 XFS_DIR3_DATA_ENTSIZE(2));
336 }
337
338 static struct xfs_dir2_data_entry *
339 xfs_dir3_data_dot_entry_p(
340 struct xfs_dir2_data_hdr *hdr)
341 {
342 return (struct xfs_dir2_data_entry *)
343 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
344 }
345
346 static struct xfs_dir2_data_entry *
347 xfs_dir3_data_dotdot_entry_p(
348 struct xfs_dir2_data_hdr *hdr)
349 {
350 return (struct xfs_dir2_data_entry *)
351 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
352 XFS_DIR3_DATA_ENTSIZE(1));
353 }
354
355 static struct xfs_dir2_data_entry *
356 xfs_dir3_data_first_entry_p(
357 struct xfs_dir2_data_hdr *hdr)
358 {
359 return (struct xfs_dir2_data_entry *)
360 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
361 XFS_DIR3_DATA_ENTSIZE(1) +
362 XFS_DIR3_DATA_ENTSIZE(2));
363 }
364
365 static struct xfs_dir2_data_free *
366 xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
367 {
368 return hdr->bestfree;
369 }
370
371 static struct xfs_dir2_data_free *
372 xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
373 {
374 return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
375 }
376
377 static struct xfs_dir2_data_entry *
378 xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
379 {
380 return (struct xfs_dir2_data_entry *)
381 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
382 }
383
384 static struct xfs_dir2_data_unused *
385 xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr)
386 {
387 return (struct xfs_dir2_data_unused *)
388 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
389 }
390
391 static struct xfs_dir2_data_entry *
392 xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
393 {
394 return (struct xfs_dir2_data_entry *)
395 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
396 }
397
398 static struct xfs_dir2_data_unused *
399 xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
400 {
401 return (struct xfs_dir2_data_unused *)
402 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
403 }
404
405
406 /*
407 * Directory Leaf block operations
408 */
409 static int
410 xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
411 {
412 return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
413 (uint)sizeof(struct xfs_dir2_leaf_entry);
414 }
415
416 static struct xfs_dir2_leaf_entry *
417 xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
418 {
419 return lp->__ents;
420 }
421
422 static int
423 xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
424 {
425 return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
426 (uint)sizeof(struct xfs_dir2_leaf_entry);
427 }
428
429 static struct xfs_dir2_leaf_entry *
430 xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
431 {
432 return ((struct xfs_dir3_leaf *)lp)->__ents;
433 }
434
435 static void
436 xfs_dir2_leaf_hdr_from_disk(
437 struct xfs_dir3_icleaf_hdr *to,
438 struct xfs_dir2_leaf *from)
439 {
440 to->forw = be32_to_cpu(from->hdr.info.forw);
441 to->back = be32_to_cpu(from->hdr.info.back);
442 to->magic = be16_to_cpu(from->hdr.info.magic);
443 to->count = be16_to_cpu(from->hdr.count);
444 to->stale = be16_to_cpu(from->hdr.stale);
445
446 ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
447 to->magic == XFS_DIR2_LEAFN_MAGIC);
448 }
449
450 static void
451 xfs_dir2_leaf_hdr_to_disk(
452 struct xfs_dir2_leaf *to,
453 struct xfs_dir3_icleaf_hdr *from)
454 {
455 ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
456 from->magic == XFS_DIR2_LEAFN_MAGIC);
457
458 to->hdr.info.forw = cpu_to_be32(from->forw);
459 to->hdr.info.back = cpu_to_be32(from->back);
460 to->hdr.info.magic = cpu_to_be16(from->magic);
461 to->hdr.count = cpu_to_be16(from->count);
462 to->hdr.stale = cpu_to_be16(from->stale);
463 }
464
465 static void
466 xfs_dir3_leaf_hdr_from_disk(
467 struct xfs_dir3_icleaf_hdr *to,
468 struct xfs_dir2_leaf *from)
469 {
470 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from;
471
472 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
473 to->back = be32_to_cpu(hdr3->info.hdr.back);
474 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
475 to->count = be16_to_cpu(hdr3->count);
476 to->stale = be16_to_cpu(hdr3->stale);
477
478 ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
479 to->magic == XFS_DIR3_LEAFN_MAGIC);
480 }
481
482 static void
483 xfs_dir3_leaf_hdr_to_disk(
484 struct xfs_dir2_leaf *to,
485 struct xfs_dir3_icleaf_hdr *from)
486 {
487 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to;
488
489 ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC ||
490 from->magic == XFS_DIR3_LEAFN_MAGIC);
491
492 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
493 hdr3->info.hdr.back = cpu_to_be32(from->back);
494 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
495 hdr3->count = cpu_to_be16(from->count);
496 hdr3->stale = cpu_to_be16(from->stale);
497 }
498
499
500 /*
501 * Directory/Attribute Node block operations
502 */
503 static struct xfs_da_node_entry *
504 xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
505 {
506 return dap->__btree;
507 }
508
509 static struct xfs_da_node_entry *
510 xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
511 {
512 return ((struct xfs_da3_intnode *)dap)->__btree;
513 }
514
515 static void
516 xfs_da2_node_hdr_from_disk(
517 struct xfs_da3_icnode_hdr *to,
518 struct xfs_da_intnode *from)
519 {
520 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
521 to->forw = be32_to_cpu(from->hdr.info.forw);
522 to->back = be32_to_cpu(from->hdr.info.back);
523 to->magic = be16_to_cpu(from->hdr.info.magic);
524 to->count = be16_to_cpu(from->hdr.__count);
525 to->level = be16_to_cpu(from->hdr.__level);
526 }
527
528 static void
529 xfs_da2_node_hdr_to_disk(
530 struct xfs_da_intnode *to,
531 struct xfs_da3_icnode_hdr *from)
532 {
533 ASSERT(from->magic == XFS_DA_NODE_MAGIC);
534 to->hdr.info.forw = cpu_to_be32(from->forw);
535 to->hdr.info.back = cpu_to_be32(from->back);
536 to->hdr.info.magic = cpu_to_be16(from->magic);
537 to->hdr.__count = cpu_to_be16(from->count);
538 to->hdr.__level = cpu_to_be16(from->level);
539 }
540
541 static void
542 xfs_da3_node_hdr_from_disk(
543 struct xfs_da3_icnode_hdr *to,
544 struct xfs_da_intnode *from)
545 {
546 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from;
547
548 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
549 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
550 to->back = be32_to_cpu(hdr3->info.hdr.back);
551 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
552 to->count = be16_to_cpu(hdr3->__count);
553 to->level = be16_to_cpu(hdr3->__level);
554 }
555
556 static void
557 xfs_da3_node_hdr_to_disk(
558 struct xfs_da_intnode *to,
559 struct xfs_da3_icnode_hdr *from)
560 {
561 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to;
562
563 ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
564 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
565 hdr3->info.hdr.back = cpu_to_be32(from->back);
566 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
567 hdr3->__count = cpu_to_be16(from->count);
568 hdr3->__level = cpu_to_be16(from->level);
569 }
570
571
572 /*
573 * Directory free space block operations
574 */
575 static int
576 xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
577 {
578 return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
579 sizeof(xfs_dir2_data_off_t);
580 }
581
582 static __be16 *
583 xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
584 {
585 return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr));
586 }
587
588 /*
589 * Convert data space db to the corresponding free db.
590 */
591 static xfs_dir2_db_t
592 xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
593 {
594 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
595 (db / xfs_dir2_free_max_bests(geo));
596 }
597
598 /*
599 * Convert data space db to the corresponding index in a free db.
600 */
601 static int
602 xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
603 {
604 return db % xfs_dir2_free_max_bests(geo);
605 }
606
607 static int
608 xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
609 {
610 return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
611 sizeof(xfs_dir2_data_off_t);
612 }
613
614 static __be16 *
615 xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
616 {
617 return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr));
618 }
619
620 /*
621 * Convert data space db to the corresponding free db.
622 */
623 static xfs_dir2_db_t
624 xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
625 {
626 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
627 (db / xfs_dir3_free_max_bests(geo));
628 }
629
630 /*
631 * Convert data space db to the corresponding index in a free db.
632 */
633 static int
634 xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
635 {
636 return db % xfs_dir3_free_max_bests(geo);
637 }
638
639 static void
640 xfs_dir2_free_hdr_from_disk(
641 struct xfs_dir3_icfree_hdr *to,
642 struct xfs_dir2_free *from)
643 {
644 to->magic = be32_to_cpu(from->hdr.magic);
645 to->firstdb = be32_to_cpu(from->hdr.firstdb);
646 to->nvalid = be32_to_cpu(from->hdr.nvalid);
647 to->nused = be32_to_cpu(from->hdr.nused);
648 ASSERT(to->magic == XFS_DIR2_FREE_MAGIC);
649 }
650
651 static void
652 xfs_dir2_free_hdr_to_disk(
653 struct xfs_dir2_free *to,
654 struct xfs_dir3_icfree_hdr *from)
655 {
656 ASSERT(from->magic == XFS_DIR2_FREE_MAGIC);
657
658 to->hdr.magic = cpu_to_be32(from->magic);
659 to->hdr.firstdb = cpu_to_be32(from->firstdb);
660 to->hdr.nvalid = cpu_to_be32(from->nvalid);
661 to->hdr.nused = cpu_to_be32(from->nused);
662 }
663
664 static void
665 xfs_dir3_free_hdr_from_disk(
666 struct xfs_dir3_icfree_hdr *to,
667 struct xfs_dir2_free *from)
668 {
669 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from;
670
671 to->magic = be32_to_cpu(hdr3->hdr.magic);
672 to->firstdb = be32_to_cpu(hdr3->firstdb);
673 to->nvalid = be32_to_cpu(hdr3->nvalid);
674 to->nused = be32_to_cpu(hdr3->nused);
675
676 ASSERT(to->magic == XFS_DIR3_FREE_MAGIC);
677 }
678
679 static void
680 xfs_dir3_free_hdr_to_disk(
681 struct xfs_dir2_free *to,
682 struct xfs_dir3_icfree_hdr *from)
683 {
684 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to;
685
686 ASSERT(from->magic == XFS_DIR3_FREE_MAGIC);
687
688 hdr3->hdr.magic = cpu_to_be32(from->magic);
689 hdr3->firstdb = cpu_to_be32(from->firstdb);
690 hdr3->nvalid = cpu_to_be32(from->nvalid);
691 hdr3->nused = cpu_to_be32(from->nused);
692 }
693
694 static const struct xfs_dir_ops xfs_dir2_ops = {
695 .sf_entsize = xfs_dir2_sf_entsize,
696 .sf_nextentry = xfs_dir2_sf_nextentry,
697 .sf_get_ftype = xfs_dir2_sfe_get_ftype,
698 .sf_put_ftype = xfs_dir2_sfe_put_ftype,
699 .sf_get_ino = xfs_dir2_sfe_get_ino,
700 .sf_put_ino = xfs_dir2_sfe_put_ino,
701 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
702 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
703
704 .data_entsize = xfs_dir2_data_entsize,
705 .data_get_ftype = xfs_dir2_data_get_ftype,
706 .data_put_ftype = xfs_dir2_data_put_ftype,
707 .data_entry_tag_p = xfs_dir2_data_entry_tag_p,
708 .data_bestfree_p = xfs_dir2_data_bestfree_p,
709
710 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
711 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
712 XFS_DIR2_DATA_ENTSIZE(1),
713 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) +
714 XFS_DIR2_DATA_ENTSIZE(1) +
715 XFS_DIR2_DATA_ENTSIZE(2),
716 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
717
718 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
719 .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
720 .data_first_entry_p = xfs_dir2_data_first_entry_p,
721 .data_entry_p = xfs_dir2_data_entry_p,
722 .data_unused_p = xfs_dir2_data_unused_p,
723
724 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
725 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
726 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
727 .leaf_max_ents = xfs_dir2_max_leaf_ents,
728 .leaf_ents_p = xfs_dir2_leaf_ents_p,
729
730 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
731 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
732 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
733 .node_tree_p = xfs_da2_node_tree_p,
734
735 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
736 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
737 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
738 .free_max_bests = xfs_dir2_free_max_bests,
739 .free_bests_p = xfs_dir2_free_bests_p,
740 .db_to_fdb = xfs_dir2_db_to_fdb,
741 .db_to_fdindex = xfs_dir2_db_to_fdindex,
742 };
743
744 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
745 .sf_entsize = xfs_dir3_sf_entsize,
746 .sf_nextentry = xfs_dir3_sf_nextentry,
747 .sf_get_ftype = xfs_dir3_sfe_get_ftype,
748 .sf_put_ftype = xfs_dir3_sfe_put_ftype,
749 .sf_get_ino = xfs_dir3_sfe_get_ino,
750 .sf_put_ino = xfs_dir3_sfe_put_ino,
751 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
752 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
753
754 .data_entsize = xfs_dir3_data_entsize,
755 .data_get_ftype = xfs_dir3_data_get_ftype,
756 .data_put_ftype = xfs_dir3_data_put_ftype,
757 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
758 .data_bestfree_p = xfs_dir2_data_bestfree_p,
759
760 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
761 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
762 XFS_DIR3_DATA_ENTSIZE(1),
763 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) +
764 XFS_DIR3_DATA_ENTSIZE(1) +
765 XFS_DIR3_DATA_ENTSIZE(2),
766 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
767
768 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
769 .data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p,
770 .data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
771 .data_entry_p = xfs_dir2_data_entry_p,
772 .data_unused_p = xfs_dir2_data_unused_p,
773
774 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
775 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
776 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
777 .leaf_max_ents = xfs_dir2_max_leaf_ents,
778 .leaf_ents_p = xfs_dir2_leaf_ents_p,
779
780 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
781 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
782 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
783 .node_tree_p = xfs_da2_node_tree_p,
784
785 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
786 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
787 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
788 .free_max_bests = xfs_dir2_free_max_bests,
789 .free_bests_p = xfs_dir2_free_bests_p,
790 .db_to_fdb = xfs_dir2_db_to_fdb,
791 .db_to_fdindex = xfs_dir2_db_to_fdindex,
792 };
793
794 static const struct xfs_dir_ops xfs_dir3_ops = {
795 .sf_entsize = xfs_dir3_sf_entsize,
796 .sf_nextentry = xfs_dir3_sf_nextentry,
797 .sf_get_ftype = xfs_dir3_sfe_get_ftype,
798 .sf_put_ftype = xfs_dir3_sfe_put_ftype,
799 .sf_get_ino = xfs_dir3_sfe_get_ino,
800 .sf_put_ino = xfs_dir3_sfe_put_ino,
801 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
802 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
803
804 .data_entsize = xfs_dir3_data_entsize,
805 .data_get_ftype = xfs_dir3_data_get_ftype,
806 .data_put_ftype = xfs_dir3_data_put_ftype,
807 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
808 .data_bestfree_p = xfs_dir3_data_bestfree_p,
809
810 .data_dot_offset = sizeof(struct xfs_dir3_data_hdr),
811 .data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) +
812 XFS_DIR3_DATA_ENTSIZE(1),
813 .data_first_offset = sizeof(struct xfs_dir3_data_hdr) +
814 XFS_DIR3_DATA_ENTSIZE(1) +
815 XFS_DIR3_DATA_ENTSIZE(2),
816 .data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
817
818 .data_dot_entry_p = xfs_dir3_data_dot_entry_p,
819 .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p,
820 .data_first_entry_p = xfs_dir3_data_first_entry_p,
821 .data_entry_p = xfs_dir3_data_entry_p,
822 .data_unused_p = xfs_dir3_data_unused_p,
823
824 .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
825 .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
826 .leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk,
827 .leaf_max_ents = xfs_dir3_max_leaf_ents,
828 .leaf_ents_p = xfs_dir3_leaf_ents_p,
829
830 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
831 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
832 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
833 .node_tree_p = xfs_da3_node_tree_p,
834
835 .free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
836 .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
837 .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk,
838 .free_max_bests = xfs_dir3_free_max_bests,
839 .free_bests_p = xfs_dir3_free_bests_p,
840 .db_to_fdb = xfs_dir3_db_to_fdb,
841 .db_to_fdindex = xfs_dir3_db_to_fdindex,
842 };
843
844 static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
845 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
846 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
847 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
848 .node_tree_p = xfs_da2_node_tree_p,
849 };
850
851 static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
852 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
853 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
854 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
855 .node_tree_p = xfs_da3_node_tree_p,
856 };
857
858 /*
859 * Return the ops structure according to the current config. If we are passed
860 * an inode, then that overrides the default config we use which is based on
861 * feature bits.
862 */
863 const struct xfs_dir_ops *
864 xfs_dir_get_ops(
865 struct xfs_mount *mp,
866 struct xfs_inode *dp)
867 {
868 if (dp)
869 return dp->d_ops;
870 if (mp->m_dir_inode_ops)
871 return mp->m_dir_inode_ops;
872 if (xfs_sb_version_hascrc(&mp->m_sb))
873 return &xfs_dir3_ops;
874 if (xfs_sb_version_hasftype(&mp->m_sb))
875 return &xfs_dir2_ftype_ops;
876 return &xfs_dir2_ops;
877 }
878
879 const struct xfs_dir_ops *
880 xfs_nondir_get_ops(
881 struct xfs_mount *mp,
882 struct xfs_inode *dp)
883 {
884 if (dp)
885 return dp->d_ops;
886 if (mp->m_nondir_inode_ops)
887 return mp->m_nondir_inode_ops;
888 if (xfs_sb_version_hascrc(&mp->m_sb))
889 return &xfs_dir3_nondir_ops;
890 return &xfs_dir2_nondir_ops;
891 }