xfs: convert to SPDX license tags
[linux-2.6-block.git] / fs / xfs / libxfs / xfs_da_format.c
CommitLineData
0b61f8a4 1// SPDX-License-Identifier: GPL-2.0
32c5483a
DC
2/*
3 * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
4 * Copyright (c) 2013 Red Hat, Inc.
5 * All Rights Reserved.
32c5483a
DC
6 */
7#include "xfs.h"
8#include "xfs_fs.h"
632b89e8 9#include "xfs_shared.h"
32c5483a
DC
10#include "xfs_format.h"
11#include "xfs_log_format.h"
12#include "xfs_trans_resv.h"
32c5483a
DC
13#include "xfs_mount.h"
14#include "xfs_da_format.h"
892e3f34 15#include "xfs_da_btree.h"
32c5483a
DC
16#include "xfs_inode.h"
17#include "xfs_dir2.h"
892e3f34 18#include "xfs_dir2_priv.h"
32c5483a 19
9d23fc85
DC
20/*
21 * Shortform directory ops
22 */
32c5483a
DC
23static int
24xfs_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 */
266b6969 31 count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */
32c5483a
DC
32 return count;
33}
34
35static int
36xfs_dir3_sf_entsize(
37 struct xfs_dir2_sf_hdr *hdr,
38 int len)
39{
c8ce540d 40 return xfs_dir2_sf_entsize(hdr, len) + sizeof(uint8_t);
32c5483a
DC
41}
42
43static struct xfs_dir2_sf_entry *
44xfs_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
52static struct xfs_dir2_sf_entry *
53xfs_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
4740175e
DC
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 */
c8ce540d 68static uint8_t
4740175e
DC
69xfs_dir2_sfe_get_ftype(
70 struct xfs_dir2_sf_entry *sfep)
71{
72 return XFS_DIR3_FT_UNKNOWN;
73}
74
75static void
76xfs_dir2_sfe_put_ftype(
77 struct xfs_dir2_sf_entry *sfep,
c8ce540d 78 uint8_t ftype)
4740175e
DC
79{
80 ASSERT(ftype < XFS_DIR3_FT_MAX);
81}
82
c8ce540d 83static uint8_t
4740175e
DC
84xfs_dir3_sfe_get_ftype(
85 struct xfs_dir2_sf_entry *sfep)
86{
c8ce540d 87 uint8_t ftype;
4740175e
DC
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
95static void
96xfs_dir3_sfe_put_ftype(
97 struct xfs_dir2_sf_entry *sfep,
c8ce540d 98 uint8_t ftype)
4740175e
DC
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 */
112static xfs_ino_t
113xfs_dir2_sf_get_ino(
114 struct xfs_dir2_sf_hdr *hdr,
c8ce540d 115 uint8_t *from)
4740175e
DC
116{
117 if (hdr->i8count)
266b6969 118 return get_unaligned_be64(from) & 0x00ffffffffffffffULL;
4740175e 119 else
266b6969 120 return get_unaligned_be32(from);
4740175e
DC
121}
122
123static void
124xfs_dir2_sf_put_ino(
125 struct xfs_dir2_sf_hdr *hdr,
c8ce540d 126 uint8_t *to,
4740175e
DC
127 xfs_ino_t ino)
128{
129 ASSERT((ino & 0xff00000000000000ULL) == 0);
130
131 if (hdr->i8count)
266b6969 132 put_unaligned_be64(ino, to);
4740175e 133 else
266b6969 134 put_unaligned_be32(ino, to);
4740175e
DC
135}
136
137static xfs_ino_t
138xfs_dir2_sf_get_parent_ino(
139 struct xfs_dir2_sf_hdr *hdr)
140{
266b6969 141 return xfs_dir2_sf_get_ino(hdr, hdr->parent);
4740175e
DC
142}
143
144static void
145xfs_dir2_sf_put_parent_ino(
146 struct xfs_dir2_sf_hdr *hdr,
147 xfs_ino_t ino)
148{
266b6969 149 xfs_dir2_sf_put_ino(hdr, hdr->parent, ino);
4740175e
DC
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 */
158static xfs_ino_t
159xfs_dir2_sfe_get_ino(
160 struct xfs_dir2_sf_hdr *hdr,
161 struct xfs_dir2_sf_entry *sfep)
162{
266b6969 163 return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen]);
4740175e
DC
164}
165
166static void
167xfs_dir2_sfe_put_ino(
168 struct xfs_dir2_sf_hdr *hdr,
169 struct xfs_dir2_sf_entry *sfep,
170 xfs_ino_t ino)
171{
266b6969 172 xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen], ino);
4740175e
DC
173}
174
175static xfs_ino_t
176xfs_dir3_sfe_get_ino(
177 struct xfs_dir2_sf_hdr *hdr,
178 struct xfs_dir2_sf_entry *sfep)
179{
266b6969 180 return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen + 1]);
4740175e
DC
181}
182
183static void
184xfs_dir3_sfe_put_ino(
185 struct xfs_dir2_sf_hdr *hdr,
186 struct xfs_dir2_sf_entry *sfep,
187 xfs_ino_t ino)
188{
266b6969 189 xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen + 1], ino);
4740175e
DC
190}
191
9d23fc85
DC
192
193/*
194 * Directory data block operations
195 */
9d23fc85 196
1c9a5b2e
DC
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) + \
c8ce540d 216 sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)), \
1c9a5b2e 217 XFS_DIR2_DATA_ALIGN)
9d23fc85
DC
218
219static int
220xfs_dir2_data_entsize(
221 int n)
222{
1c9a5b2e 223 return XFS_DIR2_DATA_ENTSIZE(n);
9d23fc85 224}
1c9a5b2e 225
9d23fc85
DC
226static int
227xfs_dir3_data_entsize(
228 int n)
229{
1c9a5b2e 230 return XFS_DIR3_DATA_ENTSIZE(n);
9d23fc85
DC
231}
232
c8ce540d 233static uint8_t
9d23fc85
DC
234xfs_dir2_data_get_ftype(
235 struct xfs_dir2_data_entry *dep)
236{
237 return XFS_DIR3_FT_UNKNOWN;
238}
239
240static void
241xfs_dir2_data_put_ftype(
242 struct xfs_dir2_data_entry *dep,
c8ce540d 243 uint8_t ftype)
9d23fc85
DC
244{
245 ASSERT(ftype < XFS_DIR3_FT_MAX);
246}
247
c8ce540d 248static uint8_t
9d23fc85
DC
249xfs_dir3_data_get_ftype(
250 struct xfs_dir2_data_entry *dep)
251{
c8ce540d 252 uint8_t ftype = dep->name[dep->namelen];
9d23fc85 253
9d23fc85
DC
254 if (ftype >= XFS_DIR3_FT_MAX)
255 return XFS_DIR3_FT_UNKNOWN;
256 return ftype;
257}
258
259static void
260xfs_dir3_data_put_ftype(
261 struct xfs_dir2_data_entry *dep,
c8ce540d 262 uint8_t type)
9d23fc85
DC
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 */
273static __be16 *
274xfs_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
281static __be16 *
282xfs_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
9d23fc85
DC
289/*
290 * location of . and .. in data space (always block 0)
291 */
292static struct xfs_dir2_data_entry *
293xfs_dir2_data_dot_entry_p(
294 struct xfs_dir2_data_hdr *hdr)
295{
296 return (struct xfs_dir2_data_entry *)
1c9a5b2e 297 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
9d23fc85
DC
298}
299
300static struct xfs_dir2_data_entry *
301xfs_dir2_data_dotdot_entry_p(
302 struct xfs_dir2_data_hdr *hdr)
303{
304 return (struct xfs_dir2_data_entry *)
1c9a5b2e
DC
305 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
306 XFS_DIR2_DATA_ENTSIZE(1));
9d23fc85
DC
307}
308
309static struct xfs_dir2_data_entry *
310xfs_dir2_data_first_entry_p(
311 struct xfs_dir2_data_hdr *hdr)
312{
313 return (struct xfs_dir2_data_entry *)
1c9a5b2e
DC
314 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
315 XFS_DIR2_DATA_ENTSIZE(1) +
316 XFS_DIR2_DATA_ENTSIZE(2));
9d23fc85
DC
317}
318
b01ef655
DC
319static struct xfs_dir2_data_entry *
320xfs_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
328static struct xfs_dir2_data_entry *
329xfs_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
9d23fc85
DC
338static struct xfs_dir2_data_entry *
339xfs_dir3_data_dot_entry_p(
340 struct xfs_dir2_data_hdr *hdr)
341{
342 return (struct xfs_dir2_data_entry *)
1c9a5b2e 343 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
9d23fc85
DC
344}
345
346static struct xfs_dir2_data_entry *
347xfs_dir3_data_dotdot_entry_p(
348 struct xfs_dir2_data_hdr *hdr)
349{
350 return (struct xfs_dir2_data_entry *)
1c9a5b2e
DC
351 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
352 XFS_DIR3_DATA_ENTSIZE(1));
9d23fc85
DC
353}
354
355static struct xfs_dir2_data_entry *
356xfs_dir3_data_first_entry_p(
357 struct xfs_dir2_data_hdr *hdr)
358{
359 return (struct xfs_dir2_data_entry *)
1c9a5b2e
DC
360 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
361 XFS_DIR3_DATA_ENTSIZE(1) +
362 XFS_DIR3_DATA_ENTSIZE(2));
9d23fc85
DC
363}
364
2ca98774
DC
365static struct xfs_dir2_data_free *
366xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
367{
368 return hdr->bestfree;
369}
370
371static struct xfs_dir2_data_free *
372xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
373{
374 return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
375}
376
2ca98774
DC
377static struct xfs_dir2_data_entry *
378xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
379{
380 return (struct xfs_dir2_data_entry *)
1c9a5b2e 381 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
2ca98774
DC
382}
383
384static struct xfs_dir2_data_unused *
385xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr)
386{
387 return (struct xfs_dir2_data_unused *)
1c9a5b2e 388 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
2ca98774
DC
389}
390
391static struct xfs_dir2_data_entry *
392xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
393{
394 return (struct xfs_dir2_data_entry *)
1c9a5b2e 395 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
2ca98774
DC
396}
397
398static struct xfs_dir2_data_unused *
399xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
400{
401 return (struct xfs_dir2_data_unused *)
1c9a5b2e 402 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
2ca98774
DC
403}
404
4141956a
DC
405
406/*
407 * Directory Leaf block operations
408 */
4141956a 409static int
8f66193c 410xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
4141956a 411{
8f66193c 412 return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
4141956a
DC
413 (uint)sizeof(struct xfs_dir2_leaf_entry);
414}
415
416static struct xfs_dir2_leaf_entry *
417xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
418{
419 return lp->__ents;
420}
421
01ba43b8 422static int
8f66193c 423xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
4141956a 424{
8f66193c 425 return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
4141956a
DC
426 (uint)sizeof(struct xfs_dir2_leaf_entry);
427}
428
01ba43b8 429static struct xfs_dir2_leaf_entry *
4141956a
DC
430xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
431{
432 return ((struct xfs_dir3_leaf *)lp)->__ents;
433}
434
01ba43b8
DC
435static void
436xfs_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
450static void
451xfs_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
465static void
466xfs_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
482static void
483xfs_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
4bceb18f
DC
500/*
501 * Directory/Attribute Node block operations
502 */
4bceb18f
DC
503static struct xfs_da_node_entry *
504xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
505{
506 return dap->__btree;
507}
508
1c9a5b2e 509static struct xfs_da_node_entry *
4bceb18f
DC
510xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
511{
512 return ((struct xfs_da3_intnode *)dap)->__btree;
513}
514
01ba43b8
DC
515static void
516xfs_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
528static void
529xfs_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
541static void
542xfs_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
556static void
557xfs_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 */
24dd0f54 575static int
8f66193c 576xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
24dd0f54 577{
8f66193c 578 return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
24dd0f54
DC
579 sizeof(xfs_dir2_data_off_t);
580}
581
582static __be16 *
583xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
584{
1c9a5b2e 585 return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr));
24dd0f54
DC
586}
587
588/*
589 * Convert data space db to the corresponding free db.
590 */
591static xfs_dir2_db_t
8f66193c 592xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
24dd0f54 593{
8f66193c
DC
594 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
595 (db / xfs_dir2_free_max_bests(geo));
24dd0f54
DC
596}
597
598/*
599 * Convert data space db to the corresponding index in a free db.
600 */
601static int
8f66193c 602xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
24dd0f54 603{
8f66193c 604 return db % xfs_dir2_free_max_bests(geo);
24dd0f54
DC
605}
606
24dd0f54 607static int
8f66193c 608xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
24dd0f54 609{
8f66193c 610 return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
24dd0f54
DC
611 sizeof(xfs_dir2_data_off_t);
612}
613
614static __be16 *
615xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
616{
1c9a5b2e 617 return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr));
24dd0f54
DC
618}
619
620/*
621 * Convert data space db to the corresponding free db.
622 */
623static xfs_dir2_db_t
8f66193c 624xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
24dd0f54 625{
8f66193c
DC
626 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
627 (db / xfs_dir3_free_max_bests(geo));
24dd0f54
DC
628}
629
630/*
631 * Convert data space db to the corresponding index in a free db.
632 */
633static int
8f66193c 634xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
24dd0f54 635{
8f66193c 636 return db % xfs_dir3_free_max_bests(geo);
24dd0f54
DC
637}
638
01ba43b8
DC
639static void
640xfs_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
651static void
652xfs_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
664static void
665xfs_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
679static void
680xfs_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
632b89e8 694static const struct xfs_dir_ops xfs_dir2_ops = {
32c5483a
DC
695 .sf_entsize = xfs_dir2_sf_entsize,
696 .sf_nextentry = xfs_dir2_sf_nextentry,
4740175e
DC
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,
9d23fc85
DC
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,
2ca98774 708 .data_bestfree_p = xfs_dir2_data_bestfree_p,
9d23fc85 709
1c9a5b2e
DC
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),
2ca98774 717
9d23fc85
DC
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,
2ca98774
DC
721 .data_entry_p = xfs_dir2_data_entry_p,
722 .data_unused_p = xfs_dir2_data_unused_p,
723
1c9a5b2e 724 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
01ba43b8
DC
725 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
726 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
4141956a
DC
727 .leaf_max_ents = xfs_dir2_max_leaf_ents,
728 .leaf_ents_p = xfs_dir2_leaf_ents_p,
729
1c9a5b2e 730 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
01ba43b8
DC
731 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
732 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
4bceb18f 733 .node_tree_p = xfs_da2_node_tree_p,
01ba43b8 734
1c9a5b2e 735 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
01ba43b8
DC
736 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
737 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
24dd0f54
DC
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,
32c5483a
DC
742};
743
632b89e8 744static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
32c5483a
DC
745 .sf_entsize = xfs_dir3_sf_entsize,
746 .sf_nextentry = xfs_dir3_sf_nextentry,
4740175e
DC
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,
9d23fc85
DC
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,
2ca98774 758 .data_bestfree_p = xfs_dir2_data_bestfree_p,
9d23fc85 759
1c9a5b2e
DC
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),
2ca98774 767
9d23fc85 768 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
b01ef655
DC
769 .data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p,
770 .data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
2ca98774
DC
771 .data_entry_p = xfs_dir2_data_entry_p,
772 .data_unused_p = xfs_dir2_data_unused_p,
4141956a 773
1c9a5b2e 774 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
01ba43b8
DC
775 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
776 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
4141956a
DC
777 .leaf_max_ents = xfs_dir2_max_leaf_ents,
778 .leaf_ents_p = xfs_dir2_leaf_ents_p,
4bceb18f 779
1c9a5b2e 780 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
01ba43b8
DC
781 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
782 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
4bceb18f 783 .node_tree_p = xfs_da2_node_tree_p,
01ba43b8 784
1c9a5b2e 785 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
01ba43b8
DC
786 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
787 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
24dd0f54
DC
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,
32c5483a
DC
792};
793
632b89e8 794static const struct xfs_dir_ops xfs_dir3_ops = {
32c5483a
DC
795 .sf_entsize = xfs_dir3_sf_entsize,
796 .sf_nextentry = xfs_dir3_sf_nextentry,
4740175e
DC
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,
9d23fc85
DC
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,
2ca98774 808 .data_bestfree_p = xfs_dir3_data_bestfree_p,
9d23fc85 809
1c9a5b2e
DC
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),
2ca98774 817
9d23fc85
DC
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,
2ca98774
DC
821 .data_entry_p = xfs_dir3_data_entry_p,
822 .data_unused_p = xfs_dir3_data_unused_p,
4141956a 823
1c9a5b2e 824 .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
01ba43b8
DC
825 .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
826 .leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk,
4141956a
DC
827 .leaf_max_ents = xfs_dir3_max_leaf_ents,
828 .leaf_ents_p = xfs_dir3_leaf_ents_p,
4bceb18f 829
1c9a5b2e 830 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
01ba43b8
DC
831 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
832 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
4bceb18f 833 .node_tree_p = xfs_da3_node_tree_p,
01ba43b8 834
1c9a5b2e 835 .free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
01ba43b8
DC
836 .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
837 .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk,
24dd0f54
DC
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,
4bceb18f
DC
842};
843
632b89e8 844static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
1c9a5b2e 845 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
01ba43b8
DC
846 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
847 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
4bceb18f
DC
848 .node_tree_p = xfs_da2_node_tree_p,
849};
850
632b89e8 851static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
1c9a5b2e 852 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
01ba43b8
DC
853 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
854 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
4bceb18f 855 .node_tree_p = xfs_da3_node_tree_p,
32c5483a 856};
4141956a
DC
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 */
863const struct xfs_dir_ops *
864xfs_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}
4bceb18f
DC
878
879const struct xfs_dir_ops *
880xfs_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}