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