blob: e6c83e1fbc8a786bfde2af6aad97e58c8bb19bd7 [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"
29#include "xfs_inode.h"
30#include "xfs_dir2.h"
31
Dave Chinner9d23fc82013-10-29 22:11:48 +110032/*
33 * Shortform directory ops
34 */
Dave Chinner32c54832013-10-29 22:11:46 +110035static int
36xfs_dir2_sf_entsize(
37 struct xfs_dir2_sf_hdr *hdr,
38 int len)
39{
40 int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */
41
42 count += len; /* name */
43 count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) :
44 sizeof(xfs_dir2_ino4_t); /* ino # */
45 return count;
46}
47
48static int
49xfs_dir3_sf_entsize(
50 struct xfs_dir2_sf_hdr *hdr,
51 int len)
52{
53 return xfs_dir2_sf_entsize(hdr, len) + sizeof(__uint8_t);
54}
55
56static struct xfs_dir2_sf_entry *
57xfs_dir2_sf_nextentry(
58 struct xfs_dir2_sf_hdr *hdr,
59 struct xfs_dir2_sf_entry *sfep)
60{
61 return (struct xfs_dir2_sf_entry *)
62 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
63}
64
65static struct xfs_dir2_sf_entry *
66xfs_dir3_sf_nextentry(
67 struct xfs_dir2_sf_hdr *hdr,
68 struct xfs_dir2_sf_entry *sfep)
69{
70 return (struct xfs_dir2_sf_entry *)
71 ((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen));
72}
73
74
Dave Chinner47401752013-10-29 22:11:47 +110075/*
76 * For filetype enabled shortform directories, the file type field is stored at
77 * the end of the name. Because it's only a single byte, endian conversion is
78 * not necessary. For non-filetype enable directories, the type is always
79 * unknown and we never store the value.
80 */
81static __uint8_t
82xfs_dir2_sfe_get_ftype(
83 struct xfs_dir2_sf_entry *sfep)
84{
85 return XFS_DIR3_FT_UNKNOWN;
86}
87
88static void
89xfs_dir2_sfe_put_ftype(
90 struct xfs_dir2_sf_entry *sfep,
91 __uint8_t ftype)
92{
93 ASSERT(ftype < XFS_DIR3_FT_MAX);
94}
95
96static __uint8_t
97xfs_dir3_sfe_get_ftype(
98 struct xfs_dir2_sf_entry *sfep)
99{
100 __uint8_t ftype;
101
102 ftype = sfep->name[sfep->namelen];
103 if (ftype >= XFS_DIR3_FT_MAX)
104 return XFS_DIR3_FT_UNKNOWN;
105 return ftype;
106}
107
108static void
109xfs_dir3_sfe_put_ftype(
110 struct xfs_dir2_sf_entry *sfep,
111 __uint8_t ftype)
112{
113 ASSERT(ftype < XFS_DIR3_FT_MAX);
114
115 sfep->name[sfep->namelen] = ftype;
116}
117
118/*
119 * Inode numbers in short-form directories can come in two versions,
120 * either 4 bytes or 8 bytes wide. These helpers deal with the
121 * two forms transparently by looking at the headers i8count field.
122 *
123 * For 64-bit inode number the most significant byte must be zero.
124 */
125static xfs_ino_t
126xfs_dir2_sf_get_ino(
127 struct xfs_dir2_sf_hdr *hdr,
128 xfs_dir2_inou_t *from)
129{
130 if (hdr->i8count)
131 return get_unaligned_be64(&from->i8.i) & 0x00ffffffffffffffULL;
132 else
133 return get_unaligned_be32(&from->i4.i);
134}
135
136static void
137xfs_dir2_sf_put_ino(
138 struct xfs_dir2_sf_hdr *hdr,
139 xfs_dir2_inou_t *to,
140 xfs_ino_t ino)
141{
142 ASSERT((ino & 0xff00000000000000ULL) == 0);
143
144 if (hdr->i8count)
145 put_unaligned_be64(ino, &to->i8.i);
146 else
147 put_unaligned_be32(ino, &to->i4.i);
148}
149
150static xfs_ino_t
151xfs_dir2_sf_get_parent_ino(
152 struct xfs_dir2_sf_hdr *hdr)
153{
154 return xfs_dir2_sf_get_ino(hdr, &hdr->parent);
155}
156
157static void
158xfs_dir2_sf_put_parent_ino(
159 struct xfs_dir2_sf_hdr *hdr,
160 xfs_ino_t ino)
161{
162 xfs_dir2_sf_put_ino(hdr, &hdr->parent, ino);
163}
164
165/*
166 * In short-form directory entries the inode numbers are stored at variable
167 * offset behind the entry name. If the entry stores a filetype value, then it
168 * sits between the name and the inode number. Hence the inode numbers may only
169 * be accessed through the helpers below.
170 */
171static xfs_ino_t
172xfs_dir2_sfe_get_ino(
173 struct xfs_dir2_sf_hdr *hdr,
174 struct xfs_dir2_sf_entry *sfep)
175{
176 return xfs_dir2_sf_get_ino(hdr,
177 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen]);
178}
179
180static void
181xfs_dir2_sfe_put_ino(
182 struct xfs_dir2_sf_hdr *hdr,
183 struct xfs_dir2_sf_entry *sfep,
184 xfs_ino_t ino)
185{
186 xfs_dir2_sf_put_ino(hdr,
187 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen], ino);
188}
189
190static xfs_ino_t
191xfs_dir3_sfe_get_ino(
192 struct xfs_dir2_sf_hdr *hdr,
193 struct xfs_dir2_sf_entry *sfep)
194{
195 return xfs_dir2_sf_get_ino(hdr,
196 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1]);
197}
198
199static void
200xfs_dir3_sfe_put_ino(
201 struct xfs_dir2_sf_hdr *hdr,
202 struct xfs_dir2_sf_entry *sfep,
203 xfs_ino_t ino)
204{
205 xfs_dir2_sf_put_ino(hdr,
206 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1], ino);
207}
208
Dave Chinner9d23fc82013-10-29 22:11:48 +1100209
210/*
211 * Directory data block operations
212 */
Dave Chinner9d23fc82013-10-29 22:11:48 +1100213
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100214/*
215 * For special situations, the dirent size ends up fixed because we always know
216 * what the size of the entry is. That's true for the "." and "..", and
217 * therefore we know that they are a fixed size and hence their offsets are
218 * constant, as is the first entry.
219 *
220 * Hence, this calculation is written as a macro to be able to be calculated at
221 * compile time and so certain offsets can be calculated directly in the
222 * structure initaliser via the macro. There are two macros - one for dirents
223 * with ftype and without so there are no unresolvable conditionals in the
224 * calculations. We also use round_up() as XFS_DIR2_DATA_ALIGN is always a power
225 * of 2 and the compiler doesn't reject it (unlike roundup()).
226 */
227#define XFS_DIR2_DATA_ENTSIZE(n) \
228 round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \
229 sizeof(xfs_dir2_data_off_t)), XFS_DIR2_DATA_ALIGN)
230
231#define XFS_DIR3_DATA_ENTSIZE(n) \
232 round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \
233 sizeof(xfs_dir2_data_off_t) + sizeof(__uint8_t)), \
234 XFS_DIR2_DATA_ALIGN)
Dave Chinner9d23fc82013-10-29 22:11:48 +1100235
236static int
237xfs_dir2_data_entsize(
238 int n)
239{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100240 return XFS_DIR2_DATA_ENTSIZE(n);
Dave Chinner9d23fc82013-10-29 22:11:48 +1100241}
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100242
Dave Chinner9d23fc82013-10-29 22:11:48 +1100243static int
244xfs_dir3_data_entsize(
245 int n)
246{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100247 return XFS_DIR3_DATA_ENTSIZE(n);
Dave Chinner9d23fc82013-10-29 22:11:48 +1100248}
249
250static __uint8_t
251xfs_dir2_data_get_ftype(
252 struct xfs_dir2_data_entry *dep)
253{
254 return XFS_DIR3_FT_UNKNOWN;
255}
256
257static void
258xfs_dir2_data_put_ftype(
259 struct xfs_dir2_data_entry *dep,
260 __uint8_t ftype)
261{
262 ASSERT(ftype < XFS_DIR3_FT_MAX);
263}
264
265static __uint8_t
266xfs_dir3_data_get_ftype(
267 struct xfs_dir2_data_entry *dep)
268{
269 __uint8_t ftype = dep->name[dep->namelen];
270
271 ASSERT(ftype < XFS_DIR3_FT_MAX);
272 if (ftype >= XFS_DIR3_FT_MAX)
273 return XFS_DIR3_FT_UNKNOWN;
274 return ftype;
275}
276
277static void
278xfs_dir3_data_put_ftype(
279 struct xfs_dir2_data_entry *dep,
280 __uint8_t type)
281{
282 ASSERT(type < XFS_DIR3_FT_MAX);
283 ASSERT(dep->namelen != 0);
284
285 dep->name[dep->namelen] = type;
286}
287
288/*
289 * Pointer to an entry's tag word.
290 */
291static __be16 *
292xfs_dir2_data_entry_tag_p(
293 struct xfs_dir2_data_entry *dep)
294{
295 return (__be16 *)((char *)dep +
296 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
297}
298
299static __be16 *
300xfs_dir3_data_entry_tag_p(
301 struct xfs_dir2_data_entry *dep)
302{
303 return (__be16 *)((char *)dep +
304 xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
305}
306
307/*
Dave Chinner9d23fc82013-10-29 22:11:48 +1100308 * location of . and .. in data space (always block 0)
309 */
310static struct xfs_dir2_data_entry *
311xfs_dir2_data_dot_entry_p(
312 struct xfs_dir2_data_hdr *hdr)
313{
314 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100315 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100316}
317
318static struct xfs_dir2_data_entry *
319xfs_dir2_data_dotdot_entry_p(
320 struct xfs_dir2_data_hdr *hdr)
321{
322 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100323 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
324 XFS_DIR2_DATA_ENTSIZE(1));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100325}
326
327static struct xfs_dir2_data_entry *
328xfs_dir2_data_first_entry_p(
329 struct xfs_dir2_data_hdr *hdr)
330{
331 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100332 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
333 XFS_DIR2_DATA_ENTSIZE(1) +
334 XFS_DIR2_DATA_ENTSIZE(2));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100335}
336
337static struct xfs_dir2_data_entry *
Dave Chinnerb01ef652013-10-29 22:11:55 +1100338xfs_dir2_ftype_data_dotdot_entry_p(
339 struct xfs_dir2_data_hdr *hdr)
340{
341 return (struct xfs_dir2_data_entry *)
342 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
343 XFS_DIR3_DATA_ENTSIZE(1));
344}
345
346static struct xfs_dir2_data_entry *
347xfs_dir2_ftype_data_first_entry_p(
348 struct xfs_dir2_data_hdr *hdr)
349{
350 return (struct xfs_dir2_data_entry *)
351 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
352 XFS_DIR3_DATA_ENTSIZE(1) +
353 XFS_DIR3_DATA_ENTSIZE(2));
354}
355
356static struct xfs_dir2_data_entry *
Dave Chinner9d23fc82013-10-29 22:11:48 +1100357xfs_dir3_data_dot_entry_p(
358 struct xfs_dir2_data_hdr *hdr)
359{
360 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100361 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100362}
363
364static struct xfs_dir2_data_entry *
365xfs_dir3_data_dotdot_entry_p(
366 struct xfs_dir2_data_hdr *hdr)
367{
368 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100369 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
370 XFS_DIR3_DATA_ENTSIZE(1));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100371}
372
373static struct xfs_dir2_data_entry *
374xfs_dir3_data_first_entry_p(
375 struct xfs_dir2_data_hdr *hdr)
376{
377 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100378 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
379 XFS_DIR3_DATA_ENTSIZE(1) +
380 XFS_DIR3_DATA_ENTSIZE(2));
Dave Chinner9d23fc82013-10-29 22:11:48 +1100381}
382
Dave Chinner2ca98772013-10-29 22:11:49 +1100383static struct xfs_dir2_data_free *
384xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
385{
386 return hdr->bestfree;
387}
388
389static struct xfs_dir2_data_free *
390xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
391{
392 return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
393}
394
Dave Chinner2ca98772013-10-29 22:11:49 +1100395static struct xfs_dir2_data_entry *
396xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
397{
398 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100399 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100400}
401
402static struct xfs_dir2_data_unused *
403xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr)
404{
405 return (struct xfs_dir2_data_unused *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100406 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100407}
408
409static struct xfs_dir2_data_entry *
410xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
411{
412 return (struct xfs_dir2_data_entry *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100413 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100414}
415
416static struct xfs_dir2_data_unused *
417xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
418{
419 return (struct xfs_dir2_data_unused *)
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100420 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
Dave Chinner2ca98772013-10-29 22:11:49 +1100421}
422
Dave Chinner41419562013-10-29 22:11:50 +1100423
424/*
425 * Directory Leaf block operations
426 */
427static int
Dave Chinner41419562013-10-29 22:11:50 +1100428xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
429{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100430 return (mp->m_dirblksize - sizeof(struct xfs_dir2_leaf_hdr)) /
Dave Chinner41419562013-10-29 22:11:50 +1100431 (uint)sizeof(struct xfs_dir2_leaf_entry);
432}
433
434static struct xfs_dir2_leaf_entry *
435xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
436{
437 return lp->__ents;
438}
439
440static int
Dave Chinner41419562013-10-29 22:11:50 +1100441xfs_dir3_max_leaf_ents(struct xfs_mount *mp)
442{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100443 return (mp->m_dirblksize - sizeof(struct xfs_dir3_leaf_hdr)) /
Dave Chinner41419562013-10-29 22:11:50 +1100444 (uint)sizeof(struct xfs_dir2_leaf_entry);
445}
446
Dave Chinner01ba43b2013-10-29 22:11:52 +1100447static struct xfs_dir2_leaf_entry *
Dave Chinner41419562013-10-29 22:11:50 +1100448xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
449{
450 return ((struct xfs_dir3_leaf *)lp)->__ents;
451}
452
Dave Chinner01ba43b2013-10-29 22:11:52 +1100453static void
454xfs_dir2_leaf_hdr_from_disk(
455 struct xfs_dir3_icleaf_hdr *to,
456 struct xfs_dir2_leaf *from)
457{
458 to->forw = be32_to_cpu(from->hdr.info.forw);
459 to->back = be32_to_cpu(from->hdr.info.back);
460 to->magic = be16_to_cpu(from->hdr.info.magic);
461 to->count = be16_to_cpu(from->hdr.count);
462 to->stale = be16_to_cpu(from->hdr.stale);
463
464 ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
465 to->magic == XFS_DIR2_LEAFN_MAGIC);
466}
467
468static void
469xfs_dir2_leaf_hdr_to_disk(
470 struct xfs_dir2_leaf *to,
471 struct xfs_dir3_icleaf_hdr *from)
472{
473 ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
474 from->magic == XFS_DIR2_LEAFN_MAGIC);
475
476 to->hdr.info.forw = cpu_to_be32(from->forw);
477 to->hdr.info.back = cpu_to_be32(from->back);
478 to->hdr.info.magic = cpu_to_be16(from->magic);
479 to->hdr.count = cpu_to_be16(from->count);
480 to->hdr.stale = cpu_to_be16(from->stale);
481}
482
483static void
484xfs_dir3_leaf_hdr_from_disk(
485 struct xfs_dir3_icleaf_hdr *to,
486 struct xfs_dir2_leaf *from)
487{
488 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from;
489
490 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
491 to->back = be32_to_cpu(hdr3->info.hdr.back);
492 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
493 to->count = be16_to_cpu(hdr3->count);
494 to->stale = be16_to_cpu(hdr3->stale);
495
496 ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
497 to->magic == XFS_DIR3_LEAFN_MAGIC);
498}
499
500static void
501xfs_dir3_leaf_hdr_to_disk(
502 struct xfs_dir2_leaf *to,
503 struct xfs_dir3_icleaf_hdr *from)
504{
505 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to;
506
507 ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC ||
508 from->magic == XFS_DIR3_LEAFN_MAGIC);
509
510 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
511 hdr3->info.hdr.back = cpu_to_be32(from->back);
512 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
513 hdr3->count = cpu_to_be16(from->count);
514 hdr3->stale = cpu_to_be16(from->stale);
515}
516
517
Dave Chinner4bceb182013-10-29 22:11:51 +1100518/*
519 * Directory/Attribute Node block operations
520 */
Dave Chinner4bceb182013-10-29 22:11:51 +1100521static struct xfs_da_node_entry *
522xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
523{
524 return dap->__btree;
525}
526
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100527static struct xfs_da_node_entry *
Dave Chinner4bceb182013-10-29 22:11:51 +1100528xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
529{
530 return ((struct xfs_da3_intnode *)dap)->__btree;
531}
532
Dave Chinner01ba43b2013-10-29 22:11:52 +1100533static void
534xfs_da2_node_hdr_from_disk(
535 struct xfs_da3_icnode_hdr *to,
536 struct xfs_da_intnode *from)
537{
538 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
539 to->forw = be32_to_cpu(from->hdr.info.forw);
540 to->back = be32_to_cpu(from->hdr.info.back);
541 to->magic = be16_to_cpu(from->hdr.info.magic);
542 to->count = be16_to_cpu(from->hdr.__count);
543 to->level = be16_to_cpu(from->hdr.__level);
544}
545
546static void
547xfs_da2_node_hdr_to_disk(
548 struct xfs_da_intnode *to,
549 struct xfs_da3_icnode_hdr *from)
550{
551 ASSERT(from->magic == XFS_DA_NODE_MAGIC);
552 to->hdr.info.forw = cpu_to_be32(from->forw);
553 to->hdr.info.back = cpu_to_be32(from->back);
554 to->hdr.info.magic = cpu_to_be16(from->magic);
555 to->hdr.__count = cpu_to_be16(from->count);
556 to->hdr.__level = cpu_to_be16(from->level);
557}
558
559static void
560xfs_da3_node_hdr_from_disk(
561 struct xfs_da3_icnode_hdr *to,
562 struct xfs_da_intnode *from)
563{
564 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from;
565
566 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
567 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
568 to->back = be32_to_cpu(hdr3->info.hdr.back);
569 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
570 to->count = be16_to_cpu(hdr3->__count);
571 to->level = be16_to_cpu(hdr3->__level);
572}
573
574static void
575xfs_da3_node_hdr_to_disk(
576 struct xfs_da_intnode *to,
577 struct xfs_da3_icnode_hdr *from)
578{
579 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to;
580
581 ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
582 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
583 hdr3->info.hdr.back = cpu_to_be32(from->back);
584 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
585 hdr3->__count = cpu_to_be16(from->count);
586 hdr3->__level = cpu_to_be16(from->level);
587}
588
589
590/*
591 * Directory free space block operations
592 */
Dave Chinner24dd0f52013-10-30 13:48:41 -0500593static int
Dave Chinner24dd0f52013-10-30 13:48:41 -0500594xfs_dir2_free_max_bests(struct xfs_mount *mp)
595{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100596 return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) /
Dave Chinner24dd0f52013-10-30 13:48:41 -0500597 sizeof(xfs_dir2_data_off_t);
598}
599
600static __be16 *
601xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
602{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100603 return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr));
Dave Chinner24dd0f52013-10-30 13:48:41 -0500604}
605
606/*
607 * Convert data space db to the corresponding free db.
608 */
609static xfs_dir2_db_t
610xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
611{
612 return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir2_free_max_bests(mp);
613}
614
615/*
616 * Convert data space db to the corresponding index in a free db.
617 */
618static int
619xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
620{
621 return db % xfs_dir2_free_max_bests(mp);
622}
623
624static int
Dave Chinner24dd0f52013-10-30 13:48:41 -0500625xfs_dir3_free_max_bests(struct xfs_mount *mp)
626{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100627 return (mp->m_dirblksize - sizeof(struct xfs_dir3_free_hdr)) /
Dave Chinner24dd0f52013-10-30 13:48:41 -0500628 sizeof(xfs_dir2_data_off_t);
629}
630
631static __be16 *
632xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
633{
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100634 return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr));
Dave Chinner24dd0f52013-10-30 13:48:41 -0500635}
636
637/*
638 * Convert data space db to the corresponding free db.
639 */
640static xfs_dir2_db_t
641xfs_dir3_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
642{
643 return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir3_free_max_bests(mp);
644}
645
646/*
647 * Convert data space db to the corresponding index in a free db.
648 */
649static int
650xfs_dir3_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
651{
652 return db % xfs_dir3_free_max_bests(mp);
653}
654
Dave Chinner01ba43b2013-10-29 22:11:52 +1100655static void
656xfs_dir2_free_hdr_from_disk(
657 struct xfs_dir3_icfree_hdr *to,
658 struct xfs_dir2_free *from)
659{
660 to->magic = be32_to_cpu(from->hdr.magic);
661 to->firstdb = be32_to_cpu(from->hdr.firstdb);
662 to->nvalid = be32_to_cpu(from->hdr.nvalid);
663 to->nused = be32_to_cpu(from->hdr.nused);
664 ASSERT(to->magic == XFS_DIR2_FREE_MAGIC);
665}
666
667static void
668xfs_dir2_free_hdr_to_disk(
669 struct xfs_dir2_free *to,
670 struct xfs_dir3_icfree_hdr *from)
671{
672 ASSERT(from->magic == XFS_DIR2_FREE_MAGIC);
673
674 to->hdr.magic = cpu_to_be32(from->magic);
675 to->hdr.firstdb = cpu_to_be32(from->firstdb);
676 to->hdr.nvalid = cpu_to_be32(from->nvalid);
677 to->hdr.nused = cpu_to_be32(from->nused);
678}
679
680static void
681xfs_dir3_free_hdr_from_disk(
682 struct xfs_dir3_icfree_hdr *to,
683 struct xfs_dir2_free *from)
684{
685 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from;
686
687 to->magic = be32_to_cpu(hdr3->hdr.magic);
688 to->firstdb = be32_to_cpu(hdr3->firstdb);
689 to->nvalid = be32_to_cpu(hdr3->nvalid);
690 to->nused = be32_to_cpu(hdr3->nused);
691
692 ASSERT(to->magic == XFS_DIR3_FREE_MAGIC);
693}
694
695static void
696xfs_dir3_free_hdr_to_disk(
697 struct xfs_dir2_free *to,
698 struct xfs_dir3_icfree_hdr *from)
699{
700 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to;
701
702 ASSERT(from->magic == XFS_DIR3_FREE_MAGIC);
703
704 hdr3->hdr.magic = cpu_to_be32(from->magic);
705 hdr3->firstdb = cpu_to_be32(from->firstdb);
706 hdr3->nvalid = cpu_to_be32(from->nvalid);
707 hdr3->nused = cpu_to_be32(from->nused);
708}
709
Dave Chinner632b89e2013-10-29 22:11:58 +1100710static const struct xfs_dir_ops xfs_dir2_ops = {
Dave Chinner32c54832013-10-29 22:11:46 +1100711 .sf_entsize = xfs_dir2_sf_entsize,
712 .sf_nextentry = xfs_dir2_sf_nextentry,
Dave Chinner47401752013-10-29 22:11:47 +1100713 .sf_get_ftype = xfs_dir2_sfe_get_ftype,
714 .sf_put_ftype = xfs_dir2_sfe_put_ftype,
715 .sf_get_ino = xfs_dir2_sfe_get_ino,
716 .sf_put_ino = xfs_dir2_sfe_put_ino,
717 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
718 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100719
720 .data_entsize = xfs_dir2_data_entsize,
721 .data_get_ftype = xfs_dir2_data_get_ftype,
722 .data_put_ftype = xfs_dir2_data_put_ftype,
723 .data_entry_tag_p = xfs_dir2_data_entry_tag_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100724 .data_bestfree_p = xfs_dir2_data_bestfree_p,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100725
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100726 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
727 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
728 XFS_DIR2_DATA_ENTSIZE(1),
729 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) +
730 XFS_DIR2_DATA_ENTSIZE(1) +
731 XFS_DIR2_DATA_ENTSIZE(2),
732 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
Dave Chinner2ca98772013-10-29 22:11:49 +1100733
Dave Chinner9d23fc82013-10-29 22:11:48 +1100734 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
735 .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
736 .data_first_entry_p = xfs_dir2_data_first_entry_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100737 .data_entry_p = xfs_dir2_data_entry_p,
738 .data_unused_p = xfs_dir2_data_unused_p,
739
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100740 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100741 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
742 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
Dave Chinner41419562013-10-29 22:11:50 +1100743 .leaf_max_ents = xfs_dir2_max_leaf_ents,
744 .leaf_ents_p = xfs_dir2_leaf_ents_p,
745
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100746 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100747 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
748 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100749 .node_tree_p = xfs_da2_node_tree_p,
Dave Chinner01ba43b2013-10-29 22:11:52 +1100750
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100751 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100752 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
753 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
Dave Chinner24dd0f52013-10-30 13:48:41 -0500754 .free_max_bests = xfs_dir2_free_max_bests,
755 .free_bests_p = xfs_dir2_free_bests_p,
756 .db_to_fdb = xfs_dir2_db_to_fdb,
757 .db_to_fdindex = xfs_dir2_db_to_fdindex,
Dave Chinner32c54832013-10-29 22:11:46 +1100758};
759
Dave Chinner632b89e2013-10-29 22:11:58 +1100760static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
Dave Chinner32c54832013-10-29 22:11:46 +1100761 .sf_entsize = xfs_dir3_sf_entsize,
762 .sf_nextentry = xfs_dir3_sf_nextentry,
Dave Chinner47401752013-10-29 22:11:47 +1100763 .sf_get_ftype = xfs_dir3_sfe_get_ftype,
764 .sf_put_ftype = xfs_dir3_sfe_put_ftype,
765 .sf_get_ino = xfs_dir3_sfe_get_ino,
766 .sf_put_ino = xfs_dir3_sfe_put_ino,
767 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
768 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100769
770 .data_entsize = xfs_dir3_data_entsize,
771 .data_get_ftype = xfs_dir3_data_get_ftype,
772 .data_put_ftype = xfs_dir3_data_put_ftype,
773 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100774 .data_bestfree_p = xfs_dir2_data_bestfree_p,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100775
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100776 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
777 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
778 XFS_DIR3_DATA_ENTSIZE(1),
779 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) +
780 XFS_DIR3_DATA_ENTSIZE(1) +
781 XFS_DIR3_DATA_ENTSIZE(2),
782 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
Dave Chinner2ca98772013-10-29 22:11:49 +1100783
Dave Chinner9d23fc82013-10-29 22:11:48 +1100784 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
Dave Chinnerb01ef652013-10-29 22:11:55 +1100785 .data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p,
786 .data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100787 .data_entry_p = xfs_dir2_data_entry_p,
788 .data_unused_p = xfs_dir2_data_unused_p,
Dave Chinner41419562013-10-29 22:11:50 +1100789
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100790 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100791 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
792 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
Dave Chinner41419562013-10-29 22:11:50 +1100793 .leaf_max_ents = xfs_dir2_max_leaf_ents,
794 .leaf_ents_p = xfs_dir2_leaf_ents_p,
Dave Chinner4bceb182013-10-29 22:11:51 +1100795
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100796 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100797 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
798 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100799 .node_tree_p = xfs_da2_node_tree_p,
Dave Chinner01ba43b2013-10-29 22:11:52 +1100800
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100801 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100802 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
803 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
Dave Chinner24dd0f52013-10-30 13:48:41 -0500804 .free_max_bests = xfs_dir2_free_max_bests,
805 .free_bests_p = xfs_dir2_free_bests_p,
806 .db_to_fdb = xfs_dir2_db_to_fdb,
807 .db_to_fdindex = xfs_dir2_db_to_fdindex,
Dave Chinner32c54832013-10-29 22:11:46 +1100808};
809
Dave Chinner632b89e2013-10-29 22:11:58 +1100810static const struct xfs_dir_ops xfs_dir3_ops = {
Dave Chinner32c54832013-10-29 22:11:46 +1100811 .sf_entsize = xfs_dir3_sf_entsize,
812 .sf_nextentry = xfs_dir3_sf_nextentry,
Dave Chinner47401752013-10-29 22:11:47 +1100813 .sf_get_ftype = xfs_dir3_sfe_get_ftype,
814 .sf_put_ftype = xfs_dir3_sfe_put_ftype,
815 .sf_get_ino = xfs_dir3_sfe_get_ino,
816 .sf_put_ino = xfs_dir3_sfe_put_ino,
817 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
818 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100819
820 .data_entsize = xfs_dir3_data_entsize,
821 .data_get_ftype = xfs_dir3_data_get_ftype,
822 .data_put_ftype = xfs_dir3_data_put_ftype,
823 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100824 .data_bestfree_p = xfs_dir3_data_bestfree_p,
Dave Chinner9d23fc82013-10-29 22:11:48 +1100825
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100826 .data_dot_offset = sizeof(struct xfs_dir3_data_hdr),
827 .data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) +
828 XFS_DIR3_DATA_ENTSIZE(1),
829 .data_first_offset = sizeof(struct xfs_dir3_data_hdr) +
830 XFS_DIR3_DATA_ENTSIZE(1) +
831 XFS_DIR3_DATA_ENTSIZE(2),
832 .data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
Dave Chinner2ca98772013-10-29 22:11:49 +1100833
Dave Chinner9d23fc82013-10-29 22:11:48 +1100834 .data_dot_entry_p = xfs_dir3_data_dot_entry_p,
835 .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p,
836 .data_first_entry_p = xfs_dir3_data_first_entry_p,
Dave Chinner2ca98772013-10-29 22:11:49 +1100837 .data_entry_p = xfs_dir3_data_entry_p,
838 .data_unused_p = xfs_dir3_data_unused_p,
Dave Chinner41419562013-10-29 22:11:50 +1100839
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100840 .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100841 .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
842 .leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk,
Dave Chinner41419562013-10-29 22:11:50 +1100843 .leaf_max_ents = xfs_dir3_max_leaf_ents,
844 .leaf_ents_p = xfs_dir3_leaf_ents_p,
Dave Chinner4bceb182013-10-29 22:11:51 +1100845
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100846 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100847 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
848 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100849 .node_tree_p = xfs_da3_node_tree_p,
Dave Chinner01ba43b2013-10-29 22:11:52 +1100850
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100851 .free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100852 .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
853 .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk,
Dave Chinner24dd0f52013-10-30 13:48:41 -0500854 .free_max_bests = xfs_dir3_free_max_bests,
855 .free_bests_p = xfs_dir3_free_bests_p,
856 .db_to_fdb = xfs_dir3_db_to_fdb,
857 .db_to_fdindex = xfs_dir3_db_to_fdindex,
Dave Chinner4bceb182013-10-29 22:11:51 +1100858};
859
Dave Chinner632b89e2013-10-29 22:11:58 +1100860static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100861 .node_hdr_size = sizeof(struct xfs_da_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100862 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
863 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100864 .node_tree_p = xfs_da2_node_tree_p,
865};
866
Dave Chinner632b89e2013-10-29 22:11:58 +1100867static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
Dave Chinner1c9a5b22013-10-30 09:15:02 +1100868 .node_hdr_size = sizeof(struct xfs_da3_node_hdr),
Dave Chinner01ba43b2013-10-29 22:11:52 +1100869 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
870 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
Dave Chinner4bceb182013-10-29 22:11:51 +1100871 .node_tree_p = xfs_da3_node_tree_p,
Dave Chinner32c54832013-10-29 22:11:46 +1100872};
Dave Chinner41419562013-10-29 22:11:50 +1100873
874/*
875 * Return the ops structure according to the current config. If we are passed
876 * an inode, then that overrides the default config we use which is based on
877 * feature bits.
878 */
879const struct xfs_dir_ops *
880xfs_dir_get_ops(
881 struct xfs_mount *mp,
882 struct xfs_inode *dp)
883{
884 if (dp)
885 return dp->d_ops;
886 if (mp->m_dir_inode_ops)
887 return mp->m_dir_inode_ops;
888 if (xfs_sb_version_hascrc(&mp->m_sb))
889 return &xfs_dir3_ops;
890 if (xfs_sb_version_hasftype(&mp->m_sb))
891 return &xfs_dir2_ftype_ops;
892 return &xfs_dir2_ops;
893}
Dave Chinner4bceb182013-10-29 22:11:51 +1100894
895const struct xfs_dir_ops *
896xfs_nondir_get_ops(
897 struct xfs_mount *mp,
898 struct xfs_inode *dp)
899{
900 if (dp)
901 return dp->d_ops;
902 if (mp->m_nondir_inode_ops)
903 return mp->m_nondir_inode_ops;
904 if (xfs_sb_version_hascrc(&mp->m_sb))
905 return &xfs_dir3_nondir_ops;
906 return &xfs_dir2_nondir_ops;
907}