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