Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1/*
  2 * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
  3 * Copyright (c) 2013 Red Hat, Inc.
  4 * All Rights Reserved.
  5 *
  6 * This program is free software; you can redistribute it and/or
  7 * modify it under the terms of the GNU General Public License as
  8 * published by the Free Software Foundation.
  9 *
 10 * This program is distributed in the hope that it would be useful,
 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13 * GNU General Public License for more details.
 14 *
 15 * You should have received a copy of the GNU General Public License
 16 * along with this program; if not, write the Free Software Foundation,
 17 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 18 */
 19#include "xfs.h"
 20#include "xfs_fs.h"
 21#include "xfs_shared.h"
 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"
 29#include "xfs_inode.h"
 30#include "xfs_dir2.h"
 31
 32/*
 33 * Shortform directory ops
 34 */
 35static 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
 75/*
 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
209
210/*
211 * Directory data block operations
212 */
213
214/*
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)
235
236static int
237xfs_dir2_data_entsize(
238	int			n)
239{
240	return XFS_DIR2_DATA_ENTSIZE(n);
241}
242
243static int
244xfs_dir3_data_entsize(
245	int			n)
246{
247	return XFS_DIR3_DATA_ENTSIZE(n);
248}
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/*
308 * 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 *)
315		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
316}
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 *)
323		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
324				XFS_DIR2_DATA_ENTSIZE(1));
325}
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 *)
332		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
333				XFS_DIR2_DATA_ENTSIZE(1) +
334				XFS_DIR2_DATA_ENTSIZE(2));
335}
336
337static struct xfs_dir2_data_entry *
338xfs_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 *
357xfs_dir3_data_dot_entry_p(
358	struct xfs_dir2_data_hdr *hdr)
359{
360	return (struct xfs_dir2_data_entry *)
361		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
362}
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 *)
369		((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
370				XFS_DIR3_DATA_ENTSIZE(1));
371}
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 *)
378		((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
379				XFS_DIR3_DATA_ENTSIZE(1) +
380				XFS_DIR3_DATA_ENTSIZE(2));
381}
382
383static 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
395static struct xfs_dir2_data_entry *
396xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
397{
398	return (struct xfs_dir2_data_entry *)
399		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
400}
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 *)
406		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
407}
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 *)
413		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
414}
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 *)
420		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
421}
422
423
424/*
425 * Directory Leaf block operations
426 */
427static int
428xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
429{
430	return (mp->m_dirblksize - sizeof(struct xfs_dir2_leaf_hdr)) /
431		(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
441xfs_dir3_max_leaf_ents(struct xfs_mount *mp)
442{
443	return (mp->m_dirblksize - sizeof(struct xfs_dir3_leaf_hdr)) /
444		(uint)sizeof(struct xfs_dir2_leaf_entry);
445}
446
447static struct xfs_dir2_leaf_entry *
448xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
449{
450	return ((struct xfs_dir3_leaf *)lp)->__ents;
451}
452
453static 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
518/*
519 * Directory/Attribute Node block operations
520 */
521static struct xfs_da_node_entry *
522xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
523{
524	return dap->__btree;
525}
526
527static struct xfs_da_node_entry *
528xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
529{
530	return ((struct xfs_da3_intnode *)dap)->__btree;
531}
532
533static 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 */
593static int
594xfs_dir2_free_max_bests(struct xfs_mount *mp)
595{
596	return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) /
597		sizeof(xfs_dir2_data_off_t);
598}
599
600static __be16 *
601xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
602{
603	return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr));
604}
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
625xfs_dir3_free_max_bests(struct xfs_mount *mp)
626{
627	return (mp->m_dirblksize - sizeof(struct xfs_dir3_free_hdr)) /
628		sizeof(xfs_dir2_data_off_t);
629}
630
631static __be16 *
632xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
633{
634	return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr));
635}
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
655static 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
710static const struct xfs_dir_ops xfs_dir2_ops = {
711	.sf_entsize = xfs_dir2_sf_entsize,
712	.sf_nextentry = xfs_dir2_sf_nextentry,
713	.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,
719
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,
724	.data_bestfree_p = xfs_dir2_data_bestfree_p,
725
726	.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),
733
734	.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,
737	.data_entry_p = xfs_dir2_data_entry_p,
738	.data_unused_p = xfs_dir2_data_unused_p,
739
740	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
741	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
742	.leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
743	.leaf_max_ents = xfs_dir2_max_leaf_ents,
744	.leaf_ents_p = xfs_dir2_leaf_ents_p,
745
746	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
747	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
748	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
749	.node_tree_p = xfs_da2_node_tree_p,
750
751	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
752	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
753	.free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
754	.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,
758};
759
760static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
761	.sf_entsize = xfs_dir3_sf_entsize,
762	.sf_nextentry = xfs_dir3_sf_nextentry,
763	.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,
769
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,
774	.data_bestfree_p = xfs_dir2_data_bestfree_p,
775
776	.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),
783
784	.data_dot_entry_p = xfs_dir2_data_dot_entry_p,
785	.data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p,
786	.data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
787	.data_entry_p = xfs_dir2_data_entry_p,
788	.data_unused_p = xfs_dir2_data_unused_p,
789
790	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
791	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
792	.leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
793	.leaf_max_ents = xfs_dir2_max_leaf_ents,
794	.leaf_ents_p = xfs_dir2_leaf_ents_p,
795
796	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
797	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
798	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
799	.node_tree_p = xfs_da2_node_tree_p,
800
801	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
802	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
803	.free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
804	.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,
808};
809
810static const struct xfs_dir_ops xfs_dir3_ops = {
811	.sf_entsize = xfs_dir3_sf_entsize,
812	.sf_nextentry = xfs_dir3_sf_nextentry,
813	.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,
819
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,
824	.data_bestfree_p = xfs_dir3_data_bestfree_p,
825
826	.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),
833
834	.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,
837	.data_entry_p = xfs_dir3_data_entry_p,
838	.data_unused_p = xfs_dir3_data_unused_p,
839
840	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
841	.leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
842	.leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk,
843	.leaf_max_ents = xfs_dir3_max_leaf_ents,
844	.leaf_ents_p = xfs_dir3_leaf_ents_p,
845
846	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
847	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
848	.node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
849	.node_tree_p = xfs_da3_node_tree_p,
850
851	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
852	.free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
853	.free_hdr_from_disk = xfs_dir3_free_hdr_from_disk,
854	.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,
858};
859
860static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
861	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
862	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
863	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
864	.node_tree_p = xfs_da2_node_tree_p,
865};
866
867static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
868	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
869	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
870	.node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
871	.node_tree_p = xfs_da3_node_tree_p,
872};
873
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}
894
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}