Home | History | Annotate | Download | only in xfs
      1 /*
      2  * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr (at) 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 
    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 
    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  */
    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 
    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 *
    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 *
    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 *
    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
    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
    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
    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
    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
    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
    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 
    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 
    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 
    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 
    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
    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