blob: 7e42fdfd2f1de5f0732689de22aadcdf0c07282f [file] [log] [blame]
Dave Chinner32c54832013-10-29 22:11:46 +11001/*
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"
Dave Chinner632b89e2013-10-29 22:11:58 +110021#include "xfs_shared.h"
Dave Chinner32c54832013-10-29 22:11:46 +110022#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"
Dave Chinner892e3f32014-06-06 15:04:05 +100029#include "xfs_da_btree.h"
Dave Chinner32c54832013-10-29 22:11:46 +110030#include "xfs_inode.h"
31#include "xfs_dir2.h"
Dave Chinner892e3f32014-06-06 15:04:05 +100032#include "xfs_dir2_priv.h"
Dave Chinner32c54832013-10-29 22:11:46 +110033
Dave Chinner9d23fc82013-10-29 22:11:48 +110034/*
35 * Shortform directory ops
36 */
Dave Chinner32c54832013-10-29 22:11:46 +110037static 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
Dave Chinner47401752013-10-29 22:11:47 +110077/*
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
Dave Chinner9d23fc82013-10-29 22:11:48 +1100211
212/*
213 * Directory data block operations
214 */
Dave Chinner9d23fc82013-10-29 22:11:48 +1100215
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100216/*
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)
Dave Chinner9d23fc82013-10-29 22:11:48 +1100237
238static int
239xfs_dir2_data_entsize(
240 int n)
241{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100242 return XFS_DIR2_DATA_ENTSIZE(n);
Dave Chinner9d23fc82013-10-29 22:11:48 +1100243}
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100244
Dave Chinner9d23fc82013-10-29 22:11:48 +1100245static int
246xfs_dir3_data_entsize(
247 int n)
248{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100249 return XFS_DIR3_DATA_ENTSIZE(n);
Dave Chinner9d23fc82013-10-29 22:11:48 +1100250}
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
Dave Chinner9d23fc82013-10-29 22:11:48 +1100273 if (ftype >= XFS_DIR3_FT_MAX)
274 return XFS_DIR3_FT_UNKNOWN;
275 return ftype;
276}
277
278static void
279xfs_dir3_data_put_ftype(
280 struct xfs_dir2_data_entry *dep,
281 __uint8_t type)
282{
283 ASSERT(type < XFS_DIR3_FT_MAX);
284 ASSERT(dep->namelen != 0);
285
286 dep->name[dep->namelen] = type;
287}
288
289/*
290 * Pointer to an entry's tag word.
291 */
292static __be16 *
293xfs_dir2_data_entry_tag_p(
294 struct xfs_dir2_data_entry *dep)
295{
296 return (__be16 *)((char *)dep +
297 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
298}
299
300static __be16 *
301xfs_dir3_data_entry_tag_p(
302 struct xfs_dir2_data_entry *dep)
303{
304 return (__be16 *)((char *)dep +
305 xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
306}
307
308/*
Dave Chinner9d23fc82013-10-29 22:11:48 +1100309 * location of . and .. in data space (always block 0)
310 */
311static struct xfs_dir2_data_entry *
312xfs_dir2_data_dot_entry_p(
313 struct xfs_dir2_data_hdr *hdr)
314{
315 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100316 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100317}
318
319static struct xfs_dir2_data_entry *
320xfs_dir2_data_dotdot_entry_p(
321 struct xfs_dir2_data_hdr *hdr)
322{
323 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100324 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
325 XFS_DIR2_DATA_ENTSIZE(1));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100326}
327
328static struct xfs_dir2_data_entry *
329xfs_dir2_data_first_entry_p(
330 struct xfs_dir2_data_hdr *hdr)
331{
332 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100333 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
334 XFS_DIR2_DATA_ENTSIZE(1) +
335 XFS_DIR2_DATA_ENTSIZE(2));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100336}
337
338static struct xfs_dir2_data_entry *
Dave Chinnerb01ef652013-10-29 22:11:55 +1100339xfs_dir2_ftype_data_dotdot_entry_p(
340 struct xfs_dir2_data_hdr *hdr)
341{
342 return (struct xfs_dir2_data_entry *)
343 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
344 XFS_DIR3_DATA_ENTSIZE(1));
345}
346
347static struct xfs_dir2_data_entry *
348xfs_dir2_ftype_data_first_entry_p(
349 struct xfs_dir2_data_hdr *hdr)
350{
351 return (struct xfs_dir2_data_entry *)
352 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
353 XFS_DIR3_DATA_ENTSIZE(1) +
354 XFS_DIR3_DATA_ENTSIZE(2));
355}
356
357static struct xfs_dir2_data_entry *
Dave Chinner9d23fc82013-10-29 22:11:48 +1100358xfs_dir3_data_dot_entry_p(
359 struct xfs_dir2_data_hdr *hdr)
360{
361 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100362 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100363}
364
365static struct xfs_dir2_data_entry *
366xfs_dir3_data_dotdot_entry_p(
367 struct xfs_dir2_data_hdr *hdr)
368{
369 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100370 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
371 XFS_DIR3_DATA_ENTSIZE(1));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100372}
373
374static struct xfs_dir2_data_entry *
375xfs_dir3_data_first_entry_p(
376 struct xfs_dir2_data_hdr *hdr)
377{
378 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100379 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
380 XFS_DIR3_DATA_ENTSIZE(1) +
381 XFS_DIR3_DATA_ENTSIZE(2));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100382}
383
Dave Chinner2ca98772013-10-29 22:11:49 +1100384static struct xfs_dir2_data_free *
385xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
386{
387 return hdr->bestfree;
388}
389
390static struct xfs_dir2_data_free *
391xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
392{
393 return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
394}
395
Dave Chinner2ca98772013-10-29 22:11:49 +1100396static struct xfs_dir2_data_entry *
397xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
398{
399 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100400 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100401}
402
403static struct xfs_dir2_data_unused *
404xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr)
405{
406 return (struct xfs_dir2_data_unused *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100407 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100408}
409
410static struct xfs_dir2_data_entry *
411xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
412{
413 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100414 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100415}
416
417static struct xfs_dir2_data_unused *
418xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
419{
420 return (struct xfs_dir2_data_unused *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100421 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100422}
423
Dave Chinner41419562013-10-29 22:11:50 +1100424
425/*
426 * Directory Leaf block operations
427 */
428static int
Dave Chinner8f661932014-06-06 15:15:59 +1000429xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
Dave Chinner41419562013-10-29 22:11:50 +1100430{
Dave Chinner8f661932014-06-06 15:15:59 +1000431 return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
Dave Chinner41419562013-10-29 22:11:50 +1100432 (uint)sizeof(struct xfs_dir2_leaf_entry);
433}
434
435static struct xfs_dir2_leaf_entry *
436xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
437{
438 return lp->__ents;
439}
440
441static int
Dave Chinner8f661932014-06-06 15:15:59 +1000442xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
Dave Chinner41419562013-10-29 22:11:50 +1100443{
Dave Chinner8f661932014-06-06 15:15:59 +1000444 return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
Dave Chinner41419562013-10-29 22:11:50 +1100445 (uint)sizeof(struct xfs_dir2_leaf_entry);
446}
447
Dave Chinner01ba43b2013-10-29 22:11:52 +1100448static struct xfs_dir2_leaf_entry *
Dave Chinner41419562013-10-29 22:11:50 +1100449xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
450{
451 return ((struct xfs_dir3_leaf *)lp)->__ents;
452}
453
Dave Chinner01ba43b2013-10-29 22:11:52 +1100454static void
455xfs_dir2_leaf_hdr_from_disk(
456 struct xfs_dir3_icleaf_hdr *to,
457 struct xfs_dir2_leaf *from)
458{
459 to->forw = be32_to_cpu(from->hdr.info.forw);
460 to->back = be32_to_cpu(from->hdr.info.back);
461 to->magic = be16_to_cpu(from->hdr.info.magic);
462 to->count = be16_to_cpu(from->hdr.count);
463 to->stale = be16_to_cpu(from->hdr.stale);
464
465 ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
466 to->magic == XFS_DIR2_LEAFN_MAGIC);
467}
468
469static void
470xfs_dir2_leaf_hdr_to_disk(
471 struct xfs_dir2_leaf *to,
472 struct xfs_dir3_icleaf_hdr *from)
473{
474 ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
475 from->magic == XFS_DIR2_LEAFN_MAGIC);
476
477 to->hdr.info.forw = cpu_to_be32(from->forw);
478 to->hdr.info.back = cpu_to_be32(from->back);
479 to->hdr.info.magic = cpu_to_be16(from->magic);
480 to->hdr.count = cpu_to_be16(from->count);
481 to->hdr.stale = cpu_to_be16(from->stale);
482}
483
484static void
485xfs_dir3_leaf_hdr_from_disk(
486 struct xfs_dir3_icleaf_hdr *to,
487 struct xfs_dir2_leaf *from)
488{
489 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from;
490
491 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
492 to->back = be32_to_cpu(hdr3->info.hdr.back);
493 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
494 to->count = be16_to_cpu(hdr3->count);
495 to->stale = be16_to_cpu(hdr3->stale);
496
497 ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
498 to->magic == XFS_DIR3_LEAFN_MAGIC);
499}
500
501static void
502xfs_dir3_leaf_hdr_to_disk(
503 struct xfs_dir2_leaf *to,
504 struct xfs_dir3_icleaf_hdr *from)
505{
506 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to;
507
508 ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC ||
509 from->magic == XFS_DIR3_LEAFN_MAGIC);
510
511 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
512 hdr3->info.hdr.back = cpu_to_be32(from->back);
513 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
514 hdr3->count = cpu_to_be16(from->count);
515 hdr3->stale = cpu_to_be16(from->stale);
516}
517
518
Dave Chinner4bceb182013-10-29 22:11:51 +1100519/*
520 * Directory/Attribute Node block operations
521 */
Dave Chinner4bceb182013-10-29 22:11:51 +1100522static struct xfs_da_node_entry *
523xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
524{
525 return dap->__btree;
526}
527
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100528static struct xfs_da_node_entry *
Dave Chinner4bceb182013-10-29 22:11:51 +1100529xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
530{
531 return ((struct xfs_da3_intnode *)dap)->__btree;
532}
533
Dave Chinner01ba43b2013-10-29 22:11:52 +1100534static void
535xfs_da2_node_hdr_from_disk(
536 struct xfs_da3_icnode_hdr *to,
537 struct xfs_da_intnode *from)
538{
539 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
540 to->forw = be32_to_cpu(from->hdr.info.forw);
541 to->back = be32_to_cpu(from->hdr.info.back);
542 to->magic = be16_to_cpu(from->hdr.info.magic);
543 to->count = be16_to_cpu(from->hdr.__count);
544 to->level = be16_to_cpu(from->hdr.__level);
545}
546
547static void
548xfs_da2_node_hdr_to_disk(
549 struct xfs_da_intnode *to,
550 struct xfs_da3_icnode_hdr *from)
551{
552 ASSERT(from->magic == XFS_DA_NODE_MAGIC);
553 to->hdr.info.forw = cpu_to_be32(from->forw);
554 to->hdr.info.back = cpu_to_be32(from->back);
555 to->hdr.info.magic = cpu_to_be16(from->magic);
556 to->hdr.__count = cpu_to_be16(from->count);
557 to->hdr.__level = cpu_to_be16(from->level);
558}
559
560static void
561xfs_da3_node_hdr_from_disk(
562 struct xfs_da3_icnode_hdr *to,
563 struct xfs_da_intnode *from)
564{
565 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from;
566
567 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
568 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
569 to->back = be32_to_cpu(hdr3->info.hdr.back);
570 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
571 to->count = be16_to_cpu(hdr3->__count);
572 to->level = be16_to_cpu(hdr3->__level);
573}
574
575static void
576xfs_da3_node_hdr_to_disk(
577 struct xfs_da_intnode *to,
578 struct xfs_da3_icnode_hdr *from)
579{
580 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to;
581
582 ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
583 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
584 hdr3->info.hdr.back = cpu_to_be32(from->back);
585 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
586 hdr3->__count = cpu_to_be16(from->count);
587 hdr3->__level = cpu_to_be16(from->level);
588}
589
590
591/*
592 * Directory free space block operations
593 */
Dave Chinner24dd0f52013-10-30 13:48:41 -0500594static int
Dave Chinner8f661932014-06-06 15:15:59 +1000595xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
Dave Chinner24dd0f52013-10-30 13:48:41 -0500596{
Dave Chinner8f661932014-06-06 15:15:59 +1000597 return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
Dave Chinner24dd0f52013-10-30 13:48:41 -0500598 sizeof(xfs_dir2_data_off_t);
599}
600
601static __be16 *
602xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
603{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100604 return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr));
Dave Chinner24dd0f52013-10-30 13:48:41 -0500605}
606
607/*
608 * Convert data space db to the corresponding free db.
609 */
610static xfs_dir2_db_t
Dave Chinner8f661932014-06-06 15:15:59 +1000611xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
Dave Chinner24dd0f52013-10-30 13:48:41 -0500612{
Dave Chinner8f661932014-06-06 15:15:59 +1000613 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
614 (db / xfs_dir2_free_max_bests(geo));
Dave Chinner24dd0f52013-10-30 13:48:41 -0500615}
616
617/*
618 * Convert data space db to the corresponding index in a free db.
619 */
620static int
Dave Chinner8f661932014-06-06 15:15:59 +1000621xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
Dave Chinner24dd0f52013-10-30 13:48:41 -0500622{
Dave Chinner8f661932014-06-06 15:15:59 +1000623 return db % xfs_dir2_free_max_bests(geo);
Dave Chinner24dd0f52013-10-30 13:48:41 -0500624}
625
626static int
Dave Chinner8f661932014-06-06 15:15:59 +1000627xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
Dave Chinner24dd0f52013-10-30 13:48:41 -0500628{
Dave Chinner8f661932014-06-06 15:15:59 +1000629 return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
Dave Chinner24dd0f52013-10-30 13:48:41 -0500630 sizeof(xfs_dir2_data_off_t);
631}
632
633static __be16 *
634xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
635{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100636 return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr));
Dave Chinner24dd0f52013-10-30 13:48:41 -0500637}
638
639/*
640 * Convert data space db to the corresponding free db.
641 */
642static xfs_dir2_db_t
Dave Chinner8f661932014-06-06 15:15:59 +1000643xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
Dave Chinner24dd0f52013-10-30 13:48:41 -0500644{
Dave Chinner8f661932014-06-06 15:15:59 +1000645 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
646 (db / xfs_dir3_free_max_bests(geo));
Dave Chinner24dd0f52013-10-30 13:48:41 -0500647}
648
649/*
650 * Convert data space db to the corresponding index in a free db.
651 */
652static int
Dave Chinner8f661932014-06-06 15:15:59 +1000653xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
Dave Chinner24dd0f52013-10-30 13:48:41 -0500654{
Dave Chinner8f661932014-06-06 15:15:59 +1000655 return db % xfs_dir3_free_max_bests(geo);
Dave Chinner24dd0f52013-10-30 13:48:41 -0500656}
657
Dave Chinner01ba43b2013-10-29 22:11:52 +1100658static void
659xfs_dir2_free_hdr_from_disk(
660 struct xfs_dir3_icfree_hdr *to,
661 struct xfs_dir2_free *from)
662{
663 to->magic = be32_to_cpu(from->hdr.magic);
664 to->firstdb = be32_to_cpu(from->hdr.firstdb);
665 to->nvalid = be32_to_cpu(from->hdr.nvalid);
666 to->nused = be32_to_cpu(from->hdr.nused);
667 ASSERT(to->magic == XFS_DIR2_FREE_MAGIC);
668}
669
670static void
671xfs_dir2_free_hdr_to_disk(
672 struct xfs_dir2_free *to,
673 struct xfs_dir3_icfree_hdr *from)
674{
675 ASSERT(from->magic == XFS_DIR2_FREE_MAGIC);
676
677 to->hdr.magic = cpu_to_be32(from->magic);
678 to->hdr.firstdb = cpu_to_be32(from->firstdb);
679 to->hdr.nvalid = cpu_to_be32(from->nvalid);
680 to->hdr.nused = cpu_to_be32(from->nused);
681}
682
683static void
684xfs_dir3_free_hdr_from_disk(
685 struct xfs_dir3_icfree_hdr *to,
686 struct xfs_dir2_free *from)
687{
688 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from;
689
690 to->magic = be32_to_cpu(hdr3->hdr.magic);
691 to->firstdb = be32_to_cpu(hdr3->firstdb);
692 to->nvalid = be32_to_cpu(hdr3->nvalid);
693 to->nused = be32_to_cpu(hdr3->nused);
694
695 ASSERT(to->magic == XFS_DIR3_FREE_MAGIC);
696}
697
698static void
699xfs_dir3_free_hdr_to_disk(
700 struct xfs_dir2_free *to,
701 struct xfs_dir3_icfree_hdr *from)
702{
703 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to;
704
705 ASSERT(from->magic == XFS_DIR3_FREE_MAGIC);
706
707 hdr3->hdr.magic = cpu_to_be32(from->magic);
708 hdr3->firstdb = cpu_to_be32(from->firstdb);
709 hdr3->nvalid = cpu_to_be32(from->nvalid);
710 hdr3->nused = cpu_to_be32(from->nused);
711}
712
Dave Chinner632b89e2013-10-29 22:11:58 +1100713static const struct xfs_dir_ops xfs_dir2_ops = {
Dave Chinner32c54832013-10-29 22:11:46 +1100714 .sf_entsize = xfs_dir2_sf_entsize,
715 .sf_nextentry = xfs_dir2_sf_nextentry,
Dave Chinner47401752013-10-29 22:11:47 +1100716 .sf_get_ftype = xfs_dir2_sfe_get_ftype,
717 .sf_put_ftype = xfs_dir2_sfe_put_ftype,
718 .sf_get_ino = xfs_dir2_sfe_get_ino,
719 .sf_put_ino = xfs_dir2_sfe_put_ino,
720 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
721 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100722
723 .data_entsize = xfs_dir2_data_entsize,
724 .data_get_ftype = xfs_dir2_data_get_ftype,
725 .data_put_ftype = xfs_dir2_data_put_ftype,
726 .data_entry_tag_p = xfs_dir2_data_entry_tag_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100727 .data_bestfree_p = xfs_dir2_data_bestfree_p,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100728
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100729 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
730 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
731 XFS_DIR2_DATA_ENTSIZE(1),
732 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) +
733 XFS_DIR2_DATA_ENTSIZE(1) +
734 XFS_DIR2_DATA_ENTSIZE(2),
735 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
Dave Chinner2ca98772013-10-29 22:11:49 +1100736
Dave Chinner9d23fc82013-10-29 22:11:48 +1100737 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
738 .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
739 .data_first_entry_p = xfs_dir2_data_first_entry_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100740 .data_entry_p = xfs_dir2_data_entry_p,
741 .data_unused_p = xfs_dir2_data_unused_p,
742
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100743 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100744 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
745 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
Dave Chinner41419562013-10-29 22:11:50 +1100746 .leaf_max_ents = xfs_dir2_max_leaf_ents,
747 .leaf_ents_p = xfs_dir2_leaf_ents_p,
748
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100749 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100750 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
751 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100752 .node_tree_p = xfs_da2_node_tree_p,
Dave Chinner01ba43b2013-10-29 22:11:52 +1100753
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100754 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100755 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
756 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
Dave Chinner24dd0f52013-10-30 13:48:41 -0500757 .free_max_bests = xfs_dir2_free_max_bests,
758 .free_bests_p = xfs_dir2_free_bests_p,
759 .db_to_fdb = xfs_dir2_db_to_fdb,
760 .db_to_fdindex = xfs_dir2_db_to_fdindex,
Dave Chinner32c54832013-10-29 22:11:46 +1100761};
762
Dave Chinner632b89e2013-10-29 22:11:58 +1100763static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
Dave Chinner32c54832013-10-29 22:11:46 +1100764 .sf_entsize = xfs_dir3_sf_entsize,
765 .sf_nextentry = xfs_dir3_sf_nextentry,
Dave Chinner47401752013-10-29 22:11:47 +1100766 .sf_get_ftype = xfs_dir3_sfe_get_ftype,
767 .sf_put_ftype = xfs_dir3_sfe_put_ftype,
768 .sf_get_ino = xfs_dir3_sfe_get_ino,
769 .sf_put_ino = xfs_dir3_sfe_put_ino,
770 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
771 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100772
773 .data_entsize = xfs_dir3_data_entsize,
774 .data_get_ftype = xfs_dir3_data_get_ftype,
775 .data_put_ftype = xfs_dir3_data_put_ftype,
776 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100777 .data_bestfree_p = xfs_dir2_data_bestfree_p,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100778
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100779 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
780 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
781 XFS_DIR3_DATA_ENTSIZE(1),
782 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) +
783 XFS_DIR3_DATA_ENTSIZE(1) +
784 XFS_DIR3_DATA_ENTSIZE(2),
785 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
Dave Chinner2ca98772013-10-29 22:11:49 +1100786
Dave Chinner9d23fc82013-10-29 22:11:48 +1100787 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
Dave Chinnerb01ef652013-10-29 22:11:55 +1100788 .data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p,
789 .data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100790 .data_entry_p = xfs_dir2_data_entry_p,
791 .data_unused_p = xfs_dir2_data_unused_p,
Dave Chinner41419562013-10-29 22:11:50 +1100792
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100793 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100794 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
795 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
Dave Chinner41419562013-10-29 22:11:50 +1100796 .leaf_max_ents = xfs_dir2_max_leaf_ents,
797 .leaf_ents_p = xfs_dir2_leaf_ents_p,
Dave Chinner4bceb182013-10-29 22:11:51 +1100798
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100799 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100800 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
801 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100802 .node_tree_p = xfs_da2_node_tree_p,
Dave Chinner01ba43b2013-10-29 22:11:52 +1100803
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100804 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100805 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
806 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
Dave Chinner24dd0f52013-10-30 13:48:41 -0500807 .free_max_bests = xfs_dir2_free_max_bests,
808 .free_bests_p = xfs_dir2_free_bests_p,
809 .db_to_fdb = xfs_dir2_db_to_fdb,
810 .db_to_fdindex = xfs_dir2_db_to_fdindex,
Dave Chinner32c54832013-10-29 22:11:46 +1100811};
812
Dave Chinner632b89e2013-10-29 22:11:58 +1100813static const struct xfs_dir_ops xfs_dir3_ops = {
Dave Chinner32c54832013-10-29 22:11:46 +1100814 .sf_entsize = xfs_dir3_sf_entsize,
815 .sf_nextentry = xfs_dir3_sf_nextentry,
Dave Chinner47401752013-10-29 22:11:47 +1100816 .sf_get_ftype = xfs_dir3_sfe_get_ftype,
817 .sf_put_ftype = xfs_dir3_sfe_put_ftype,
818 .sf_get_ino = xfs_dir3_sfe_get_ino,
819 .sf_put_ino = xfs_dir3_sfe_put_ino,
820 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
821 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100822
823 .data_entsize = xfs_dir3_data_entsize,
824 .data_get_ftype = xfs_dir3_data_get_ftype,
825 .data_put_ftype = xfs_dir3_data_put_ftype,
826 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100827 .data_bestfree_p = xfs_dir3_data_bestfree_p,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100828
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100829 .data_dot_offset = sizeof(struct xfs_dir3_data_hdr),
830 .data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) +
831 XFS_DIR3_DATA_ENTSIZE(1),
832 .data_first_offset = sizeof(struct xfs_dir3_data_hdr) +
833 XFS_DIR3_DATA_ENTSIZE(1) +
834 XFS_DIR3_DATA_ENTSIZE(2),
835 .data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
Dave Chinner2ca98772013-10-29 22:11:49 +1100836
Dave Chinner9d23fc82013-10-29 22:11:48 +1100837 .data_dot_entry_p = xfs_dir3_data_dot_entry_p,
838 .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p,
839 .data_first_entry_p = xfs_dir3_data_first_entry_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100840 .data_entry_p = xfs_dir3_data_entry_p,
841 .data_unused_p = xfs_dir3_data_unused_p,
Dave Chinner41419562013-10-29 22:11:50 +1100842
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100843 .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100844 .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
845 .leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk,
Dave Chinner41419562013-10-29 22:11:50 +1100846 .leaf_max_ents = xfs_dir3_max_leaf_ents,
847 .leaf_ents_p = xfs_dir3_leaf_ents_p,
Dave Chinner4bceb182013-10-29 22:11:51 +1100848
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100849 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100850 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
851 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100852 .node_tree_p = xfs_da3_node_tree_p,
Dave Chinner01ba43b2013-10-29 22:11:52 +1100853
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100854 .free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100855 .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
856 .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk,
Dave Chinner24dd0f52013-10-30 13:48:41 -0500857 .free_max_bests = xfs_dir3_free_max_bests,
858 .free_bests_p = xfs_dir3_free_bests_p,
859 .db_to_fdb = xfs_dir3_db_to_fdb,
860 .db_to_fdindex = xfs_dir3_db_to_fdindex,
Dave Chinner4bceb182013-10-29 22:11:51 +1100861};
862
Dave Chinner632b89e2013-10-29 22:11:58 +1100863static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100864 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100865 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
866 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100867 .node_tree_p = xfs_da2_node_tree_p,
868};
869
Dave Chinner632b89e2013-10-29 22:11:58 +1100870static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100871 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100872 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
873 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100874 .node_tree_p = xfs_da3_node_tree_p,
Dave Chinner32c54832013-10-29 22:11:46 +1100875};
Dave Chinner41419562013-10-29 22:11:50 +1100876
877/*
878 * Return the ops structure according to the current config. If we are passed
879 * an inode, then that overrides the default config we use which is based on
880 * feature bits.
881 */
882const struct xfs_dir_ops *
883xfs_dir_get_ops(
884 struct xfs_mount *mp,
885 struct xfs_inode *dp)
886{
887 if (dp)
888 return dp->d_ops;
889 if (mp->m_dir_inode_ops)
890 return mp->m_dir_inode_ops;
891 if (xfs_sb_version_hascrc(&mp->m_sb))
892 return &xfs_dir3_ops;
893 if (xfs_sb_version_hasftype(&mp->m_sb))
894 return &xfs_dir2_ftype_ops;
895 return &xfs_dir2_ops;
896}
Dave Chinner4bceb182013-10-29 22:11:51 +1100897
898const struct xfs_dir_ops *
899xfs_nondir_get_ops(
900 struct xfs_mount *mp,
901 struct xfs_inode *dp)
902{
903 if (dp)
904 return dp->d_ops;
905 if (mp->m_nondir_inode_ops)
906 return mp->m_nondir_inode_ops;
907 if (xfs_sb_version_hascrc(&mp->m_sb))
908 return &xfs_dir3_nondir_ops;
909 return &xfs_dir2_nondir_ops;
910}