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