• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com>
3  *
4  * Some parts borrowed from Linux kernel tree (linux/fs/xfs):
5  *
6  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
7  * All Rights Reserved.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it would be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write the Free Software Foundation,
20  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 #ifndef XFS_H_
24 #define XFS_H_
25 
26 #include <disk.h>
27 #include <fs.h>
28 #include <dprintf.h>
29 
30 #include "xfs_types.h"
31 #include "xfs_ag.h"
32 
33 #define xfs_error(fmt, args...)						\
34     ({									\
35 	printf("%s:%u: xfs - [ERROR] " fmt "\n", __func__, __LINE__, ## args); \
36     })
37 
38 #define xfs_debug(fmt, args...)						\
39     ({									\
40 	dprintf("%s:%u: xfs - [DEBUG] " fmt "\n", __func__, __LINE__,	\
41 		## args);						\
42     })
43 
44 struct xfs_fs_info;
45 
46 #define XFS_INFO(fs) ((struct xfs_fs_info *)((fs)->fs_info))
47 #define XFS_PVT(ino) ((struct xfs_inode *)((ino)->pvt))
48 
49 #define XFS_INO_MASK(k)                 (uint32_t)((1ULL << (k)) - 1)
50 #define XFS_INO_OFFSET_BITS(fs)		(fs)->inopb_shift
51 #define XFS_INO_AGINO_BITS(fs) \
52     (XFS_INFO((fs))->inopb_shift + XFS_INFO((fs))->agblk_shift)
53 
54 #define XFS_INO_TO_AGINO(fs, i) \
55     ((xfs_agino_t)(i) & XFS_INO_MASK(XFS_INO_AGINO_BITS(fs)))
56 
57 #define XFS_INO_TO_AGNO(fs, ino) \
58     ((xfs_agnumber_t)((ino) >> (XFS_INFO((fs))->inopb_shift + \
59 				XFS_INFO((fs))->agblk_shift)))
60 
61 #define XFS_INO_TO_OFFSET(fs, i) \
62 	((int)(i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(fs)))
63 
64 #define XFS_AGNO_TO_FSB(fs, agno) \
65     ((block_t)((agno) << XFS_INFO((fs))->agblocks_shift))
66 
67 #define XFS_AGI_OFFS(fs, mp) \
68     ((xfs_agi_t *)((uint8_t *)(mp) + 2 * SECTOR_SIZE((fs))))
69 
70 #define XFS_GET_DIR_INO4(di) \
71     (((uint32_t)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | \
72 		((di).i[3]))
73 
74 #define XFS_DI_HI(di) \
75     (((uint32_t)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
76 
77 #define XFS_DI_LO(di) \
78     (((uint32_t)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | \
79 		((di).i[7]))
80 
81 #define XFS_GET_DIR_INO8(di) \
82     (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \
83      ((xfs_ino_t)XFS_DI_HI(di) << 32))
84 
85 #define XFS_FSB_TO_AGNO(fs, fsbno) \
86     ((xfs_agnumber_t)((fsbno) >> XFS_INFO((fs))->agblk_shift))
87 #define XFS_FSB_TO_AGBNO(fs, fsbno) \
88     ((xfs_agblock_t)((fsbno) & (uint32_t)((1ULL << \
89 					   XFS_INFO((fs))->agblk_shift) - 1)))
90 
91 #define agblock_to_bytes(fs, x) \
92     ((uint64_t)(x) << BLOCK_SHIFT((fs)))
93 #define agino_to_bytes(fs, x) \
94     ((uint64_t)(x) << XFS_INFO((fs))->inode_shift)
95 #define agnumber_to_bytes(fs, x) \
96     agblock_to_bytes(fs, (uint64_t)(x) * XFS_INFO((fs))->agblocks)
97 #define fsblock_to_bytes(fs,x)				\
98     (agnumber_to_bytes(fs, XFS_FSB_TO_AGNO(fs, (x))) +	\
99      agblock_to_bytes(fs, XFS_FSB_TO_AGBNO(fs, (x))))
100 #define ino_to_bytes(fs, x)			   \
101     (agnumber_to_bytes(fs, XFS_INO_TO_AGNO(fs, (x))) +	\
102      agino_to_bytes(fs, XFS_INO_TO_AGINO(fs, (x))))
103 
104 /* Superblock's LBA */
105 #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
106 
107 /* Magic numbers */
108 #define	XFS_AGI_MAGIC 		"XAGI"
109 #define XFS_IBT_MAGIC 		"IABT"
110 #define XFS_DINODE_MAGIC	"IN"
111 
112 #define XFS_DIR2_BLOCK_MAGIC    0x58443242U      /* XD2B: single block dirs */
113 #define XFS_DIR2_DATA_MAGIC     0x58443244U      /* XD2D: multiblock dirs */
114 #define XFS_DIR2_FREE_MAGIC     0x58443246U      /* XD2F: free index blocks */
115 
116 #define XFS_DIR2_NULL_DATAPTR   ((uint32_t)0)
117 
118 /* File types and modes */
119 #define S_IFMT  	00170000
120 #define S_IFSOCK 	0140000
121 #define S_IFLNK 	0120000
122 #define S_IFREG  	0100000
123 #define S_IFBLK  	0060000
124 #define S_IFDIR  	0040000
125 #define S_IFCHR  	0020000
126 #define S_IFIFO  	0010000
127 #define S_ISUID  	0004000
128 #define S_ISGID  	0002000
129 #define S_ISVTX  	0001000
130 
131 #define MAXPATHLEN 1024
132 /*
133  * NOTE: The fields in the superblock are stored in big-endian format on disk.
134  */
135 typedef struct xfs_sb {
136     uint32_t	sb_magicnum;	/* magic number == XFS_SB_MAGIC */
137     uint32_t	sb_blocksize;	/* logical block size, bytes */
138     xfs_drfsbno_t	sb_dblocks;	/* number of data blocks */
139     xfs_drfsbno_t	sb_rblocks;	/* number of realtime blocks */
140     xfs_drtbno_t	sb_rextents;	/* number of realtime extents */
141     uuid_t		sb_uuid;	/* file system unique id */
142     xfs_dfsbno_t	sb_logstart;	/* starting block of log if internal */
143     xfs_ino_t	sb_rootino;	/* root inode number */
144     xfs_ino_t	sb_rbmino;	/* bitmap inode for realtime extents */
145     xfs_ino_t	sb_rsumino;	/* summary inode for rt bitmap */
146     xfs_agblock_t	sb_rextsize;	/* realtime extent size, blocks */
147     xfs_agblock_t	sb_agblocks;	/* size of an allocation group */
148     xfs_agnumber_t	sb_agcount;	/* number of allocation groups */
149     xfs_extlen_t	sb_rbmblocks;	/* number of rt bitmap blocks */
150     xfs_extlen_t	sb_logblocks;	/* number of log blocks */
151     uint16_t	sb_versionnum;	/* header version == XFS_SB_VERSION */
152     uint16_t	sb_sectsize;	/* volume sector size, bytes */
153     uint16_t	sb_inodesize;	/* inode size, bytes */
154     uint16_t	sb_inopblock;	/* inodes per block */
155     char	sb_fname[12];	/* file system name */
156     uint8_t	sb_blocklog;	/* log2 of sb_blocksize */
157     uint8_t	sb_sectlog;	/* log2 of sb_sectsize */
158     uint8_t	sb_inodelog;	/* log2 of sb_inodesize */
159     uint8_t	sb_inopblog;	/* log2 of sb_inopblock */
160     uint8_t	sb_agblklog;	/* log2 of sb_agblocks (rounded up) */
161     uint8_t	sb_rextslog;	/* log2 of sb_rextents */
162     uint8_t	sb_inprogress;	/* mkfs is in progress, don't mount */
163     uint8_t	sb_imax_pct;	/* max % of fs for inode space */
164 					/* statistics */
165     /*
166      * These fields must remain contiguous.  If you really
167      * want to change their layout, make sure you fix the
168      * code in xfs_trans_apply_sb_deltas().
169      */
170     uint64_t	sb_icount;	/* allocated inodes */
171     uint64_t	sb_ifree;	/* free inodes */
172     uint64_t	sb_fdblocks;	/* free data blocks */
173     uint64_t	sb_frextents;	/* free realtime extents */
174     /*
175      * End contiguous fields.
176      */
177     xfs_ino_t	sb_uquotino;	/* user quota inode */
178     xfs_ino_t	sb_gquotino;	/* group quota inode */
179     uint16_t	sb_qflags;	/* quota flags */
180     uint8_t	sb_flags;	/* misc. flags */
181     uint8_t	sb_shared_vn;	/* shared version number */
182     xfs_extlen_t	sb_inoalignmt;	/* inode chunk alignment, fsblocks */
183     uint32_t	sb_unit;	/* stripe or raid unit */
184     uint32_t	sb_width;	/* stripe or raid width */
185     uint8_t	sb_dirblklog;	/* log2 of dir block size (fsbs) */
186     uint8_t	sb_logsectlog;	/* log2 of the log sector size */
187     uint16_t	sb_logsectsize;	/* sector size for the log, bytes */
188     uint32_t	sb_logsunit;	/* stripe unit size for the log */
189     uint32_t	sb_features2;	/* additional feature bits */
190 
191     /*
192      * bad features2 field as a result of failing to pad the sb
193      * structure to 64 bits. Some machines will be using this field
194      * for features2 bits. Easiest just to mark it bad and not use
195      * it for anything else.
196      */
197     uint32_t	sb_bad_features2;
198     uint8_t	pad[304]; /* must be padded to a sector boundary */
199 } __attribute__((__packed__)) xfs_sb_t;
200 
201 /* In-memory structure that stores filesystem-specific information.
202  * The information stored is basically retrieved from the XFS superblock
203  * to be used statically around the driver.
204  */
205 struct xfs_fs_info {
206     uint32_t 		blocksize; /* Filesystem block size */
207     uint8_t		block_shift; /* Filesystem block size in bits */
208     uint32_t		dirblksize;
209     uint8_t		dirblklog;
210     uint8_t		inopb_shift;
211     uint8_t		agblk_shift;
212     uint32_t		dirleafblk;
213 
214     /* AG number bits (MSB of the inode number) */
215     uint8_t		ag_number_ino_shift;
216 
217     xfs_ino_t 		rootino; /* Root inode number for the filesystem */
218     xfs_agblock_t	agblocks; /* Size of each AG in blocks */
219     uint8_t		agblocks_shift; /* agblocks in bits */
220     xfs_agnumber_t	agcount; /* Number of AGs in the filesytem */
221     uint16_t		inodesize; /* Size of the inode in bytes */
222     uint8_t		inode_shift; /* Inode size in bits */
223 } __attribute__((__packed__));
224 
225 typedef struct xfs_agi {
226 	/*
227 	 * Common allocation group header information
228 	 */
229     uint32_t		agi_magicnum;	/* magic number == XFS_AGI_MAGIC */
230     uint32_t		agi_versionnum;	/* header version == XFS_AGI_VERSION */
231     uint32_t		agi_seqno;	/* sequence # starting from 0 */
232     uint32_t		agi_length;	/* size in blocks of a.g. */
233     /*
234      * Inode information
235      * Inodes are mapped by interpreting the inode number, so no
236      * mapping data is needed here.
237      */
238     uint32_t		agi_count;	/* count of allocated inodes */
239     uint32_t		agi_root;	/* root of inode btree */
240     uint32_t		agi_level;	/* levels in inode btree */
241     uint32_t		agi_freecount;	/* number of free inodes */
242     uint32_t		agi_newino;	/* new inode just allocated */
243     uint32_t		agi_dirino;	/* last directory inode chunk */
244     /*
245      * Hash table of inodes which have been unlinked but are
246      * still being referenced.
247      */
248     uint32_t		agi_unlinked[XFS_AGI_UNLINKED_BUCKETS];
249 } __attribute__((__packed__)) xfs_agi_t;
250 
251 /*
252  * Bmap btree record and extent descriptor.
253  *  l0:63 is an extent flag (value 1 indicates non-normal).
254  *  l0:9-62 are startoff.
255  *  l0:0-8 and l1:21-63 are startblock.
256  *  l1:0-20 are blockcount.
257  */
258 typedef struct xfs_bmbt_rec {
259     uint64_t l0;
260     uint64_t l1;
261 } __attribute__((__packed__)) xfs_bmbt_rec_t;
262 
263 typedef xfs_bmbt_rec_t xfs_bmdr_rec_t;
264 
265 /*
266  * Possible extent states.
267  */
268 typedef enum {
269     XFS_EXT_NORM,
270     XFS_EXT_UNWRITTEN,
271     XFS_EXT_DMAPI_OFFLINE,
272     XFS_EXT_INVALID,
273 } xfs_exntst_t;
274 
275 typedef struct xfs_bmbt_irec
276 {
277     xfs_fileoff_t br_startoff;    /* starting file offset */
278     xfs_fsblock_t br_startblock;  /* starting block number */
279     xfs_filblks_t br_blockcount;  /* number of blocks */
280     xfs_exntst_t  br_state;       /* extent state */
281 } __attribute__((__packed__)) xfs_bmbt_irec_t;
282 
bmbt_irec_get(xfs_bmbt_irec_t * dest,const xfs_bmbt_rec_t * src)283 static inline void bmbt_irec_get(xfs_bmbt_irec_t *dest,
284 				 const xfs_bmbt_rec_t *src)
285 {
286     uint64_t l0, l1;
287 
288     l0 = be64_to_cpu(src->l0);
289     l1 = be64_to_cpu(src->l1);
290 
291     dest->br_startoff = ((xfs_fileoff_t)l0 & 0x7ffffffffffffe00ULL) >> 9;
292     dest->br_startblock = (((xfs_fsblock_t)l0 & 0x00000000000001ffULL) << 43) |
293                           (((xfs_fsblock_t)l1) >> 21);
294     dest->br_blockcount = (xfs_filblks_t)(l1 & 0x00000000001fffffULL);
295     dest->br_state = (l0 & 0x8000000000000000ULL) ?
296 					XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
297 }
298 
299 typedef struct xfs_timestamp {
300     int32_t t_sec;
301     int32_t t_nsec;
302 } __attribute__((__packed__)) xfs_timestamp_t;
303 
304 /*
305  * Fork identifiers.
306  */
307 #define XFS_DATA_FORK 0
308 #define xFS_ATTR_FORK 1
309 
310 typedef enum xfs_dinode_fmt {
311     XFS_DINODE_FMT_DEV,
312     XFS_DINODE_FMT_LOCAL,
313     XFS_DINODE_FMT_EXTENTS,
314     XFS_DINODE_FMT_BTREE,
315     XFS_DINODE_FMT_UUID,
316 } xfs_dinode_fmt_t;
317 
318 typedef struct xfs_dinode {
319     uint16_t		di_magic;	/* inode magic # = XFS_DINODE_MAGIC */
320     uint16_t		di_mode;	/* mode and type of file */
321     uint8_t		di_version;	/* inode version */
322     uint8_t		di_format;	/* format of di_c data */
323     uint16_t		di_onlink;	/* old number of links to file */
324     uint32_t		di_uid;		/* owner's user id */
325     uint32_t		di_gid;		/* owner's group id */
326     uint32_t		di_nlink;	/* number of links to file */
327     uint16_t		di_projid_lo;	/* lower part of owner's project id */
328     uint16_t		di_projid_hi;	/* higher part owner's project id */
329     uint8_t		di_pad[6];	/* unused, zeroed space */
330     uint16_t		di_flushiter;	/* incremented on flush */
331     xfs_timestamp_t	di_atime;	/* time last accessed */
332     xfs_timestamp_t	di_mtime;	/* time last modified */
333     xfs_timestamp_t	di_ctime;	/* time created/inode modified */
334     uint64_t		di_size;	/* number of bytes in file */
335     uint64_t		di_nblocks;	/* # of direct & btree blocks used */
336     uint32_t		di_extsize;	/* basic/minimum extent size for file */
337     uint32_t		di_nextents;	/* number of extents in data fork */
338     uint16_t		di_anextents;	/* number of extents in attribute fork*/
339     uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
340     int8_t		di_aformat;	/* format of attr fork's data */
341     uint32_t		di_dmevmask;	/* DMIG event mask */
342     uint16_t		di_dmstate;	/* DMIG state info */
343     uint16_t		di_flags;	/* random flags, XFS_DIFLAG_... */
344     uint32_t		di_gen;		/* generation number */
345 
346     /* di_next_unlinked is the only non-core field in the old dinode */
347     uint32_t		di_next_unlinked;/* agi unlinked list ptr */
348     uint8_t		di_literal_area[1];
349 } __attribute__((packed)) xfs_dinode_t;
350 
351 /*
352  * Inode size for given fs.
353  */
354 #define XFS_LITINO(fs) \
355         ((int)((XFS_INFO(fs)->inodesize) - sizeof(struct xfs_dinode) - 1))
356 
357 #define XFS_BROOT_SIZE_ADJ \
358         (XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t))
359 
360 /*
361  * Inode data & attribute fork sizes, per inode.
362  */
363 #define XFS_DFORK_Q(dip)	((dip)->di_forkoff != 0)
364 #define XFS_DFORK_BOFF(dip)	((int)((dip)->di_forkoff << 3))
365 
366 #define XFS_DFORK_DSIZE(dip, fs) \
367         (XFS_DFORK_Q(dip) ? \
368                 XFS_DFORK_BOFF(dip) : \
369                 XFS_LITINO(fs))
370 #define XFS_DFORK_ASIZE(dip, fs) \
371         (XFS_DFORK_Q(dip) ? \
372                 XFS_LITINO(fs) - XFS_DFORK_BOFF(dip) : \
373                 0)
374 #define XFS_DFORK_SIZE(dip, fs, w) \
375         ((w) == XFS_DATA_FORK ? \
376                 XFS_DFORK_DSIZE(dip, fs) : \
377                 XFS_DFORK_ASIZE(dip, fs))
378 
379 struct xfs_inode {
380     xfs_agblock_t 	i_agblock;
381     block_t		i_ino_blk;
382     uint64_t		i_block_offset;
383     uint64_t		i_offset;
384     uint32_t		i_cur_extent;
385     uint32_t		i_btree_offset;
386     uint16_t		i_leaf_ent_offset;
387 };
388 
389 typedef struct { uint8_t i[8]; } __attribute__((__packed__)) xfs_dir2_ino8_t;
390 typedef struct { uint8_t i[4]; } __attribute__((__packed__)) xfs_dir2_ino4_t;
391 
392 typedef union {
393     xfs_dir2_ino8_t i8;
394     xfs_dir2_ino4_t i4;
395 } __attribute__((__packed__)) xfs_dir2_inou_t;
396 
397 typedef struct { uint8_t i[2]; } __attribute__((__packed__)) xfs_dir2_sf_off_t;
398 
399 typedef struct xfs_dir2_sf_hdr {
400     uint8_t		count;		/* count of entries */
401     uint8_t           	i8count;        /* count of 8-byte inode #s */
402     xfs_dir2_inou_t     parent;         /* parent dir inode number */
403 } __attribute__((__packed__)) xfs_dir2_sf_hdr_t;
404 
405 typedef struct xfs_dir2_sf_entry {
406     uint8_t             namelen;        /* actual name length */
407     xfs_dir2_sf_off_t   offset;         /* saved offset */
408     uint8_t             name[1];        /* name, variable size */
409     xfs_dir2_inou_t	inumber;	/* inode number, var. offset */
410 } __attribute__((__packed__)) xfs_dir2_sf_entry_t;
411 
412 typedef struct xfs_dir2_sf {
413     xfs_dir2_sf_hdr_t       hdr;            /* shortform header */
414     xfs_dir2_sf_entry_t     list[1];        /* shortform entries */
415 } __attribute__((__packed__)) xfs_dir2_sf_t;
416 
417 typedef xfs_ino_t	xfs_intino_t;
418 
xfs_dir2_sf_get_inumber(xfs_dir2_sf_t * sfp,xfs_dir2_inou_t * from)419 static inline xfs_intino_t xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp,
420 						   xfs_dir2_inou_t *from)
421 {
422     return ((sfp)->hdr.i8count == 0 ? \
423 	    (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \
424 	    (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8));
425 }
426 
427 /*
428  * DIR2 Data block structures.
429  *
430  * A pure data block looks like the following drawing on disk:
431  *
432  *    +-------------------------------------------------+
433  *    | xfs_dir2_data_hdr_t                             |
434  *    +-------------------------------------------------+
435  *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
436  *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
437  *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
438  *    | ...                                             |
439  *    +-------------------------------------------------+
440  *    | unused space                                    |
441  *    +-------------------------------------------------+
442  *
443  * As all the entries are variable size structure the accessors below should
444  * be used to iterate over them.
445  *
446  * In addition to the pure data blocks for the data and node formats.
447  * most structures are also used for the combined data/freespace "block"
448  * format below.
449  */
450 #define XFS_DIR2_DATA_ALIGN_LOG 3
451 #define XFS_DIR2_DATA_ALIGN     (1 << XFS_DIR2_DATA_ALIGN_LOG)
452 #define XFS_DIR2_DATA_FREE_TAG  0xffff
453 #define XFS_DIR2_DATA_FD_COUNT  3
454 
455 /*
456  * Directory address space divided into sections.
457  * spaces separated by 32GB.
458  */
459 #define XFS_DIR2_SPACE_SIZE	(1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
460 
461 typedef struct xfs_dir2_data_free {
462     uint16_t offset;
463     uint16_t length;
464 } __attribute__((__packed__)) xfs_dir2_data_free_t;
465 
466 typedef struct xfs_dir2_data_hdr {
467     uint32_t magic;
468     xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
469 } __attribute__((__packed__)) xfs_dir2_data_hdr_t;
470 
471 typedef struct xfs_dir2_data_entry {
472     uint64_t inumber; /* inode number */
473     uint8_t  namelen; /* name length */
474     uint8_t  name[];  /* name types, no null */
475  /* uint16_t tag; */  /* starting offset of us */
476 } __attribute__((__packed__)) xfs_dir2_data_entry_t;
477 
478 typedef struct xfs_dir2_data_unused {
479     uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */
480     uint16_t length;  /* total free length */
481                       /* variable offset */
482  /* uint16_t tag; */  /* starting offset of us */
483 } __attribute__((__packed__)) xfs_dir2_data_unused_t;
484 
485 /**
486  * rol32 - rotate a 32-bit value left
487  * @word: value to rotate
488  * @shift: bits to roll
489  */
rol32(uint32_t word,signed int shift)490 static inline uint32_t rol32(uint32_t word, signed int shift)
491 {
492     return (word << shift) | (word >> (32 - shift));
493 }
494 
495 #define roundup(x, y) (					\
496 {							\
497 	const typeof(y) __y = y;			\
498 	(((x) + (__y - 1)) / __y) * __y;		\
499 }							\
500 )
501 
xfs_dir2_data_entsize(int n)502 static inline int xfs_dir2_data_entsize(int n)
503 {
504     return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
505 			(unsigned int)sizeof(uint16_t), XFS_DIR2_DATA_ALIGN);
506 }
507 
508 static inline uint16_t *
xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry * dep)509 xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
510 {
511     return (uint16_t *)((char *)dep +
512 	    xfs_dir2_data_entsize(dep->namelen) - sizeof(uint16_t));
513 }
514 
515 static inline uint16_t *
xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused * dup)516 xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
517 {
518     return (uint16_t *)((char *)dup +
519 	    be16_to_cpu(dup->length) - sizeof(uint16_t));
520 }
521 
522 typedef struct xfs_dir2_block_tail {
523     uint32_t 		count;			/* count of leaf entries */
524     uint32_t 		stale;			/* count of stale lf entries */
525 } __attribute__((__packed__)) xfs_dir2_block_tail_t;
526 
527 static inline struct xfs_dir2_block_tail *
xfs_dir2_block_tail_p(struct xfs_fs_info * fs_info,struct xfs_dir2_data_hdr * hdr)528 xfs_dir2_block_tail_p(struct xfs_fs_info *fs_info, struct xfs_dir2_data_hdr *hdr)
529 {
530     return ((struct xfs_dir2_block_tail *)
531 	    ((char *)hdr + fs_info->dirblksize)) - 1;
532 }
533 
534 static inline uint32_t
xfs_dir2_db_to_da(struct fs_info * fs,uint32_t db)535 xfs_dir2_db_to_da(struct fs_info *fs, uint32_t db)
536 {
537     return db << XFS_INFO(fs)->dirblklog;
538 }
539 
540 static inline int64_t
xfs_dir2_dataptr_to_byte(uint32_t dp)541 xfs_dir2_dataptr_to_byte(uint32_t dp)
542 {
543     return (int64_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
544 }
545 
546 static inline uint32_t
xfs_dir2_byte_to_db(struct fs_info * fs,int64_t by)547 xfs_dir2_byte_to_db(struct fs_info *fs, int64_t by)
548 {
549     return (uint32_t)
550 	    (by >> (XFS_INFO(fs)->block_shift + XFS_INFO(fs)->dirblklog));
551 }
552 
553 static inline uint32_t
xfs_dir2_dataptr_to_db(struct fs_info * fs,uint32_t dp)554 xfs_dir2_dataptr_to_db(struct fs_info *fs, uint32_t dp)
555 {
556     return xfs_dir2_byte_to_db(fs, xfs_dir2_dataptr_to_byte(dp));
557 }
558 
559 static inline unsigned int
xfs_dir2_byte_to_off(struct fs_info * fs,int64_t by)560 xfs_dir2_byte_to_off(struct fs_info *fs, int64_t by)
561 {
562     return (unsigned int)(by &
563         (( 1 << (XFS_INFO(fs)->block_shift + XFS_INFO(fs)->dirblklog)) - 1));
564 }
565 
566 static inline unsigned int
xfs_dir2_dataptr_to_off(struct fs_info * fs,uint32_t dp)567 xfs_dir2_dataptr_to_off(struct fs_info *fs, uint32_t dp)
568 {
569     return xfs_dir2_byte_to_off(fs, xfs_dir2_dataptr_to_byte(dp));
570 }
571 
572 #define XFS_DIR2_LEAF_SPACE	1
573 #define XFS_DIR2_LEAF_OFFSET	(XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
574 #define XFS_DIR2_LEAF_FIRSTDB(fs)	\
575 	xfs_dir2_byte_to_db(fs, XFS_DIR2_LEAF_OFFSET)
576 
577 typedef struct xfs_da_blkinfo {
578     uint32_t		forw;
579     uint32_t 		back;
580     uint16_t		magic;
581     uint16_t	 	pad;
582 } __attribute__((__packed__)) xfs_da_blkinfo_t;
583 
584 typedef struct xfs_dir2_leaf_hdr {
585     xfs_da_blkinfo_t	info;
586     uint16_t		count;
587     uint16_t		stale;
588 } __attribute__((__packed__)) xfs_dir2_leaf_hdr_t;
589 
590 typedef struct xfs_dir2_leaf_entry {
591     uint32_t		hashval;		/* hash value of name */
592     uint32_t		address;		/* address of data entry */
593 } __attribute__((__packed__)) xfs_dir2_leaf_entry_t;
594 
595 typedef struct xfs_dir2_leaf {
596     xfs_dir2_leaf_hdr_t 	hdr;	/* leaf header */
597     xfs_dir2_leaf_entry_t	ents[];	/* entries */
598 } __attribute__((__packed__)) xfs_dir2_leaf_t;
599 
600 #define XFS_DA_NODE_MAGIC	0xfebeU	/* magic number: non-leaf blocks */
601 #define XFS_ATTR_LEAF_MAGIC	0xfbeeU	/* magic number: attribute leaf blks */
602 #define XFS_DIR2_LEAF1_MAGIC	0xd2f1U /* magic number: v2 dirlf single blks */
603 #define XFS_DIR2_LEAFN_MAGIC	0xd2ffU	/* magic number: V2 dirlf multi blks */
604 
605 typedef struct xfs_da_intnode {
606     struct xfs_da_node_hdr {	/* constant-structure header block */
607 	xfs_da_blkinfo_t info;	/* block type, links, etc. */
608 	uint16_t count;		/* count of active entries */
609 	uint16_t level;		/* level above leaves (leaf == 0) */
610     } hdr;
611     struct xfs_da_node_entry {
612 	uint32_t hashval;	/* hash value for this descendant */
613 	uint32_t before;	/* Btree block before this key */
614     } btree[1];
615 } __attribute__((__packed__)) xfs_da_intnode_t;
616 
617 typedef struct xfs_da_node_hdr xfs_da_node_hdr_t;
618 typedef struct xfs_da_node_entry xfs_da_node_entry_t;
619 
xfs_is_valid_magicnum(const xfs_sb_t * sb)620 static inline bool xfs_is_valid_magicnum(const xfs_sb_t *sb)
621 {
622     return sb->sb_magicnum == *(uint32_t *)XFS_SB_MAGIC;
623 }
624 
xfs_is_valid_agi(xfs_agi_t * agi)625 static inline bool xfs_is_valid_agi(xfs_agi_t *agi)
626 {
627     return agi->agi_magicnum == *(uint32_t *)XFS_AGI_MAGIC;
628 }
629 
xfs_new_inode(struct fs_info * fs)630 static inline struct inode *xfs_new_inode(struct fs_info *fs)
631 {
632     struct inode *inode;
633 
634     inode = alloc_inode(fs, 0, sizeof(struct xfs_inode));
635     if (!inode)
636 	malloc_error("xfs_inode structure");
637 
638     return inode;
639 }
640 
fill_xfs_inode_pvt(struct fs_info * fs,struct inode * inode,xfs_ino_t ino)641 static inline void fill_xfs_inode_pvt(struct fs_info *fs, struct inode *inode,
642 				      xfs_ino_t ino)
643 {
644     XFS_PVT(inode)->i_agblock =
645 	agnumber_to_bytes(fs, XFS_INO_TO_AGNO(fs, ino)) >> BLOCK_SHIFT(fs);
646     XFS_PVT(inode)->i_ino_blk = ino_to_bytes(fs, ino) >> BLOCK_SHIFT(fs);
647     XFS_PVT(inode)->i_block_offset = XFS_INO_TO_OFFSET(XFS_INFO(fs), ino) <<
648                                      XFS_INFO(fs)->inode_shift;
649 }
650 
651 /*
652  * Generic btree header.
653  *
654  * This is a combination of the actual format used on disk for short and long
655  * format btrees. The first three fields are shared by both format, but
656  * the pointers are different and should be used with care.
657  *
658  * To get the size of the actual short or long form headers please use
659  * the size macros belows. Never use sizeof(xfs_btree_block);
660  */
661 typedef struct xfs_btree_block {
662     uint32_t bb_magic;			/* magic number for block type */
663     uint16_t bb_level;			/* 0 is a leaf */
664     uint16_t bb_numrecs;		/* current # of data records */
665     union {
666         struct {
667             uint32_t bb_leftsib;
668             uint32_t bb_rightsib;
669         } s;				/* short form pointers */
670         struct {
671             uint64_t bb_leftsib;
672             uint64_t bb_rightsib;
673         } l;				/* long form pointers */
674     } bb_u;				/* rest */
675 } xfs_btree_block_t;
676 
677 #define XFS_BTREE_SBLOCK_LEN 16 /* size of a short form block */
678 #define XFS_BTREE_LBLOCK_LEN 24 /* size of a long form block */
679 
680 /*
681  * Bmap root header, on-disk form only.
682  */
683 typedef struct xfs_bmdr_block {
684     uint16_t bb_level;		/* 0 is a leaf */
685     uint16_t bb_numrecs;	/* current # of data records */
686 } xfs_bmdr_block_t;
687 
688 /*
689  * Key structure for non-leaf levels of the tree.
690  */
691 typedef struct xfs_bmbt_key {
692     uint64_t br_startoff;	/* starting file offset */
693 } xfs_bmbt_key_t, xfs_bmdr_key_t;
694 
695 /* btree pointer type */
696 typedef uint64_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
697 
698 /*
699  * Btree block header size depends on a superblock flag.
700  *
701  * (not quite yet, but soon)
702  */
703 #define XFS_BMBT_BLOCK_LEN(fs) XFS_BTREE_LBLOCK_LEN
704 
705 #define XFS_BMBT_REC_ADDR(fs, block, index) \
706         ((xfs_bmbt_rec_t *) \
707                 ((char *)(block) + \
708                  XFS_BMBT_BLOCK_LEN(fs) + \
709                  ((index) - 1) * sizeof(xfs_bmbt_rec_t)))
710 
711 #define XFS_BMBT_KEY_ADDR(fs, block, index) \
712         ((xfs_bmbt_key_t *) \
713                 ((char *)(block) + \
714                  XFS_BMBT_BLOCK_LEN(fs) + \
715                  ((index) - 1) * sizeof(xfs_bmbt_key_t)))
716 
717 #define XFS_BMBT_PTR_ADDR(fs, block, index, maxrecs) \
718         ((xfs_bmbt_ptr_t *) \
719                 ((char *)(block) + \
720                  XFS_BMBT_BLOCK_LEN(fs) + \
721                  (maxrecs) * sizeof(xfs_bmbt_key_t) + \
722                  ((index) - 1) * sizeof(xfs_bmbt_ptr_t)))
723 
724 #define XFS_BMDR_REC_ADDR(block, index) \
725         ((xfs_bmdr_rec_t *) \
726                 ((char *)(block) + \
727                  sizeof(struct xfs_bmdr_block) + \
728                  ((index) - 1) * sizeof(xfs_bmdr_rec_t)))
729 
730 #define XFS_BMDR_KEY_ADDR(block, index) \
731         ((xfs_bmdr_key_t *) \
732                 ((char *)(block) + \
733                  sizeof(struct xfs_bmdr_block) + \
734                  ((index) - 1) * sizeof(xfs_bmdr_key_t)))
735 
736 #define XFS_BMDR_PTR_ADDR(block, index, maxrecs) \
737         ((xfs_bmdr_ptr_t *) \
738                 ((char *)(block) + \
739                  sizeof(struct xfs_bmdr_block) + \
740                  (maxrecs) * sizeof(xfs_bmdr_key_t) + \
741                  ((index) - 1) * sizeof(xfs_bmdr_ptr_t)))
742 
743 /*
744  * Calculate number of records in a bmap btree inode root.
745  */
746 static inline int
xfs_bmdr_maxrecs(int blocklen,int leaf)747 xfs_bmdr_maxrecs(int blocklen, int leaf)
748 {
749     blocklen -= sizeof(xfs_bmdr_block_t);
750 
751     if (leaf)
752         return blocklen / sizeof(xfs_bmdr_rec_t);
753 
754     return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t));
755 }
756 
757 #endif /* XFS_H_ */
758