162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2000-2005 Silicon Graphics, Inc.
462306a36Sopenharmony_ci * All Rights Reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __XFS_FORMAT_H__
762306a36Sopenharmony_ci#define __XFS_FORMAT_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/*
1062306a36Sopenharmony_ci * XFS On Disk Format Definitions
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * This header file defines all the on-disk format definitions for
1362306a36Sopenharmony_ci * general XFS objects. Directory and attribute related objects are defined in
1462306a36Sopenharmony_ci * xfs_da_format.h, which log and log item formats are defined in
1562306a36Sopenharmony_ci * xfs_log_format.h. Everything else goes here.
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistruct xfs_mount;
1962306a36Sopenharmony_cistruct xfs_trans;
2062306a36Sopenharmony_cistruct xfs_inode;
2162306a36Sopenharmony_cistruct xfs_buf;
2262306a36Sopenharmony_cistruct xfs_ifork;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci/*
2562306a36Sopenharmony_ci * Super block
2662306a36Sopenharmony_ci * Fits into a sector-sized buffer at address 0 of each allocation group.
2762306a36Sopenharmony_ci * Only the first of these is ever updated except during growfs.
2862306a36Sopenharmony_ci */
2962306a36Sopenharmony_ci#define	XFS_SB_MAGIC		0x58465342	/* 'XFSB' */
3062306a36Sopenharmony_ci#define	XFS_SB_VERSION_1	1		/* 5.3, 6.0.1, 6.1 */
3162306a36Sopenharmony_ci#define	XFS_SB_VERSION_2	2		/* 6.2 - attributes */
3262306a36Sopenharmony_ci#define	XFS_SB_VERSION_3	3		/* 6.2 - new inode version */
3362306a36Sopenharmony_ci#define	XFS_SB_VERSION_4	4		/* 6.2+ - bitmask version */
3462306a36Sopenharmony_ci#define	XFS_SB_VERSION_5	5		/* CRC enabled filesystem */
3562306a36Sopenharmony_ci#define	XFS_SB_VERSION_NUMBITS		0x000f
3662306a36Sopenharmony_ci#define	XFS_SB_VERSION_ALLFBITS		0xfff0
3762306a36Sopenharmony_ci#define	XFS_SB_VERSION_ATTRBIT		0x0010
3862306a36Sopenharmony_ci#define	XFS_SB_VERSION_NLINKBIT		0x0020
3962306a36Sopenharmony_ci#define	XFS_SB_VERSION_QUOTABIT		0x0040
4062306a36Sopenharmony_ci#define	XFS_SB_VERSION_ALIGNBIT		0x0080
4162306a36Sopenharmony_ci#define	XFS_SB_VERSION_DALIGNBIT	0x0100
4262306a36Sopenharmony_ci#define	XFS_SB_VERSION_SHAREDBIT	0x0200
4362306a36Sopenharmony_ci#define XFS_SB_VERSION_LOGV2BIT		0x0400
4462306a36Sopenharmony_ci#define XFS_SB_VERSION_SECTORBIT	0x0800
4562306a36Sopenharmony_ci#define	XFS_SB_VERSION_EXTFLGBIT	0x1000
4662306a36Sopenharmony_ci#define	XFS_SB_VERSION_DIRV2BIT		0x2000
4762306a36Sopenharmony_ci#define	XFS_SB_VERSION_BORGBIT		0x4000	/* ASCII only case-insens. */
4862306a36Sopenharmony_ci#define	XFS_SB_VERSION_MOREBITSBIT	0x8000
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/*
5162306a36Sopenharmony_ci * The size of a single extended attribute on disk is limited by
5262306a36Sopenharmony_ci * the size of index values within the attribute entries themselves.
5362306a36Sopenharmony_ci * These are be16 fields, so we can only support attribute data
5462306a36Sopenharmony_ci * sizes up to 2^16 bytes in length.
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_ci#define XFS_XATTR_SIZE_MAX (1 << 16)
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/*
5962306a36Sopenharmony_ci * Supported feature bit list is just all bits in the versionnum field because
6062306a36Sopenharmony_ci * we've used them all up and understand them all. Except, of course, for the
6162306a36Sopenharmony_ci * shared superblock bit, which nobody knows what it does and so is unsupported.
6262306a36Sopenharmony_ci */
6362306a36Sopenharmony_ci#define	XFS_SB_VERSION_OKBITS		\
6462306a36Sopenharmony_ci	((XFS_SB_VERSION_NUMBITS | XFS_SB_VERSION_ALLFBITS) & \
6562306a36Sopenharmony_ci		~XFS_SB_VERSION_SHAREDBIT)
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci/*
6862306a36Sopenharmony_ci * There are two words to hold XFS "feature" bits: the original
6962306a36Sopenharmony_ci * word, sb_versionnum, and sb_features2.  Whenever a bit is set in
7062306a36Sopenharmony_ci * sb_features2, the feature bit XFS_SB_VERSION_MOREBITSBIT must be set.
7162306a36Sopenharmony_ci *
7262306a36Sopenharmony_ci * These defines represent bits in sb_features2.
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_ci#define XFS_SB_VERSION2_RESERVED1BIT	0x00000001
7562306a36Sopenharmony_ci#define XFS_SB_VERSION2_LAZYSBCOUNTBIT	0x00000002	/* Superblk counters */
7662306a36Sopenharmony_ci#define XFS_SB_VERSION2_RESERVED4BIT	0x00000004
7762306a36Sopenharmony_ci#define XFS_SB_VERSION2_ATTR2BIT	0x00000008	/* Inline attr rework */
7862306a36Sopenharmony_ci#define XFS_SB_VERSION2_PARENTBIT	0x00000010	/* parent pointers */
7962306a36Sopenharmony_ci#define XFS_SB_VERSION2_PROJID32BIT	0x00000080	/* 32 bit project id */
8062306a36Sopenharmony_ci#define XFS_SB_VERSION2_CRCBIT		0x00000100	/* metadata CRCs */
8162306a36Sopenharmony_ci#define XFS_SB_VERSION2_FTYPE		0x00000200	/* inode type in dir */
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci#define	XFS_SB_VERSION2_OKBITS		\
8462306a36Sopenharmony_ci	(XFS_SB_VERSION2_LAZYSBCOUNTBIT	| \
8562306a36Sopenharmony_ci	 XFS_SB_VERSION2_ATTR2BIT	| \
8662306a36Sopenharmony_ci	 XFS_SB_VERSION2_PROJID32BIT	| \
8762306a36Sopenharmony_ci	 XFS_SB_VERSION2_FTYPE)
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/* Maximum size of the xfs filesystem label, no terminating NULL */
9062306a36Sopenharmony_ci#define XFSLABEL_MAX			12
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/*
9362306a36Sopenharmony_ci * Superblock - in core version.  Must match the ondisk version below.
9462306a36Sopenharmony_ci * Must be padded to 64 bit alignment.
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_citypedef struct xfs_sb {
9762306a36Sopenharmony_ci	uint32_t	sb_magicnum;	/* magic number == XFS_SB_MAGIC */
9862306a36Sopenharmony_ci	uint32_t	sb_blocksize;	/* logical block size, bytes */
9962306a36Sopenharmony_ci	xfs_rfsblock_t	sb_dblocks;	/* number of data blocks */
10062306a36Sopenharmony_ci	xfs_rfsblock_t	sb_rblocks;	/* number of realtime blocks */
10162306a36Sopenharmony_ci	xfs_rtblock_t	sb_rextents;	/* number of realtime extents */
10262306a36Sopenharmony_ci	uuid_t		sb_uuid;	/* user-visible file system unique id */
10362306a36Sopenharmony_ci	xfs_fsblock_t	sb_logstart;	/* starting block of log if internal */
10462306a36Sopenharmony_ci	xfs_ino_t	sb_rootino;	/* root inode number */
10562306a36Sopenharmony_ci	xfs_ino_t	sb_rbmino;	/* bitmap inode for realtime extents */
10662306a36Sopenharmony_ci	xfs_ino_t	sb_rsumino;	/* summary inode for rt bitmap */
10762306a36Sopenharmony_ci	xfs_agblock_t	sb_rextsize;	/* realtime extent size, blocks */
10862306a36Sopenharmony_ci	xfs_agblock_t	sb_agblocks;	/* size of an allocation group */
10962306a36Sopenharmony_ci	xfs_agnumber_t	sb_agcount;	/* number of allocation groups */
11062306a36Sopenharmony_ci	xfs_extlen_t	sb_rbmblocks;	/* number of rt bitmap blocks */
11162306a36Sopenharmony_ci	xfs_extlen_t	sb_logblocks;	/* number of log blocks */
11262306a36Sopenharmony_ci	uint16_t	sb_versionnum;	/* header version == XFS_SB_VERSION */
11362306a36Sopenharmony_ci	uint16_t	sb_sectsize;	/* volume sector size, bytes */
11462306a36Sopenharmony_ci	uint16_t	sb_inodesize;	/* inode size, bytes */
11562306a36Sopenharmony_ci	uint16_t	sb_inopblock;	/* inodes per block */
11662306a36Sopenharmony_ci	char		sb_fname[XFSLABEL_MAX]; /* file system name */
11762306a36Sopenharmony_ci	uint8_t		sb_blocklog;	/* log2 of sb_blocksize */
11862306a36Sopenharmony_ci	uint8_t		sb_sectlog;	/* log2 of sb_sectsize */
11962306a36Sopenharmony_ci	uint8_t		sb_inodelog;	/* log2 of sb_inodesize */
12062306a36Sopenharmony_ci	uint8_t		sb_inopblog;	/* log2 of sb_inopblock */
12162306a36Sopenharmony_ci	uint8_t		sb_agblklog;	/* log2 of sb_agblocks (rounded up) */
12262306a36Sopenharmony_ci	uint8_t		sb_rextslog;	/* log2 of sb_rextents */
12362306a36Sopenharmony_ci	uint8_t		sb_inprogress;	/* mkfs is in progress, don't mount */
12462306a36Sopenharmony_ci	uint8_t		sb_imax_pct;	/* max % of fs for inode space */
12562306a36Sopenharmony_ci					/* statistics */
12662306a36Sopenharmony_ci	/*
12762306a36Sopenharmony_ci	 * These fields must remain contiguous.  If you really
12862306a36Sopenharmony_ci	 * want to change their layout, make sure you fix the
12962306a36Sopenharmony_ci	 * code in xfs_trans_apply_sb_deltas().
13062306a36Sopenharmony_ci	 */
13162306a36Sopenharmony_ci	uint64_t	sb_icount;	/* allocated inodes */
13262306a36Sopenharmony_ci	uint64_t	sb_ifree;	/* free inodes */
13362306a36Sopenharmony_ci	uint64_t	sb_fdblocks;	/* free data blocks */
13462306a36Sopenharmony_ci	uint64_t	sb_frextents;	/* free realtime extents */
13562306a36Sopenharmony_ci	/*
13662306a36Sopenharmony_ci	 * End contiguous fields.
13762306a36Sopenharmony_ci	 */
13862306a36Sopenharmony_ci	xfs_ino_t	sb_uquotino;	/* user quota inode */
13962306a36Sopenharmony_ci	xfs_ino_t	sb_gquotino;	/* group quota inode */
14062306a36Sopenharmony_ci	uint16_t	sb_qflags;	/* quota flags */
14162306a36Sopenharmony_ci	uint8_t		sb_flags;	/* misc. flags */
14262306a36Sopenharmony_ci	uint8_t		sb_shared_vn;	/* shared version number */
14362306a36Sopenharmony_ci	xfs_extlen_t	sb_inoalignmt;	/* inode chunk alignment, fsblocks */
14462306a36Sopenharmony_ci	uint32_t	sb_unit;	/* stripe or raid unit */
14562306a36Sopenharmony_ci	uint32_t	sb_width;	/* stripe or raid width */
14662306a36Sopenharmony_ci	uint8_t		sb_dirblklog;	/* log2 of dir block size (fsbs) */
14762306a36Sopenharmony_ci	uint8_t		sb_logsectlog;	/* log2 of the log sector size */
14862306a36Sopenharmony_ci	uint16_t	sb_logsectsize;	/* sector size for the log, bytes */
14962306a36Sopenharmony_ci	uint32_t	sb_logsunit;	/* stripe unit size for the log */
15062306a36Sopenharmony_ci	uint32_t	sb_features2;	/* additional feature bits */
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	/*
15362306a36Sopenharmony_ci	 * bad features2 field as a result of failing to pad the sb structure to
15462306a36Sopenharmony_ci	 * 64 bits. Some machines will be using this field for features2 bits.
15562306a36Sopenharmony_ci	 * Easiest just to mark it bad and not use it for anything else.
15662306a36Sopenharmony_ci	 *
15762306a36Sopenharmony_ci	 * This is not kept up to date in memory; it is always overwritten by
15862306a36Sopenharmony_ci	 * the value in sb_features2 when formatting the incore superblock to
15962306a36Sopenharmony_ci	 * the disk buffer.
16062306a36Sopenharmony_ci	 */
16162306a36Sopenharmony_ci	uint32_t	sb_bad_features2;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	/* version 5 superblock fields start here */
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	/* feature masks */
16662306a36Sopenharmony_ci	uint32_t	sb_features_compat;
16762306a36Sopenharmony_ci	uint32_t	sb_features_ro_compat;
16862306a36Sopenharmony_ci	uint32_t	sb_features_incompat;
16962306a36Sopenharmony_ci	uint32_t	sb_features_log_incompat;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	uint32_t	sb_crc;		/* superblock crc */
17262306a36Sopenharmony_ci	xfs_extlen_t	sb_spino_align;	/* sparse inode chunk alignment */
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	xfs_ino_t	sb_pquotino;	/* project quota inode */
17562306a36Sopenharmony_ci	xfs_lsn_t	sb_lsn;		/* last write sequence */
17662306a36Sopenharmony_ci	uuid_t		sb_meta_uuid;	/* metadata file system unique id */
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	/* must be padded to 64 bit alignment */
17962306a36Sopenharmony_ci} xfs_sb_t;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci#define XFS_SB_CRC_OFF		offsetof(struct xfs_sb, sb_crc)
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/*
18462306a36Sopenharmony_ci * Superblock - on disk version.  Must match the in core version above.
18562306a36Sopenharmony_ci * Must be padded to 64 bit alignment.
18662306a36Sopenharmony_ci */
18762306a36Sopenharmony_cistruct xfs_dsb {
18862306a36Sopenharmony_ci	__be32		sb_magicnum;	/* magic number == XFS_SB_MAGIC */
18962306a36Sopenharmony_ci	__be32		sb_blocksize;	/* logical block size, bytes */
19062306a36Sopenharmony_ci	__be64		sb_dblocks;	/* number of data blocks */
19162306a36Sopenharmony_ci	__be64		sb_rblocks;	/* number of realtime blocks */
19262306a36Sopenharmony_ci	__be64		sb_rextents;	/* number of realtime extents */
19362306a36Sopenharmony_ci	uuid_t		sb_uuid;	/* user-visible file system unique id */
19462306a36Sopenharmony_ci	__be64		sb_logstart;	/* starting block of log if internal */
19562306a36Sopenharmony_ci	__be64		sb_rootino;	/* root inode number */
19662306a36Sopenharmony_ci	__be64		sb_rbmino;	/* bitmap inode for realtime extents */
19762306a36Sopenharmony_ci	__be64		sb_rsumino;	/* summary inode for rt bitmap */
19862306a36Sopenharmony_ci	__be32		sb_rextsize;	/* realtime extent size, blocks */
19962306a36Sopenharmony_ci	__be32		sb_agblocks;	/* size of an allocation group */
20062306a36Sopenharmony_ci	__be32		sb_agcount;	/* number of allocation groups */
20162306a36Sopenharmony_ci	__be32		sb_rbmblocks;	/* number of rt bitmap blocks */
20262306a36Sopenharmony_ci	__be32		sb_logblocks;	/* number of log blocks */
20362306a36Sopenharmony_ci	__be16		sb_versionnum;	/* header version == XFS_SB_VERSION */
20462306a36Sopenharmony_ci	__be16		sb_sectsize;	/* volume sector size, bytes */
20562306a36Sopenharmony_ci	__be16		sb_inodesize;	/* inode size, bytes */
20662306a36Sopenharmony_ci	__be16		sb_inopblock;	/* inodes per block */
20762306a36Sopenharmony_ci	char		sb_fname[XFSLABEL_MAX]; /* file system name */
20862306a36Sopenharmony_ci	__u8		sb_blocklog;	/* log2 of sb_blocksize */
20962306a36Sopenharmony_ci	__u8		sb_sectlog;	/* log2 of sb_sectsize */
21062306a36Sopenharmony_ci	__u8		sb_inodelog;	/* log2 of sb_inodesize */
21162306a36Sopenharmony_ci	__u8		sb_inopblog;	/* log2 of sb_inopblock */
21262306a36Sopenharmony_ci	__u8		sb_agblklog;	/* log2 of sb_agblocks (rounded up) */
21362306a36Sopenharmony_ci	__u8		sb_rextslog;	/* log2 of sb_rextents */
21462306a36Sopenharmony_ci	__u8		sb_inprogress;	/* mkfs is in progress, don't mount */
21562306a36Sopenharmony_ci	__u8		sb_imax_pct;	/* max % of fs for inode space */
21662306a36Sopenharmony_ci					/* statistics */
21762306a36Sopenharmony_ci	/*
21862306a36Sopenharmony_ci	 * These fields must remain contiguous.  If you really
21962306a36Sopenharmony_ci	 * want to change their layout, make sure you fix the
22062306a36Sopenharmony_ci	 * code in xfs_trans_apply_sb_deltas().
22162306a36Sopenharmony_ci	 */
22262306a36Sopenharmony_ci	__be64		sb_icount;	/* allocated inodes */
22362306a36Sopenharmony_ci	__be64		sb_ifree;	/* free inodes */
22462306a36Sopenharmony_ci	__be64		sb_fdblocks;	/* free data blocks */
22562306a36Sopenharmony_ci	__be64		sb_frextents;	/* free realtime extents */
22662306a36Sopenharmony_ci	/*
22762306a36Sopenharmony_ci	 * End contiguous fields.
22862306a36Sopenharmony_ci	 */
22962306a36Sopenharmony_ci	__be64		sb_uquotino;	/* user quota inode */
23062306a36Sopenharmony_ci	__be64		sb_gquotino;	/* group quota inode */
23162306a36Sopenharmony_ci	__be16		sb_qflags;	/* quota flags */
23262306a36Sopenharmony_ci	__u8		sb_flags;	/* misc. flags */
23362306a36Sopenharmony_ci	__u8		sb_shared_vn;	/* shared version number */
23462306a36Sopenharmony_ci	__be32		sb_inoalignmt;	/* inode chunk alignment, fsblocks */
23562306a36Sopenharmony_ci	__be32		sb_unit;	/* stripe or raid unit */
23662306a36Sopenharmony_ci	__be32		sb_width;	/* stripe or raid width */
23762306a36Sopenharmony_ci	__u8		sb_dirblklog;	/* log2 of dir block size (fsbs) */
23862306a36Sopenharmony_ci	__u8		sb_logsectlog;	/* log2 of the log sector size */
23962306a36Sopenharmony_ci	__be16		sb_logsectsize;	/* sector size for the log, bytes */
24062306a36Sopenharmony_ci	__be32		sb_logsunit;	/* stripe unit size for the log */
24162306a36Sopenharmony_ci	__be32		sb_features2;	/* additional feature bits */
24262306a36Sopenharmony_ci	/*
24362306a36Sopenharmony_ci	 * bad features2 field as a result of failing to pad the sb
24462306a36Sopenharmony_ci	 * structure to 64 bits. Some machines will be using this field
24562306a36Sopenharmony_ci	 * for features2 bits. Easiest just to mark it bad and not use
24662306a36Sopenharmony_ci	 * it for anything else.
24762306a36Sopenharmony_ci	 */
24862306a36Sopenharmony_ci	__be32		sb_bad_features2;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	/* version 5 superblock fields start here */
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	/* feature masks */
25362306a36Sopenharmony_ci	__be32		sb_features_compat;
25462306a36Sopenharmony_ci	__be32		sb_features_ro_compat;
25562306a36Sopenharmony_ci	__be32		sb_features_incompat;
25662306a36Sopenharmony_ci	__be32		sb_features_log_incompat;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	__le32		sb_crc;		/* superblock crc */
25962306a36Sopenharmony_ci	__be32		sb_spino_align;	/* sparse inode chunk alignment */
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	__be64		sb_pquotino;	/* project quota inode */
26262306a36Sopenharmony_ci	__be64		sb_lsn;		/* last write sequence */
26362306a36Sopenharmony_ci	uuid_t		sb_meta_uuid;	/* metadata file system unique id */
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	/* must be padded to 64 bit alignment */
26662306a36Sopenharmony_ci};
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci/*
26962306a36Sopenharmony_ci * Misc. Flags - warning - these will be cleared by xfs_repair unless
27062306a36Sopenharmony_ci * a feature bit is set when the flag is used.
27162306a36Sopenharmony_ci */
27262306a36Sopenharmony_ci#define XFS_SBF_NOFLAGS		0x00	/* no flags set */
27362306a36Sopenharmony_ci#define XFS_SBF_READONLY	0x01	/* only read-only mounts allowed */
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci/*
27662306a36Sopenharmony_ci * define max. shared version we can interoperate with
27762306a36Sopenharmony_ci */
27862306a36Sopenharmony_ci#define XFS_SB_MAX_SHARED_VN	0
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci#define	XFS_SB_VERSION_NUM(sbp)	((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_cistatic inline bool xfs_sb_is_v5(struct xfs_sb *sbp)
28362306a36Sopenharmony_ci{
28462306a36Sopenharmony_ci	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
28562306a36Sopenharmony_ci}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci/*
28862306a36Sopenharmony_ci * Detect a mismatched features2 field.  Older kernels read/wrote
28962306a36Sopenharmony_ci * this into the wrong slot, so to be safe we keep them in sync.
29062306a36Sopenharmony_ci */
29162306a36Sopenharmony_cistatic inline bool xfs_sb_has_mismatched_features2(struct xfs_sb *sbp)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	return sbp->sb_bad_features2 != sbp->sb_features2;
29462306a36Sopenharmony_ci}
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cistatic inline bool xfs_sb_version_hasmorebits(struct xfs_sb *sbp)
29762306a36Sopenharmony_ci{
29862306a36Sopenharmony_ci	return xfs_sb_is_v5(sbp) ||
29962306a36Sopenharmony_ci	       (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT);
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_cistatic inline void xfs_sb_version_addattr(struct xfs_sb *sbp)
30362306a36Sopenharmony_ci{
30462306a36Sopenharmony_ci	sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
30562306a36Sopenharmony_ci}
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_cistatic inline void xfs_sb_version_addquota(struct xfs_sb *sbp)
30862306a36Sopenharmony_ci{
30962306a36Sopenharmony_ci	sbp->sb_versionnum |= XFS_SB_VERSION_QUOTABIT;
31062306a36Sopenharmony_ci}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_cistatic inline void xfs_sb_version_addattr2(struct xfs_sb *sbp)
31362306a36Sopenharmony_ci{
31462306a36Sopenharmony_ci	sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
31562306a36Sopenharmony_ci	sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic inline void xfs_sb_version_addprojid32(struct xfs_sb *sbp)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
32162306a36Sopenharmony_ci	sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
32262306a36Sopenharmony_ci}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci/*
32562306a36Sopenharmony_ci * Extended v5 superblock feature masks. These are to be used for new v5
32662306a36Sopenharmony_ci * superblock features only.
32762306a36Sopenharmony_ci *
32862306a36Sopenharmony_ci * Compat features are new features that old kernels will not notice or affect
32962306a36Sopenharmony_ci * and so can mount read-write without issues.
33062306a36Sopenharmony_ci *
33162306a36Sopenharmony_ci * RO-Compat (read only) are features that old kernels can read but will break
33262306a36Sopenharmony_ci * if they write. Hence only read-only mounts of such filesystems are allowed on
33362306a36Sopenharmony_ci * kernels that don't support the feature bit.
33462306a36Sopenharmony_ci *
33562306a36Sopenharmony_ci * InCompat features are features which old kernels will not understand and so
33662306a36Sopenharmony_ci * must not mount.
33762306a36Sopenharmony_ci *
33862306a36Sopenharmony_ci * Log-InCompat features are for changes to log formats or new transactions that
33962306a36Sopenharmony_ci * can't be replayed on older kernels. The fields are set when the filesystem is
34062306a36Sopenharmony_ci * mounted, and a clean unmount clears the fields.
34162306a36Sopenharmony_ci */
34262306a36Sopenharmony_ci#define XFS_SB_FEAT_COMPAT_ALL 0
34362306a36Sopenharmony_ci#define XFS_SB_FEAT_COMPAT_UNKNOWN	~XFS_SB_FEAT_COMPAT_ALL
34462306a36Sopenharmony_cistatic inline bool
34562306a36Sopenharmony_cixfs_sb_has_compat_feature(
34662306a36Sopenharmony_ci	struct xfs_sb	*sbp,
34762306a36Sopenharmony_ci	uint32_t	feature)
34862306a36Sopenharmony_ci{
34962306a36Sopenharmony_ci	return (sbp->sb_features_compat & feature) != 0;
35062306a36Sopenharmony_ci}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci#define XFS_SB_FEAT_RO_COMPAT_FINOBT   (1 << 0)		/* free inode btree */
35362306a36Sopenharmony_ci#define XFS_SB_FEAT_RO_COMPAT_RMAPBT   (1 << 1)		/* reverse map btree */
35462306a36Sopenharmony_ci#define XFS_SB_FEAT_RO_COMPAT_REFLINK  (1 << 2)		/* reflinked files */
35562306a36Sopenharmony_ci#define XFS_SB_FEAT_RO_COMPAT_INOBTCNT (1 << 3)		/* inobt block counts */
35662306a36Sopenharmony_ci#define XFS_SB_FEAT_RO_COMPAT_ALL \
35762306a36Sopenharmony_ci		(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
35862306a36Sopenharmony_ci		 XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
35962306a36Sopenharmony_ci		 XFS_SB_FEAT_RO_COMPAT_REFLINK| \
36062306a36Sopenharmony_ci		 XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
36162306a36Sopenharmony_ci#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN	~XFS_SB_FEAT_RO_COMPAT_ALL
36262306a36Sopenharmony_cistatic inline bool
36362306a36Sopenharmony_cixfs_sb_has_ro_compat_feature(
36462306a36Sopenharmony_ci	struct xfs_sb	*sbp,
36562306a36Sopenharmony_ci	uint32_t	feature)
36662306a36Sopenharmony_ci{
36762306a36Sopenharmony_ci	return (sbp->sb_features_ro_compat & feature) != 0;
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_FTYPE	(1 << 0)	/* filetype in dirent */
37162306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_SPINODES	(1 << 1)	/* sparse inode chunks */
37262306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_META_UUID	(1 << 2)	/* metadata UUID */
37362306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_BIGTIME	(1 << 3)	/* large timestamps */
37462306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4)	/* needs xfs_repair */
37562306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_NREXT64	(1 << 5)	/* large extent counters */
37662306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_ALL \
37762306a36Sopenharmony_ci		(XFS_SB_FEAT_INCOMPAT_FTYPE|	\
37862306a36Sopenharmony_ci		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\
37962306a36Sopenharmony_ci		 XFS_SB_FEAT_INCOMPAT_META_UUID| \
38062306a36Sopenharmony_ci		 XFS_SB_FEAT_INCOMPAT_BIGTIME| \
38162306a36Sopenharmony_ci		 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR| \
38262306a36Sopenharmony_ci		 XFS_SB_FEAT_INCOMPAT_NREXT64)
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_UNKNOWN	~XFS_SB_FEAT_INCOMPAT_ALL
38562306a36Sopenharmony_cistatic inline bool
38662306a36Sopenharmony_cixfs_sb_has_incompat_feature(
38762306a36Sopenharmony_ci	struct xfs_sb	*sbp,
38862306a36Sopenharmony_ci	uint32_t	feature)
38962306a36Sopenharmony_ci{
39062306a36Sopenharmony_ci	return (sbp->sb_features_incompat & feature) != 0;
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_LOG_XATTRS   (1 << 0)	/* Delayed Attributes */
39462306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_LOG_ALL \
39562306a36Sopenharmony_ci	(XFS_SB_FEAT_INCOMPAT_LOG_XATTRS)
39662306a36Sopenharmony_ci#define XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN	~XFS_SB_FEAT_INCOMPAT_LOG_ALL
39762306a36Sopenharmony_cistatic inline bool
39862306a36Sopenharmony_cixfs_sb_has_incompat_log_feature(
39962306a36Sopenharmony_ci	struct xfs_sb	*sbp,
40062306a36Sopenharmony_ci	uint32_t	feature)
40162306a36Sopenharmony_ci{
40262306a36Sopenharmony_ci	return (sbp->sb_features_log_incompat & feature) != 0;
40362306a36Sopenharmony_ci}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_cistatic inline void
40662306a36Sopenharmony_cixfs_sb_remove_incompat_log_features(
40762306a36Sopenharmony_ci	struct xfs_sb	*sbp)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	sbp->sb_features_log_incompat &= ~XFS_SB_FEAT_INCOMPAT_LOG_ALL;
41062306a36Sopenharmony_ci}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_cistatic inline void
41362306a36Sopenharmony_cixfs_sb_add_incompat_log_features(
41462306a36Sopenharmony_ci	struct xfs_sb	*sbp,
41562306a36Sopenharmony_ci	unsigned int	features)
41662306a36Sopenharmony_ci{
41762306a36Sopenharmony_ci	sbp->sb_features_log_incompat |= features;
41862306a36Sopenharmony_ci}
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_cistatic inline bool xfs_sb_version_haslogxattrs(struct xfs_sb *sbp)
42162306a36Sopenharmony_ci{
42262306a36Sopenharmony_ci	return xfs_sb_is_v5(sbp) && (sbp->sb_features_log_incompat &
42362306a36Sopenharmony_ci		 XFS_SB_FEAT_INCOMPAT_LOG_XATTRS);
42462306a36Sopenharmony_ci}
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_cistatic inline bool
42762306a36Sopenharmony_cixfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
42862306a36Sopenharmony_ci{
42962306a36Sopenharmony_ci	return (ino == sbp->sb_uquotino ||
43062306a36Sopenharmony_ci		ino == sbp->sb_gquotino ||
43162306a36Sopenharmony_ci		ino == sbp->sb_pquotino);
43262306a36Sopenharmony_ci}
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci#define XFS_SB_DADDR		((xfs_daddr_t)0) /* daddr in filesystem/ag */
43562306a36Sopenharmony_ci#define	XFS_SB_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci#define	XFS_HDR_BLOCK(mp,d)	((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d))
43862306a36Sopenharmony_ci#define	XFS_DADDR_TO_FSB(mp,d)	XFS_AGB_TO_FSB(mp, \
43962306a36Sopenharmony_ci			xfs_daddr_to_agno(mp,d), xfs_daddr_to_agbno(mp,d))
44062306a36Sopenharmony_ci#define	XFS_FSB_TO_DADDR(mp,fsbno)	XFS_AGB_TO_DADDR(mp, \
44162306a36Sopenharmony_ci			XFS_FSB_TO_AGNO(mp,fsbno), XFS_FSB_TO_AGBNO(mp,fsbno))
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci/*
44462306a36Sopenharmony_ci * File system sector to basic block conversions.
44562306a36Sopenharmony_ci */
44662306a36Sopenharmony_ci#define XFS_FSS_TO_BB(mp,sec)	((sec) << (mp)->m_sectbb_log)
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci/*
44962306a36Sopenharmony_ci * File system block to basic block conversions.
45062306a36Sopenharmony_ci */
45162306a36Sopenharmony_ci#define	XFS_FSB_TO_BB(mp,fsbno)	((fsbno) << (mp)->m_blkbb_log)
45262306a36Sopenharmony_ci#define	XFS_BB_TO_FSB(mp,bb)	\
45362306a36Sopenharmony_ci	(((bb) + (XFS_FSB_TO_BB(mp,1) - 1)) >> (mp)->m_blkbb_log)
45462306a36Sopenharmony_ci#define	XFS_BB_TO_FSBT(mp,bb)	((bb) >> (mp)->m_blkbb_log)
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci/*
45762306a36Sopenharmony_ci * File system block to byte conversions.
45862306a36Sopenharmony_ci */
45962306a36Sopenharmony_ci#define XFS_FSB_TO_B(mp,fsbno)	((xfs_fsize_t)(fsbno) << (mp)->m_sb.sb_blocklog)
46062306a36Sopenharmony_ci#define XFS_B_TO_FSB(mp,b)	\
46162306a36Sopenharmony_ci	((((uint64_t)(b)) + (mp)->m_blockmask) >> (mp)->m_sb.sb_blocklog)
46262306a36Sopenharmony_ci#define XFS_B_TO_FSBT(mp,b)	(((uint64_t)(b)) >> (mp)->m_sb.sb_blocklog)
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci/*
46562306a36Sopenharmony_ci * Allocation group header
46662306a36Sopenharmony_ci *
46762306a36Sopenharmony_ci * This is divided into three structures, placed in sequential 512-byte
46862306a36Sopenharmony_ci * buffers after a copy of the superblock (also in a 512-byte buffer).
46962306a36Sopenharmony_ci */
47062306a36Sopenharmony_ci#define	XFS_AGF_MAGIC	0x58414746	/* 'XAGF' */
47162306a36Sopenharmony_ci#define	XFS_AGI_MAGIC	0x58414749	/* 'XAGI' */
47262306a36Sopenharmony_ci#define	XFS_AGFL_MAGIC	0x5841464c	/* 'XAFL' */
47362306a36Sopenharmony_ci#define	XFS_AGF_VERSION	1
47462306a36Sopenharmony_ci#define	XFS_AGI_VERSION	1
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci#define	XFS_AGF_GOOD_VERSION(v)	((v) == XFS_AGF_VERSION)
47762306a36Sopenharmony_ci#define	XFS_AGI_GOOD_VERSION(v)	((v) == XFS_AGI_VERSION)
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci/*
48062306a36Sopenharmony_ci * Btree number 0 is bno, 1 is cnt, 2 is rmap. This value gives the size of the
48162306a36Sopenharmony_ci * arrays below.
48262306a36Sopenharmony_ci */
48362306a36Sopenharmony_ci#define	XFS_BTNUM_AGF	((int)XFS_BTNUM_RMAPi + 1)
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci/*
48662306a36Sopenharmony_ci * The second word of agf_levels in the first a.g. overlaps the EFS
48762306a36Sopenharmony_ci * superblock's magic number.  Since the magic numbers valid for EFS
48862306a36Sopenharmony_ci * are > 64k, our value cannot be confused for an EFS superblock's.
48962306a36Sopenharmony_ci */
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_citypedef struct xfs_agf {
49262306a36Sopenharmony_ci	/*
49362306a36Sopenharmony_ci	 * Common allocation group header information
49462306a36Sopenharmony_ci	 */
49562306a36Sopenharmony_ci	__be32		agf_magicnum;	/* magic number == XFS_AGF_MAGIC */
49662306a36Sopenharmony_ci	__be32		agf_versionnum;	/* header version == XFS_AGF_VERSION */
49762306a36Sopenharmony_ci	__be32		agf_seqno;	/* sequence # starting from 0 */
49862306a36Sopenharmony_ci	__be32		agf_length;	/* size in blocks of a.g. */
49962306a36Sopenharmony_ci	/*
50062306a36Sopenharmony_ci	 * Freespace and rmap information
50162306a36Sopenharmony_ci	 */
50262306a36Sopenharmony_ci	__be32		agf_roots[XFS_BTNUM_AGF];	/* root blocks */
50362306a36Sopenharmony_ci	__be32		agf_levels[XFS_BTNUM_AGF];	/* btree levels */
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	__be32		agf_flfirst;	/* first freelist block's index */
50662306a36Sopenharmony_ci	__be32		agf_fllast;	/* last freelist block's index */
50762306a36Sopenharmony_ci	__be32		agf_flcount;	/* count of blocks in freelist */
50862306a36Sopenharmony_ci	__be32		agf_freeblks;	/* total free blocks */
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	__be32		agf_longest;	/* longest free space */
51162306a36Sopenharmony_ci	__be32		agf_btreeblks;	/* # of blocks held in AGF btrees */
51262306a36Sopenharmony_ci	uuid_t		agf_uuid;	/* uuid of filesystem */
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	__be32		agf_rmap_blocks;	/* rmapbt blocks used */
51562306a36Sopenharmony_ci	__be32		agf_refcount_blocks;	/* refcountbt blocks used */
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	__be32		agf_refcount_root;	/* refcount tree root block */
51862306a36Sopenharmony_ci	__be32		agf_refcount_level;	/* refcount btree levels */
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	/*
52162306a36Sopenharmony_ci	 * reserve some contiguous space for future logged fields before we add
52262306a36Sopenharmony_ci	 * the unlogged fields. This makes the range logging via flags and
52362306a36Sopenharmony_ci	 * structure offsets much simpler.
52462306a36Sopenharmony_ci	 */
52562306a36Sopenharmony_ci	__be64		agf_spare64[14];
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	/* unlogged fields, written during buffer writeback. */
52862306a36Sopenharmony_ci	__be64		agf_lsn;	/* last write sequence */
52962306a36Sopenharmony_ci	__be32		agf_crc;	/* crc of agf sector */
53062306a36Sopenharmony_ci	__be32		agf_spare2;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	/* structure must be padded to 64 bit alignment */
53362306a36Sopenharmony_ci} xfs_agf_t;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci#define XFS_AGF_CRC_OFF		offsetof(struct xfs_agf, agf_crc)
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci#define	XFS_AGF_MAGICNUM	(1u << 0)
53862306a36Sopenharmony_ci#define	XFS_AGF_VERSIONNUM	(1u << 1)
53962306a36Sopenharmony_ci#define	XFS_AGF_SEQNO		(1u << 2)
54062306a36Sopenharmony_ci#define	XFS_AGF_LENGTH		(1u << 3)
54162306a36Sopenharmony_ci#define	XFS_AGF_ROOTS		(1u << 4)
54262306a36Sopenharmony_ci#define	XFS_AGF_LEVELS		(1u << 5)
54362306a36Sopenharmony_ci#define	XFS_AGF_FLFIRST		(1u << 6)
54462306a36Sopenharmony_ci#define	XFS_AGF_FLLAST		(1u << 7)
54562306a36Sopenharmony_ci#define	XFS_AGF_FLCOUNT		(1u << 8)
54662306a36Sopenharmony_ci#define	XFS_AGF_FREEBLKS	(1u << 9)
54762306a36Sopenharmony_ci#define	XFS_AGF_LONGEST		(1u << 10)
54862306a36Sopenharmony_ci#define	XFS_AGF_BTREEBLKS	(1u << 11)
54962306a36Sopenharmony_ci#define	XFS_AGF_UUID		(1u << 12)
55062306a36Sopenharmony_ci#define	XFS_AGF_RMAP_BLOCKS	(1u << 13)
55162306a36Sopenharmony_ci#define	XFS_AGF_REFCOUNT_BLOCKS	(1u << 14)
55262306a36Sopenharmony_ci#define	XFS_AGF_REFCOUNT_ROOT	(1u << 15)
55362306a36Sopenharmony_ci#define	XFS_AGF_REFCOUNT_LEVEL	(1u << 16)
55462306a36Sopenharmony_ci#define	XFS_AGF_SPARE64		(1u << 17)
55562306a36Sopenharmony_ci#define	XFS_AGF_NUM_BITS	18
55662306a36Sopenharmony_ci#define	XFS_AGF_ALL_BITS	((1u << XFS_AGF_NUM_BITS) - 1)
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci#define XFS_AGF_FLAGS \
55962306a36Sopenharmony_ci	{ XFS_AGF_MAGICNUM,	"MAGICNUM" }, \
56062306a36Sopenharmony_ci	{ XFS_AGF_VERSIONNUM,	"VERSIONNUM" }, \
56162306a36Sopenharmony_ci	{ XFS_AGF_SEQNO,	"SEQNO" }, \
56262306a36Sopenharmony_ci	{ XFS_AGF_LENGTH,	"LENGTH" }, \
56362306a36Sopenharmony_ci	{ XFS_AGF_ROOTS,	"ROOTS" }, \
56462306a36Sopenharmony_ci	{ XFS_AGF_LEVELS,	"LEVELS" }, \
56562306a36Sopenharmony_ci	{ XFS_AGF_FLFIRST,	"FLFIRST" }, \
56662306a36Sopenharmony_ci	{ XFS_AGF_FLLAST,	"FLLAST" }, \
56762306a36Sopenharmony_ci	{ XFS_AGF_FLCOUNT,	"FLCOUNT" }, \
56862306a36Sopenharmony_ci	{ XFS_AGF_FREEBLKS,	"FREEBLKS" }, \
56962306a36Sopenharmony_ci	{ XFS_AGF_LONGEST,	"LONGEST" }, \
57062306a36Sopenharmony_ci	{ XFS_AGF_BTREEBLKS,	"BTREEBLKS" }, \
57162306a36Sopenharmony_ci	{ XFS_AGF_UUID,		"UUID" }, \
57262306a36Sopenharmony_ci	{ XFS_AGF_RMAP_BLOCKS,	"RMAP_BLOCKS" }, \
57362306a36Sopenharmony_ci	{ XFS_AGF_REFCOUNT_BLOCKS,	"REFCOUNT_BLOCKS" }, \
57462306a36Sopenharmony_ci	{ XFS_AGF_REFCOUNT_ROOT,	"REFCOUNT_ROOT" }, \
57562306a36Sopenharmony_ci	{ XFS_AGF_REFCOUNT_LEVEL,	"REFCOUNT_LEVEL" }, \
57662306a36Sopenharmony_ci	{ XFS_AGF_SPARE64,	"SPARE64" }
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci/* disk block (xfs_daddr_t) in the AG */
57962306a36Sopenharmony_ci#define XFS_AGF_DADDR(mp)	((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
58062306a36Sopenharmony_ci#define	XFS_AGF_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci/*
58362306a36Sopenharmony_ci * Size of the unlinked inode hash table in the agi.
58462306a36Sopenharmony_ci */
58562306a36Sopenharmony_ci#define	XFS_AGI_UNLINKED_BUCKETS	64
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_citypedef struct xfs_agi {
58862306a36Sopenharmony_ci	/*
58962306a36Sopenharmony_ci	 * Common allocation group header information
59062306a36Sopenharmony_ci	 */
59162306a36Sopenharmony_ci	__be32		agi_magicnum;	/* magic number == XFS_AGI_MAGIC */
59262306a36Sopenharmony_ci	__be32		agi_versionnum;	/* header version == XFS_AGI_VERSION */
59362306a36Sopenharmony_ci	__be32		agi_seqno;	/* sequence # starting from 0 */
59462306a36Sopenharmony_ci	__be32		agi_length;	/* size in blocks of a.g. */
59562306a36Sopenharmony_ci	/*
59662306a36Sopenharmony_ci	 * Inode information
59762306a36Sopenharmony_ci	 * Inodes are mapped by interpreting the inode number, so no
59862306a36Sopenharmony_ci	 * mapping data is needed here.
59962306a36Sopenharmony_ci	 */
60062306a36Sopenharmony_ci	__be32		agi_count;	/* count of allocated inodes */
60162306a36Sopenharmony_ci	__be32		agi_root;	/* root of inode btree */
60262306a36Sopenharmony_ci	__be32		agi_level;	/* levels in inode btree */
60362306a36Sopenharmony_ci	__be32		agi_freecount;	/* number of free inodes */
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	__be32		agi_newino;	/* new inode just allocated */
60662306a36Sopenharmony_ci	__be32		agi_dirino;	/* last directory inode chunk */
60762306a36Sopenharmony_ci	/*
60862306a36Sopenharmony_ci	 * Hash table of inodes which have been unlinked but are
60962306a36Sopenharmony_ci	 * still being referenced.
61062306a36Sopenharmony_ci	 */
61162306a36Sopenharmony_ci	__be32		agi_unlinked[XFS_AGI_UNLINKED_BUCKETS];
61262306a36Sopenharmony_ci	/*
61362306a36Sopenharmony_ci	 * This marks the end of logging region 1 and start of logging region 2.
61462306a36Sopenharmony_ci	 */
61562306a36Sopenharmony_ci	uuid_t		agi_uuid;	/* uuid of filesystem */
61662306a36Sopenharmony_ci	__be32		agi_crc;	/* crc of agi sector */
61762306a36Sopenharmony_ci	__be32		agi_pad32;
61862306a36Sopenharmony_ci	__be64		agi_lsn;	/* last write sequence */
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci	__be32		agi_free_root; /* root of the free inode btree */
62162306a36Sopenharmony_ci	__be32		agi_free_level;/* levels in free inode btree */
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	__be32		agi_iblocks;	/* inobt blocks used */
62462306a36Sopenharmony_ci	__be32		agi_fblocks;	/* finobt blocks used */
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci	/* structure must be padded to 64 bit alignment */
62762306a36Sopenharmony_ci} xfs_agi_t;
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci#define XFS_AGI_CRC_OFF		offsetof(struct xfs_agi, agi_crc)
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci#define	XFS_AGI_MAGICNUM	(1u << 0)
63262306a36Sopenharmony_ci#define	XFS_AGI_VERSIONNUM	(1u << 1)
63362306a36Sopenharmony_ci#define	XFS_AGI_SEQNO		(1u << 2)
63462306a36Sopenharmony_ci#define	XFS_AGI_LENGTH		(1u << 3)
63562306a36Sopenharmony_ci#define	XFS_AGI_COUNT		(1u << 4)
63662306a36Sopenharmony_ci#define	XFS_AGI_ROOT		(1u << 5)
63762306a36Sopenharmony_ci#define	XFS_AGI_LEVEL		(1u << 6)
63862306a36Sopenharmony_ci#define	XFS_AGI_FREECOUNT	(1u << 7)
63962306a36Sopenharmony_ci#define	XFS_AGI_NEWINO		(1u << 8)
64062306a36Sopenharmony_ci#define	XFS_AGI_DIRINO		(1u << 9)
64162306a36Sopenharmony_ci#define	XFS_AGI_UNLINKED	(1u << 10)
64262306a36Sopenharmony_ci#define	XFS_AGI_NUM_BITS_R1	11	/* end of the 1st agi logging region */
64362306a36Sopenharmony_ci#define	XFS_AGI_ALL_BITS_R1	((1u << XFS_AGI_NUM_BITS_R1) - 1)
64462306a36Sopenharmony_ci#define	XFS_AGI_FREE_ROOT	(1u << 11)
64562306a36Sopenharmony_ci#define	XFS_AGI_FREE_LEVEL	(1u << 12)
64662306a36Sopenharmony_ci#define	XFS_AGI_IBLOCKS		(1u << 13) /* both inobt/finobt block counters */
64762306a36Sopenharmony_ci#define	XFS_AGI_NUM_BITS_R2	14
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci/* disk block (xfs_daddr_t) in the AG */
65062306a36Sopenharmony_ci#define XFS_AGI_DADDR(mp)	((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
65162306a36Sopenharmony_ci#define	XFS_AGI_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp))
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci/*
65462306a36Sopenharmony_ci * The third a.g. block contains the a.g. freelist, an array
65562306a36Sopenharmony_ci * of block pointers to blocks owned by the allocation btree code.
65662306a36Sopenharmony_ci */
65762306a36Sopenharmony_ci#define XFS_AGFL_DADDR(mp)	((xfs_daddr_t)(3 << (mp)->m_sectbb_log))
65862306a36Sopenharmony_ci#define	XFS_AGFL_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp))
65962306a36Sopenharmony_ci#define	XFS_BUF_TO_AGFL(bp)	((struct xfs_agfl *)((bp)->b_addr))
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_cistruct xfs_agfl {
66262306a36Sopenharmony_ci	__be32		agfl_magicnum;
66362306a36Sopenharmony_ci	__be32		agfl_seqno;
66462306a36Sopenharmony_ci	uuid_t		agfl_uuid;
66562306a36Sopenharmony_ci	__be64		agfl_lsn;
66662306a36Sopenharmony_ci	__be32		agfl_crc;
66762306a36Sopenharmony_ci} __attribute__((packed));
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci#define XFS_AGFL_CRC_OFF	offsetof(struct xfs_agfl, agfl_crc)
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci#define XFS_AGB_TO_FSB(mp,agno,agbno)	\
67262306a36Sopenharmony_ci	(((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno))
67362306a36Sopenharmony_ci#define	XFS_FSB_TO_AGNO(mp,fsbno)	\
67462306a36Sopenharmony_ci	((xfs_agnumber_t)((fsbno) >> (mp)->m_sb.sb_agblklog))
67562306a36Sopenharmony_ci#define	XFS_FSB_TO_AGBNO(mp,fsbno)	\
67662306a36Sopenharmony_ci	((xfs_agblock_t)((fsbno) & xfs_mask32lo((mp)->m_sb.sb_agblklog)))
67762306a36Sopenharmony_ci#define	XFS_AGB_TO_DADDR(mp,agno,agbno)	\
67862306a36Sopenharmony_ci	((xfs_daddr_t)XFS_FSB_TO_BB(mp, \
67962306a36Sopenharmony_ci		(xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno)))
68062306a36Sopenharmony_ci#define	XFS_AG_DADDR(mp,agno,d)		(XFS_AGB_TO_DADDR(mp, agno, 0) + (d))
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci/*
68362306a36Sopenharmony_ci * For checking for bad ranges of xfs_daddr_t's, covering multiple
68462306a36Sopenharmony_ci * allocation groups or a single xfs_daddr_t that's a superblock copy.
68562306a36Sopenharmony_ci */
68662306a36Sopenharmony_ci#define	XFS_AG_CHECK_DADDR(mp,d,len)	\
68762306a36Sopenharmony_ci	((len) == 1 ? \
68862306a36Sopenharmony_ci	    ASSERT((d) == XFS_SB_DADDR || \
68962306a36Sopenharmony_ci		   xfs_daddr_to_agbno(mp, d) != XFS_SB_DADDR) : \
69062306a36Sopenharmony_ci	    ASSERT(xfs_daddr_to_agno(mp, d) == \
69162306a36Sopenharmony_ci		   xfs_daddr_to_agno(mp, (d) + (len) - 1)))
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci/*
69462306a36Sopenharmony_ci * XFS Timestamps
69562306a36Sopenharmony_ci * ==============
69662306a36Sopenharmony_ci *
69762306a36Sopenharmony_ci * Traditional ondisk inode timestamps consist of signed 32-bit counters for
69862306a36Sopenharmony_ci * seconds and nanoseconds; time zero is the Unix epoch, Jan  1 00:00:00 UTC
69962306a36Sopenharmony_ci * 1970, which means that the timestamp epoch is the same as the Unix epoch.
70062306a36Sopenharmony_ci * Therefore, the ondisk min and max defined here can be used directly to
70162306a36Sopenharmony_ci * constrain the incore timestamps on a Unix system.  Note that we actually
70262306a36Sopenharmony_ci * encode a __be64 value on disk.
70362306a36Sopenharmony_ci *
70462306a36Sopenharmony_ci * When the bigtime feature is enabled, ondisk inode timestamps become an
70562306a36Sopenharmony_ci * unsigned 64-bit nanoseconds counter.  This means that the bigtime inode
70662306a36Sopenharmony_ci * timestamp epoch is the start of the classic timestamp range, which is
70762306a36Sopenharmony_ci * Dec 13 20:45:52 UTC 1901.  Because the epochs are not the same, callers
70862306a36Sopenharmony_ci * /must/ use the bigtime conversion functions when encoding and decoding raw
70962306a36Sopenharmony_ci * timestamps.
71062306a36Sopenharmony_ci */
71162306a36Sopenharmony_citypedef __be64 xfs_timestamp_t;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci/* Legacy timestamp encoding format. */
71462306a36Sopenharmony_cistruct xfs_legacy_timestamp {
71562306a36Sopenharmony_ci	__be32		t_sec;		/* timestamp seconds */
71662306a36Sopenharmony_ci	__be32		t_nsec;		/* timestamp nanoseconds */
71762306a36Sopenharmony_ci};
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci/*
72062306a36Sopenharmony_ci * Smallest possible ondisk seconds value with traditional timestamps.  This
72162306a36Sopenharmony_ci * corresponds exactly with the incore timestamp Dec 13 20:45:52 UTC 1901.
72262306a36Sopenharmony_ci */
72362306a36Sopenharmony_ci#define XFS_LEGACY_TIME_MIN	((int64_t)S32_MIN)
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci/*
72662306a36Sopenharmony_ci * Largest possible ondisk seconds value with traditional timestamps.  This
72762306a36Sopenharmony_ci * corresponds exactly with the incore timestamp Jan 19 03:14:07 UTC 2038.
72862306a36Sopenharmony_ci */
72962306a36Sopenharmony_ci#define XFS_LEGACY_TIME_MAX	((int64_t)S32_MAX)
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci/*
73262306a36Sopenharmony_ci * Smallest possible ondisk seconds value with bigtime timestamps.  This
73362306a36Sopenharmony_ci * corresponds (after conversion to a Unix timestamp) with the traditional
73462306a36Sopenharmony_ci * minimum timestamp of Dec 13 20:45:52 UTC 1901.
73562306a36Sopenharmony_ci */
73662306a36Sopenharmony_ci#define XFS_BIGTIME_TIME_MIN	((int64_t)0)
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci/*
73962306a36Sopenharmony_ci * Largest supported ondisk seconds value with bigtime timestamps.  This
74062306a36Sopenharmony_ci * corresponds (after conversion to a Unix timestamp) with an incore timestamp
74162306a36Sopenharmony_ci * of Jul  2 20:20:24 UTC 2486.
74262306a36Sopenharmony_ci *
74362306a36Sopenharmony_ci * We round down the ondisk limit so that the bigtime quota and inode max
74462306a36Sopenharmony_ci * timestamps will be the same.
74562306a36Sopenharmony_ci */
74662306a36Sopenharmony_ci#define XFS_BIGTIME_TIME_MAX	((int64_t)((-1ULL / NSEC_PER_SEC) & ~0x3ULL))
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci/*
74962306a36Sopenharmony_ci * Bigtime epoch is set exactly to the minimum time value that a traditional
75062306a36Sopenharmony_ci * 32-bit timestamp can represent when using the Unix epoch as a reference.
75162306a36Sopenharmony_ci * Hence the Unix epoch is at a fixed offset into the supported bigtime
75262306a36Sopenharmony_ci * timestamp range.
75362306a36Sopenharmony_ci *
75462306a36Sopenharmony_ci * The bigtime epoch also matches the minimum value an on-disk 32-bit XFS
75562306a36Sopenharmony_ci * timestamp can represent so we will not lose any fidelity in converting
75662306a36Sopenharmony_ci * to/from unix and bigtime timestamps.
75762306a36Sopenharmony_ci *
75862306a36Sopenharmony_ci * The following conversion factor converts a seconds counter from the Unix
75962306a36Sopenharmony_ci * epoch to the bigtime epoch.
76062306a36Sopenharmony_ci */
76162306a36Sopenharmony_ci#define XFS_BIGTIME_EPOCH_OFFSET	(-(int64_t)S32_MIN)
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ci/* Convert a timestamp from the Unix epoch to the bigtime epoch. */
76462306a36Sopenharmony_cistatic inline uint64_t xfs_unix_to_bigtime(time64_t unix_seconds)
76562306a36Sopenharmony_ci{
76662306a36Sopenharmony_ci	return (uint64_t)unix_seconds + XFS_BIGTIME_EPOCH_OFFSET;
76762306a36Sopenharmony_ci}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci/* Convert a timestamp from the bigtime epoch to the Unix epoch. */
77062306a36Sopenharmony_cistatic inline time64_t xfs_bigtime_to_unix(uint64_t ondisk_seconds)
77162306a36Sopenharmony_ci{
77262306a36Sopenharmony_ci	return (time64_t)ondisk_seconds - XFS_BIGTIME_EPOCH_OFFSET;
77362306a36Sopenharmony_ci}
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci/*
77662306a36Sopenharmony_ci * On-disk inode structure.
77762306a36Sopenharmony_ci *
77862306a36Sopenharmony_ci * This is just the header or "dinode core", the inode is expanded to fill a
77962306a36Sopenharmony_ci * variable size the leftover area split into a data and an attribute fork.
78062306a36Sopenharmony_ci * The format of the data and attribute fork depends on the format of the
78162306a36Sopenharmony_ci * inode as indicated by di_format and di_aformat.  To access the data and
78262306a36Sopenharmony_ci * attribute use the XFS_DFORK_DPTR, XFS_DFORK_APTR, and XFS_DFORK_PTR macros
78362306a36Sopenharmony_ci * below.
78462306a36Sopenharmony_ci *
78562306a36Sopenharmony_ci * There is a very similar struct xfs_log_dinode which matches the layout of
78662306a36Sopenharmony_ci * this structure, but is kept in native format instead of big endian.
78762306a36Sopenharmony_ci *
78862306a36Sopenharmony_ci * Note: di_flushiter is only used by v1/2 inodes - it's effectively a zeroed
78962306a36Sopenharmony_ci * padding field for v3 inodes.
79062306a36Sopenharmony_ci */
79162306a36Sopenharmony_ci#define	XFS_DINODE_MAGIC		0x494e	/* 'IN' */
79262306a36Sopenharmony_cistruct xfs_dinode {
79362306a36Sopenharmony_ci	__be16		di_magic;	/* inode magic # = XFS_DINODE_MAGIC */
79462306a36Sopenharmony_ci	__be16		di_mode;	/* mode and type of file */
79562306a36Sopenharmony_ci	__u8		di_version;	/* inode version */
79662306a36Sopenharmony_ci	__u8		di_format;	/* format of di_c data */
79762306a36Sopenharmony_ci	__be16		di_onlink;	/* old number of links to file */
79862306a36Sopenharmony_ci	__be32		di_uid;		/* owner's user id */
79962306a36Sopenharmony_ci	__be32		di_gid;		/* owner's group id */
80062306a36Sopenharmony_ci	__be32		di_nlink;	/* number of links to file */
80162306a36Sopenharmony_ci	__be16		di_projid_lo;	/* lower part of owner's project id */
80262306a36Sopenharmony_ci	__be16		di_projid_hi;	/* higher part owner's project id */
80362306a36Sopenharmony_ci	union {
80462306a36Sopenharmony_ci		/* Number of data fork extents if NREXT64 is set */
80562306a36Sopenharmony_ci		__be64	di_big_nextents;
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci		/* Padding for V3 inodes without NREXT64 set. */
80862306a36Sopenharmony_ci		__be64	di_v3_pad;
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci		/* Padding and inode flush counter for V2 inodes. */
81162306a36Sopenharmony_ci		struct {
81262306a36Sopenharmony_ci			__u8	di_v2_pad[6];
81362306a36Sopenharmony_ci			__be16	di_flushiter;
81462306a36Sopenharmony_ci		};
81562306a36Sopenharmony_ci	};
81662306a36Sopenharmony_ci	xfs_timestamp_t	di_atime;	/* time last accessed */
81762306a36Sopenharmony_ci	xfs_timestamp_t	di_mtime;	/* time last modified */
81862306a36Sopenharmony_ci	xfs_timestamp_t	di_ctime;	/* time created/inode modified */
81962306a36Sopenharmony_ci	__be64		di_size;	/* number of bytes in file */
82062306a36Sopenharmony_ci	__be64		di_nblocks;	/* # of direct & btree blocks used */
82162306a36Sopenharmony_ci	__be32		di_extsize;	/* basic/minimum extent size for file */
82262306a36Sopenharmony_ci	union {
82362306a36Sopenharmony_ci		/*
82462306a36Sopenharmony_ci		 * For V2 inodes and V3 inodes without NREXT64 set, this
82562306a36Sopenharmony_ci		 * is the number of data and attr fork extents.
82662306a36Sopenharmony_ci		 */
82762306a36Sopenharmony_ci		struct {
82862306a36Sopenharmony_ci			__be32	di_nextents;
82962306a36Sopenharmony_ci			__be16	di_anextents;
83062306a36Sopenharmony_ci		} __packed;
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci		/* Number of attr fork extents if NREXT64 is set. */
83362306a36Sopenharmony_ci		struct {
83462306a36Sopenharmony_ci			__be32	di_big_anextents;
83562306a36Sopenharmony_ci			__be16	di_nrext64_pad;
83662306a36Sopenharmony_ci		} __packed;
83762306a36Sopenharmony_ci	} __packed;
83862306a36Sopenharmony_ci	__u8		di_forkoff;	/* attr fork offs, <<3 for 64b align */
83962306a36Sopenharmony_ci	__s8		di_aformat;	/* format of attr fork's data */
84062306a36Sopenharmony_ci	__be32		di_dmevmask;	/* DMIG event mask */
84162306a36Sopenharmony_ci	__be16		di_dmstate;	/* DMIG state info */
84262306a36Sopenharmony_ci	__be16		di_flags;	/* random flags, XFS_DIFLAG_... */
84362306a36Sopenharmony_ci	__be32		di_gen;		/* generation number */
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ci	/* di_next_unlinked is the only non-core field in the old dinode */
84662306a36Sopenharmony_ci	__be32		di_next_unlinked;/* agi unlinked list ptr */
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci	/* start of the extended dinode, writable fields */
84962306a36Sopenharmony_ci	__le32		di_crc;		/* CRC of the inode */
85062306a36Sopenharmony_ci	__be64		di_changecount;	/* number of attribute changes */
85162306a36Sopenharmony_ci	__be64		di_lsn;		/* flush sequence */
85262306a36Sopenharmony_ci	__be64		di_flags2;	/* more random flags */
85362306a36Sopenharmony_ci	__be32		di_cowextsize;	/* basic cow extent size for file */
85462306a36Sopenharmony_ci	__u8		di_pad2[12];	/* more padding for future expansion */
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	/* fields only written to during inode creation */
85762306a36Sopenharmony_ci	xfs_timestamp_t	di_crtime;	/* time created */
85862306a36Sopenharmony_ci	__be64		di_ino;		/* inode number */
85962306a36Sopenharmony_ci	uuid_t		di_uuid;	/* UUID of the filesystem */
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	/* structure must be padded to 64 bit alignment */
86262306a36Sopenharmony_ci};
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ci#define XFS_DINODE_CRC_OFF	offsetof(struct xfs_dinode, di_crc)
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci#define DI_MAX_FLUSH 0xffff
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci/*
86962306a36Sopenharmony_ci * Size of the core inode on disk.  Version 1 and 2 inodes have
87062306a36Sopenharmony_ci * the same size, but version 3 has grown a few additional fields.
87162306a36Sopenharmony_ci */
87262306a36Sopenharmony_cistatic inline uint xfs_dinode_size(int version)
87362306a36Sopenharmony_ci{
87462306a36Sopenharmony_ci	if (version == 3)
87562306a36Sopenharmony_ci		return sizeof(struct xfs_dinode);
87662306a36Sopenharmony_ci	return offsetof(struct xfs_dinode, di_crc);
87762306a36Sopenharmony_ci}
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci/*
88062306a36Sopenharmony_ci * The 32 bit link count in the inode theoretically maxes out at UINT_MAX.
88162306a36Sopenharmony_ci * Since the pathconf interface is signed, we use 2^31 - 1 instead.
88262306a36Sopenharmony_ci */
88362306a36Sopenharmony_ci#define	XFS_MAXLINK		((1U << 31) - 1U)
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_ci/*
88662306a36Sopenharmony_ci * Values for di_format
88762306a36Sopenharmony_ci *
88862306a36Sopenharmony_ci * This enum is used in string mapping in xfs_trace.h; please keep the
88962306a36Sopenharmony_ci * TRACE_DEFINE_ENUMs for it up to date.
89062306a36Sopenharmony_ci */
89162306a36Sopenharmony_cienum xfs_dinode_fmt {
89262306a36Sopenharmony_ci	XFS_DINODE_FMT_DEV,		/* xfs_dev_t */
89362306a36Sopenharmony_ci	XFS_DINODE_FMT_LOCAL,		/* bulk data */
89462306a36Sopenharmony_ci	XFS_DINODE_FMT_EXTENTS,		/* struct xfs_bmbt_rec */
89562306a36Sopenharmony_ci	XFS_DINODE_FMT_BTREE,		/* struct xfs_bmdr_block */
89662306a36Sopenharmony_ci	XFS_DINODE_FMT_UUID		/* added long ago, but never used */
89762306a36Sopenharmony_ci};
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci#define XFS_INODE_FORMAT_STR \
90062306a36Sopenharmony_ci	{ XFS_DINODE_FMT_DEV,		"dev" }, \
90162306a36Sopenharmony_ci	{ XFS_DINODE_FMT_LOCAL,		"local" }, \
90262306a36Sopenharmony_ci	{ XFS_DINODE_FMT_EXTENTS,	"extent" }, \
90362306a36Sopenharmony_ci	{ XFS_DINODE_FMT_BTREE,		"btree" }, \
90462306a36Sopenharmony_ci	{ XFS_DINODE_FMT_UUID,		"uuid" }
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci/*
90762306a36Sopenharmony_ci * Max values for extnum and aextnum.
90862306a36Sopenharmony_ci *
90962306a36Sopenharmony_ci * The original on-disk extent counts were held in signed fields, resulting in
91062306a36Sopenharmony_ci * maximum extent counts of 2^31 and 2^15 for the data and attr forks
91162306a36Sopenharmony_ci * respectively. Similarly the maximum extent length is limited to 2^21 blocks
91262306a36Sopenharmony_ci * by the 21-bit wide blockcount field of a BMBT extent record.
91362306a36Sopenharmony_ci *
91462306a36Sopenharmony_ci * The newly introduced data fork extent counter can hold a 64-bit value,
91562306a36Sopenharmony_ci * however the maximum number of extents in a file is also limited to 2^54
91662306a36Sopenharmony_ci * extents by the 54-bit wide startoff field of a BMBT extent record.
91762306a36Sopenharmony_ci *
91862306a36Sopenharmony_ci * It is further limited by the maximum supported file size of 2^63
91962306a36Sopenharmony_ci * *bytes*. This leads to a maximum extent count for maximally sized filesystem
92062306a36Sopenharmony_ci * blocks (64kB) of:
92162306a36Sopenharmony_ci *
92262306a36Sopenharmony_ci * 2^63 bytes / 2^16 bytes per block = 2^47 blocks
92362306a36Sopenharmony_ci *
92462306a36Sopenharmony_ci * Rounding up 47 to the nearest multiple of bits-per-byte results in 48. Hence
92562306a36Sopenharmony_ci * 2^48 was chosen as the maximum data fork extent count.
92662306a36Sopenharmony_ci *
92762306a36Sopenharmony_ci * The maximum file size that can be represented by the data fork extent counter
92862306a36Sopenharmony_ci * in the worst case occurs when all extents are 1 block in length and each
92962306a36Sopenharmony_ci * block is 1KB in size.
93062306a36Sopenharmony_ci *
93162306a36Sopenharmony_ci * With XFS_MAX_EXTCNT_DATA_FORK_SMALL representing maximum extent count and
93262306a36Sopenharmony_ci * with 1KB sized blocks, a file can reach upto,
93362306a36Sopenharmony_ci * 1KB * (2^31) = 2TB
93462306a36Sopenharmony_ci *
93562306a36Sopenharmony_ci * This is much larger than the theoretical maximum size of a directory
93662306a36Sopenharmony_ci * i.e. XFS_DIR2_SPACE_SIZE * XFS_DIR2_MAX_SPACES = ~96GB.
93762306a36Sopenharmony_ci *
93862306a36Sopenharmony_ci * Hence, a directory inode can never overflow its data fork extent counter.
93962306a36Sopenharmony_ci */
94062306a36Sopenharmony_ci#define XFS_MAX_EXTCNT_DATA_FORK_LARGE	((xfs_extnum_t)((1ULL << 48) - 1))
94162306a36Sopenharmony_ci#define XFS_MAX_EXTCNT_ATTR_FORK_LARGE	((xfs_extnum_t)((1ULL << 32) - 1))
94262306a36Sopenharmony_ci#define XFS_MAX_EXTCNT_DATA_FORK_SMALL	((xfs_extnum_t)((1ULL << 31) - 1))
94362306a36Sopenharmony_ci#define XFS_MAX_EXTCNT_ATTR_FORK_SMALL	((xfs_extnum_t)((1ULL << 15) - 1))
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci/*
94662306a36Sopenharmony_ci * When we upgrade an inode to the large extent counts, the maximum value by
94762306a36Sopenharmony_ci * which the extent count can increase is bound by the change in size of the
94862306a36Sopenharmony_ci * on-disk field. No upgrade operation should ever be adding more than a few
94962306a36Sopenharmony_ci * tens of extents, so if we get a really large value it is a sign of a code bug
95062306a36Sopenharmony_ci * or corruption.
95162306a36Sopenharmony_ci */
95262306a36Sopenharmony_ci#define XFS_MAX_EXTCNT_UPGRADE_NR	\
95362306a36Sopenharmony_ci	min(XFS_MAX_EXTCNT_ATTR_FORK_LARGE - XFS_MAX_EXTCNT_ATTR_FORK_SMALL,	\
95462306a36Sopenharmony_ci	    XFS_MAX_EXTCNT_DATA_FORK_LARGE - XFS_MAX_EXTCNT_DATA_FORK_SMALL)
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci/*
95762306a36Sopenharmony_ci * Inode minimum and maximum sizes.
95862306a36Sopenharmony_ci */
95962306a36Sopenharmony_ci#define	XFS_DINODE_MIN_LOG	8
96062306a36Sopenharmony_ci#define	XFS_DINODE_MAX_LOG	11
96162306a36Sopenharmony_ci#define	XFS_DINODE_MIN_SIZE	(1 << XFS_DINODE_MIN_LOG)
96262306a36Sopenharmony_ci#define	XFS_DINODE_MAX_SIZE	(1 << XFS_DINODE_MAX_LOG)
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci/*
96562306a36Sopenharmony_ci * Inode size for given fs.
96662306a36Sopenharmony_ci */
96762306a36Sopenharmony_ci#define XFS_DINODE_SIZE(mp) \
96862306a36Sopenharmony_ci	(xfs_has_v3inodes(mp) ? \
96962306a36Sopenharmony_ci		sizeof(struct xfs_dinode) : \
97062306a36Sopenharmony_ci		offsetof(struct xfs_dinode, di_crc))
97162306a36Sopenharmony_ci#define XFS_LITINO(mp) \
97262306a36Sopenharmony_ci	((mp)->m_sb.sb_inodesize - XFS_DINODE_SIZE(mp))
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci/*
97562306a36Sopenharmony_ci * Inode data & attribute fork sizes, per inode.
97662306a36Sopenharmony_ci */
97762306a36Sopenharmony_ci#define XFS_DFORK_BOFF(dip)		((int)((dip)->di_forkoff << 3))
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci#define XFS_DFORK_DSIZE(dip,mp) \
98062306a36Sopenharmony_ci	((dip)->di_forkoff ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp))
98162306a36Sopenharmony_ci#define XFS_DFORK_ASIZE(dip,mp) \
98262306a36Sopenharmony_ci	((dip)->di_forkoff ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0)
98362306a36Sopenharmony_ci#define XFS_DFORK_SIZE(dip,mp,w) \
98462306a36Sopenharmony_ci	((w) == XFS_DATA_FORK ? \
98562306a36Sopenharmony_ci		XFS_DFORK_DSIZE(dip, mp) : \
98662306a36Sopenharmony_ci		XFS_DFORK_ASIZE(dip, mp))
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci#define XFS_DFORK_MAXEXT(dip, mp, w) \
98962306a36Sopenharmony_ci	(XFS_DFORK_SIZE(dip, mp, w) / sizeof(struct xfs_bmbt_rec))
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci/*
99262306a36Sopenharmony_ci * Return pointers to the data or attribute forks.
99362306a36Sopenharmony_ci */
99462306a36Sopenharmony_ci#define XFS_DFORK_DPTR(dip) \
99562306a36Sopenharmony_ci	((char *)dip + xfs_dinode_size(dip->di_version))
99662306a36Sopenharmony_ci#define XFS_DFORK_APTR(dip)	\
99762306a36Sopenharmony_ci	(XFS_DFORK_DPTR(dip) + XFS_DFORK_BOFF(dip))
99862306a36Sopenharmony_ci#define XFS_DFORK_PTR(dip,w)	\
99962306a36Sopenharmony_ci	((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip))
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci#define XFS_DFORK_FORMAT(dip,w) \
100262306a36Sopenharmony_ci	((w) == XFS_DATA_FORK ? \
100362306a36Sopenharmony_ci		(dip)->di_format : \
100462306a36Sopenharmony_ci		(dip)->di_aformat)
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci/*
100762306a36Sopenharmony_ci * For block and character special files the 32bit dev_t is stored at the
100862306a36Sopenharmony_ci * beginning of the data fork.
100962306a36Sopenharmony_ci */
101062306a36Sopenharmony_cistatic inline xfs_dev_t xfs_dinode_get_rdev(struct xfs_dinode *dip)
101162306a36Sopenharmony_ci{
101262306a36Sopenharmony_ci	return be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(dip));
101362306a36Sopenharmony_ci}
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_cistatic inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
101662306a36Sopenharmony_ci{
101762306a36Sopenharmony_ci	*(__be32 *)XFS_DFORK_DPTR(dip) = cpu_to_be32(rdev);
101862306a36Sopenharmony_ci}
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci/*
102162306a36Sopenharmony_ci * Values for di_flags
102262306a36Sopenharmony_ci */
102362306a36Sopenharmony_ci#define XFS_DIFLAG_REALTIME_BIT  0	/* file's blocks come from rt area */
102462306a36Sopenharmony_ci#define XFS_DIFLAG_PREALLOC_BIT  1	/* file space has been preallocated */
102562306a36Sopenharmony_ci#define XFS_DIFLAG_NEWRTBM_BIT   2	/* for rtbitmap inode, new format */
102662306a36Sopenharmony_ci#define XFS_DIFLAG_IMMUTABLE_BIT 3	/* inode is immutable */
102762306a36Sopenharmony_ci#define XFS_DIFLAG_APPEND_BIT    4	/* inode is append-only */
102862306a36Sopenharmony_ci#define XFS_DIFLAG_SYNC_BIT      5	/* inode is written synchronously */
102962306a36Sopenharmony_ci#define XFS_DIFLAG_NOATIME_BIT   6	/* do not update atime */
103062306a36Sopenharmony_ci#define XFS_DIFLAG_NODUMP_BIT    7	/* do not dump */
103162306a36Sopenharmony_ci#define XFS_DIFLAG_RTINHERIT_BIT 8	/* create with realtime bit set */
103262306a36Sopenharmony_ci#define XFS_DIFLAG_PROJINHERIT_BIT   9	/* create with parents projid */
103362306a36Sopenharmony_ci#define XFS_DIFLAG_NOSYMLINKS_BIT   10	/* disallow symlink creation */
103462306a36Sopenharmony_ci#define XFS_DIFLAG_EXTSIZE_BIT      11	/* inode extent size allocator hint */
103562306a36Sopenharmony_ci#define XFS_DIFLAG_EXTSZINHERIT_BIT 12	/* inherit inode extent size */
103662306a36Sopenharmony_ci#define XFS_DIFLAG_NODEFRAG_BIT     13	/* do not reorganize/defragment */
103762306a36Sopenharmony_ci#define XFS_DIFLAG_FILESTREAM_BIT   14  /* use filestream allocator */
103862306a36Sopenharmony_ci/* Do not use bit 15, di_flags is legacy and unchanging now */
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci#define XFS_DIFLAG_REALTIME      (1 << XFS_DIFLAG_REALTIME_BIT)
104162306a36Sopenharmony_ci#define XFS_DIFLAG_PREALLOC      (1 << XFS_DIFLAG_PREALLOC_BIT)
104262306a36Sopenharmony_ci#define XFS_DIFLAG_NEWRTBM       (1 << XFS_DIFLAG_NEWRTBM_BIT)
104362306a36Sopenharmony_ci#define XFS_DIFLAG_IMMUTABLE     (1 << XFS_DIFLAG_IMMUTABLE_BIT)
104462306a36Sopenharmony_ci#define XFS_DIFLAG_APPEND        (1 << XFS_DIFLAG_APPEND_BIT)
104562306a36Sopenharmony_ci#define XFS_DIFLAG_SYNC          (1 << XFS_DIFLAG_SYNC_BIT)
104662306a36Sopenharmony_ci#define XFS_DIFLAG_NOATIME       (1 << XFS_DIFLAG_NOATIME_BIT)
104762306a36Sopenharmony_ci#define XFS_DIFLAG_NODUMP        (1 << XFS_DIFLAG_NODUMP_BIT)
104862306a36Sopenharmony_ci#define XFS_DIFLAG_RTINHERIT     (1 << XFS_DIFLAG_RTINHERIT_BIT)
104962306a36Sopenharmony_ci#define XFS_DIFLAG_PROJINHERIT   (1 << XFS_DIFLAG_PROJINHERIT_BIT)
105062306a36Sopenharmony_ci#define XFS_DIFLAG_NOSYMLINKS    (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
105162306a36Sopenharmony_ci#define XFS_DIFLAG_EXTSIZE       (1 << XFS_DIFLAG_EXTSIZE_BIT)
105262306a36Sopenharmony_ci#define XFS_DIFLAG_EXTSZINHERIT  (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
105362306a36Sopenharmony_ci#define XFS_DIFLAG_NODEFRAG      (1 << XFS_DIFLAG_NODEFRAG_BIT)
105462306a36Sopenharmony_ci#define XFS_DIFLAG_FILESTREAM    (1 << XFS_DIFLAG_FILESTREAM_BIT)
105562306a36Sopenharmony_ci
105662306a36Sopenharmony_ci#define XFS_DIFLAG_ANY \
105762306a36Sopenharmony_ci	(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
105862306a36Sopenharmony_ci	 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
105962306a36Sopenharmony_ci	 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
106062306a36Sopenharmony_ci	 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
106162306a36Sopenharmony_ci	 XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM)
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci/*
106462306a36Sopenharmony_ci * Values for di_flags2 These start by being exposed to userspace in the upper
106562306a36Sopenharmony_ci * 16 bits of the XFS_XFLAG_s range.
106662306a36Sopenharmony_ci */
106762306a36Sopenharmony_ci#define XFS_DIFLAG2_DAX_BIT	0	/* use DAX for this inode */
106862306a36Sopenharmony_ci#define XFS_DIFLAG2_REFLINK_BIT	1	/* file's blocks may be shared */
106962306a36Sopenharmony_ci#define XFS_DIFLAG2_COWEXTSIZE_BIT   2  /* copy on write extent size hint */
107062306a36Sopenharmony_ci#define XFS_DIFLAG2_BIGTIME_BIT	3	/* big timestamps */
107162306a36Sopenharmony_ci#define XFS_DIFLAG2_NREXT64_BIT 4	/* large extent counters */
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_ci#define XFS_DIFLAG2_DAX		(1 << XFS_DIFLAG2_DAX_BIT)
107462306a36Sopenharmony_ci#define XFS_DIFLAG2_REFLINK     (1 << XFS_DIFLAG2_REFLINK_BIT)
107562306a36Sopenharmony_ci#define XFS_DIFLAG2_COWEXTSIZE  (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
107662306a36Sopenharmony_ci#define XFS_DIFLAG2_BIGTIME	(1 << XFS_DIFLAG2_BIGTIME_BIT)
107762306a36Sopenharmony_ci#define XFS_DIFLAG2_NREXT64	(1 << XFS_DIFLAG2_NREXT64_BIT)
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_ci#define XFS_DIFLAG2_ANY \
108062306a36Sopenharmony_ci	(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
108162306a36Sopenharmony_ci	 XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_NREXT64)
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_cistatic inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
108462306a36Sopenharmony_ci{
108562306a36Sopenharmony_ci	return dip->di_version >= 3 &&
108662306a36Sopenharmony_ci	       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_BIGTIME));
108762306a36Sopenharmony_ci}
108862306a36Sopenharmony_ci
108962306a36Sopenharmony_cistatic inline bool xfs_dinode_has_large_extent_counts(
109062306a36Sopenharmony_ci	const struct xfs_dinode *dip)
109162306a36Sopenharmony_ci{
109262306a36Sopenharmony_ci	return dip->di_version >= 3 &&
109362306a36Sopenharmony_ci	       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_NREXT64));
109462306a36Sopenharmony_ci}
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci/*
109762306a36Sopenharmony_ci * Inode number format:
109862306a36Sopenharmony_ci * low inopblog bits - offset in block
109962306a36Sopenharmony_ci * next agblklog bits - block number in ag
110062306a36Sopenharmony_ci * next agno_log bits - ag number
110162306a36Sopenharmony_ci * high agno_log-agblklog-inopblog bits - 0
110262306a36Sopenharmony_ci */
110362306a36Sopenharmony_ci#define	XFS_INO_MASK(k)			(uint32_t)((1ULL << (k)) - 1)
110462306a36Sopenharmony_ci#define	XFS_INO_OFFSET_BITS(mp)		(mp)->m_sb.sb_inopblog
110562306a36Sopenharmony_ci#define	XFS_INO_AGBNO_BITS(mp)		(mp)->m_sb.sb_agblklog
110662306a36Sopenharmony_ci#define	XFS_INO_AGINO_BITS(mp)		((mp)->m_ino_geo.agino_log)
110762306a36Sopenharmony_ci#define	XFS_INO_AGNO_BITS(mp)		(mp)->m_agno_log
110862306a36Sopenharmony_ci#define	XFS_INO_BITS(mp)		\
110962306a36Sopenharmony_ci	XFS_INO_AGNO_BITS(mp) + XFS_INO_AGINO_BITS(mp)
111062306a36Sopenharmony_ci#define	XFS_INO_TO_AGNO(mp,i)		\
111162306a36Sopenharmony_ci	((xfs_agnumber_t)((i) >> XFS_INO_AGINO_BITS(mp)))
111262306a36Sopenharmony_ci#define	XFS_INO_TO_AGINO(mp,i)		\
111362306a36Sopenharmony_ci	((xfs_agino_t)(i) & XFS_INO_MASK(XFS_INO_AGINO_BITS(mp)))
111462306a36Sopenharmony_ci#define	XFS_INO_TO_AGBNO(mp,i)		\
111562306a36Sopenharmony_ci	(((xfs_agblock_t)(i) >> XFS_INO_OFFSET_BITS(mp)) & \
111662306a36Sopenharmony_ci		XFS_INO_MASK(XFS_INO_AGBNO_BITS(mp)))
111762306a36Sopenharmony_ci#define	XFS_INO_TO_OFFSET(mp,i)		\
111862306a36Sopenharmony_ci	((int)(i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp)))
111962306a36Sopenharmony_ci#define	XFS_INO_TO_FSB(mp,i)		\
112062306a36Sopenharmony_ci	XFS_AGB_TO_FSB(mp, XFS_INO_TO_AGNO(mp,i), XFS_INO_TO_AGBNO(mp,i))
112162306a36Sopenharmony_ci#define	XFS_AGINO_TO_INO(mp,a,i)	\
112262306a36Sopenharmony_ci	(((xfs_ino_t)(a) << XFS_INO_AGINO_BITS(mp)) | (i))
112362306a36Sopenharmony_ci#define	XFS_AGINO_TO_AGBNO(mp,i)	((i) >> XFS_INO_OFFSET_BITS(mp))
112462306a36Sopenharmony_ci#define	XFS_AGINO_TO_OFFSET(mp,i)	\
112562306a36Sopenharmony_ci	((i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp)))
112662306a36Sopenharmony_ci#define	XFS_OFFBNO_TO_AGINO(mp,b,o)	\
112762306a36Sopenharmony_ci	((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o)))
112862306a36Sopenharmony_ci#define	XFS_FSB_TO_INO(mp, b)	((xfs_ino_t)((b) << XFS_INO_OFFSET_BITS(mp)))
112962306a36Sopenharmony_ci#define	XFS_AGB_TO_AGINO(mp, b)	((xfs_agino_t)((b) << XFS_INO_OFFSET_BITS(mp)))
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci#define	XFS_MAXINUMBER		((xfs_ino_t)((1ULL << 56) - 1ULL))
113262306a36Sopenharmony_ci#define	XFS_MAXINUMBER_32	((xfs_ino_t)((1ULL << 32) - 1ULL))
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci/*
113562306a36Sopenharmony_ci * RealTime Device format definitions
113662306a36Sopenharmony_ci */
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci/* Min and max rt extent sizes, specified in bytes */
113962306a36Sopenharmony_ci#define	XFS_MAX_RTEXTSIZE	(1024 * 1024 * 1024)	/* 1GB */
114062306a36Sopenharmony_ci#define	XFS_DFL_RTEXTSIZE	(64 * 1024)	        /* 64kB */
114162306a36Sopenharmony_ci#define	XFS_MIN_RTEXTSIZE	(4 * 1024)		/* 4kB */
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci#define	XFS_BLOCKSIZE(mp)	((mp)->m_sb.sb_blocksize)
114462306a36Sopenharmony_ci#define	XFS_BLOCKMASK(mp)	((mp)->m_blockmask)
114562306a36Sopenharmony_ci#define	XFS_BLOCKWSIZE(mp)	((mp)->m_blockwsize)
114662306a36Sopenharmony_ci#define	XFS_BLOCKWMASK(mp)	((mp)->m_blockwmask)
114762306a36Sopenharmony_ci
114862306a36Sopenharmony_ci/*
114962306a36Sopenharmony_ci * RT Summary and bit manipulation macros.
115062306a36Sopenharmony_ci */
115162306a36Sopenharmony_ci#define	XFS_SUMOFFS(mp,ls,bb)	((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb)))
115262306a36Sopenharmony_ci#define	XFS_SUMOFFSTOBLOCK(mp,s)	\
115362306a36Sopenharmony_ci	(((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog)
115462306a36Sopenharmony_ci#define	XFS_SUMPTR(mp,bp,so)	\
115562306a36Sopenharmony_ci	((xfs_suminfo_t *)((bp)->b_addr + \
115662306a36Sopenharmony_ci		(((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp))))
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci#define	XFS_BITTOBLOCK(mp,bi)	((bi) >> (mp)->m_blkbit_log)
115962306a36Sopenharmony_ci#define	XFS_BLOCKTOBIT(mp,bb)	((bb) << (mp)->m_blkbit_log)
116062306a36Sopenharmony_ci#define	XFS_BITTOWORD(mp,bi)	\
116162306a36Sopenharmony_ci	((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp)))
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci#define	XFS_RTMIN(a,b)	((a) < (b) ? (a) : (b))
116462306a36Sopenharmony_ci#define	XFS_RTMAX(a,b)	((a) > (b) ? (a) : (b))
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_ci#define	XFS_RTLOBIT(w)	xfs_lowbit32(w)
116762306a36Sopenharmony_ci#define	XFS_RTHIBIT(w)	xfs_highbit32(w)
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci#define	XFS_RTBLOCKLOG(b)	xfs_highbit64(b)
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci/*
117262306a36Sopenharmony_ci * Dquot and dquot block format definitions
117362306a36Sopenharmony_ci */
117462306a36Sopenharmony_ci#define XFS_DQUOT_MAGIC		0x4451		/* 'DQ' */
117562306a36Sopenharmony_ci#define XFS_DQUOT_VERSION	(uint8_t)0x01	/* latest version number */
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ci#define XFS_DQTYPE_USER		(1u << 0)	/* user dquot record */
117862306a36Sopenharmony_ci#define XFS_DQTYPE_PROJ		(1u << 1)	/* project dquot record */
117962306a36Sopenharmony_ci#define XFS_DQTYPE_GROUP	(1u << 2)	/* group dquot record */
118062306a36Sopenharmony_ci#define XFS_DQTYPE_BIGTIME	(1u << 7)	/* large expiry timestamps */
118162306a36Sopenharmony_ci
118262306a36Sopenharmony_ci/* bitmask to determine if this is a user/group/project dquot */
118362306a36Sopenharmony_ci#define XFS_DQTYPE_REC_MASK	(XFS_DQTYPE_USER | \
118462306a36Sopenharmony_ci				 XFS_DQTYPE_PROJ | \
118562306a36Sopenharmony_ci				 XFS_DQTYPE_GROUP)
118662306a36Sopenharmony_ci
118762306a36Sopenharmony_ci#define XFS_DQTYPE_ANY		(XFS_DQTYPE_REC_MASK | \
118862306a36Sopenharmony_ci				 XFS_DQTYPE_BIGTIME)
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci/*
119162306a36Sopenharmony_ci * XFS Quota Timers
119262306a36Sopenharmony_ci * ================
119362306a36Sopenharmony_ci *
119462306a36Sopenharmony_ci * Traditional quota grace period expiration timers are an unsigned 32-bit
119562306a36Sopenharmony_ci * seconds counter; time zero is the Unix epoch, Jan  1 00:00:01 UTC 1970.
119662306a36Sopenharmony_ci * Note that an expiration value of zero means that the quota limit has not
119762306a36Sopenharmony_ci * been reached, and therefore no expiration has been set.  Therefore, the
119862306a36Sopenharmony_ci * ondisk min and max defined here can be used directly to constrain the incore
119962306a36Sopenharmony_ci * quota expiration timestamps on a Unix system.
120062306a36Sopenharmony_ci *
120162306a36Sopenharmony_ci * When bigtime is enabled, we trade two bits of precision to expand the
120262306a36Sopenharmony_ci * expiration timeout range to match that of big inode timestamps.  The min and
120362306a36Sopenharmony_ci * max recorded here are the on-disk limits, not a Unix timestamp.
120462306a36Sopenharmony_ci *
120562306a36Sopenharmony_ci * The grace period for each quota type is stored in the root dquot (id = 0)
120662306a36Sopenharmony_ci * and is applied to a non-root dquot when it exceeds the soft or hard limits.
120762306a36Sopenharmony_ci * The length of quota grace periods are unsigned 32-bit quantities measured in
120862306a36Sopenharmony_ci * units of seconds.  A value of zero means to use the default period.
120962306a36Sopenharmony_ci */
121062306a36Sopenharmony_ci
121162306a36Sopenharmony_ci/*
121262306a36Sopenharmony_ci * Smallest possible ondisk quota expiration value with traditional timestamps.
121362306a36Sopenharmony_ci * This corresponds exactly with the incore expiration Jan  1 00:00:01 UTC 1970.
121462306a36Sopenharmony_ci */
121562306a36Sopenharmony_ci#define XFS_DQ_LEGACY_EXPIRY_MIN	((int64_t)1)
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_ci/*
121862306a36Sopenharmony_ci * Largest possible ondisk quota expiration value with traditional timestamps.
121962306a36Sopenharmony_ci * This corresponds exactly with the incore expiration Feb  7 06:28:15 UTC 2106.
122062306a36Sopenharmony_ci */
122162306a36Sopenharmony_ci#define XFS_DQ_LEGACY_EXPIRY_MAX	((int64_t)U32_MAX)
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci/*
122462306a36Sopenharmony_ci * Smallest possible ondisk quota expiration value with bigtime timestamps.
122562306a36Sopenharmony_ci * This corresponds (after conversion to a Unix timestamp) with the incore
122662306a36Sopenharmony_ci * expiration of Jan  1 00:00:04 UTC 1970.
122762306a36Sopenharmony_ci */
122862306a36Sopenharmony_ci#define XFS_DQ_BIGTIME_EXPIRY_MIN	(XFS_DQ_LEGACY_EXPIRY_MIN)
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_ci/*
123162306a36Sopenharmony_ci * Largest supported ondisk quota expiration value with bigtime timestamps.
123262306a36Sopenharmony_ci * This corresponds (after conversion to a Unix timestamp) with an incore
123362306a36Sopenharmony_ci * expiration of Jul  2 20:20:24 UTC 2486.
123462306a36Sopenharmony_ci *
123562306a36Sopenharmony_ci * The ondisk field supports values up to -1U, which corresponds to an incore
123662306a36Sopenharmony_ci * expiration in 2514.  This is beyond the maximum the bigtime inode timestamp,
123762306a36Sopenharmony_ci * so we cap the maximum bigtime quota expiration to the max inode timestamp.
123862306a36Sopenharmony_ci */
123962306a36Sopenharmony_ci#define XFS_DQ_BIGTIME_EXPIRY_MAX	((int64_t)4074815106U)
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci/*
124262306a36Sopenharmony_ci * The following conversion factors assist in converting a quota expiration
124362306a36Sopenharmony_ci * timestamp between the incore and ondisk formats.
124462306a36Sopenharmony_ci */
124562306a36Sopenharmony_ci#define XFS_DQ_BIGTIME_SHIFT	(2)
124662306a36Sopenharmony_ci#define XFS_DQ_BIGTIME_SLACK	((int64_t)(1ULL << XFS_DQ_BIGTIME_SHIFT) - 1)
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci/* Convert an incore quota expiration timestamp to an ondisk bigtime value. */
124962306a36Sopenharmony_cistatic inline uint32_t xfs_dq_unix_to_bigtime(time64_t unix_seconds)
125062306a36Sopenharmony_ci{
125162306a36Sopenharmony_ci	/*
125262306a36Sopenharmony_ci	 * Round the expiration timestamp up to the nearest bigtime timestamp
125362306a36Sopenharmony_ci	 * that we can store, to give users the most time to fix problems.
125462306a36Sopenharmony_ci	 */
125562306a36Sopenharmony_ci	return ((uint64_t)unix_seconds + XFS_DQ_BIGTIME_SLACK) >>
125662306a36Sopenharmony_ci			XFS_DQ_BIGTIME_SHIFT;
125762306a36Sopenharmony_ci}
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci/* Convert an ondisk bigtime quota expiration value to an incore timestamp. */
126062306a36Sopenharmony_cistatic inline time64_t xfs_dq_bigtime_to_unix(uint32_t ondisk_seconds)
126162306a36Sopenharmony_ci{
126262306a36Sopenharmony_ci	return (time64_t)ondisk_seconds << XFS_DQ_BIGTIME_SHIFT;
126362306a36Sopenharmony_ci}
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci/*
126662306a36Sopenharmony_ci * Default quota grace periods, ranging from zero (use the compiled defaults)
126762306a36Sopenharmony_ci * to ~136 years.  These are applied to a non-root dquot that has exceeded
126862306a36Sopenharmony_ci * either limit.
126962306a36Sopenharmony_ci */
127062306a36Sopenharmony_ci#define XFS_DQ_GRACE_MIN		((int64_t)0)
127162306a36Sopenharmony_ci#define XFS_DQ_GRACE_MAX		((int64_t)U32_MAX)
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci/*
127462306a36Sopenharmony_ci * This is the main portion of the on-disk representation of quota information
127562306a36Sopenharmony_ci * for a user.  We pad this with some more expansion room to construct the on
127662306a36Sopenharmony_ci * disk structure.
127762306a36Sopenharmony_ci */
127862306a36Sopenharmony_cistruct xfs_disk_dquot {
127962306a36Sopenharmony_ci	__be16		d_magic;	/* dquot magic = XFS_DQUOT_MAGIC */
128062306a36Sopenharmony_ci	__u8		d_version;	/* dquot version */
128162306a36Sopenharmony_ci	__u8		d_type;		/* XFS_DQTYPE_USER/PROJ/GROUP */
128262306a36Sopenharmony_ci	__be32		d_id;		/* user,project,group id */
128362306a36Sopenharmony_ci	__be64		d_blk_hardlimit;/* absolute limit on disk blks */
128462306a36Sopenharmony_ci	__be64		d_blk_softlimit;/* preferred limit on disk blks */
128562306a36Sopenharmony_ci	__be64		d_ino_hardlimit;/* maximum # allocated inodes */
128662306a36Sopenharmony_ci	__be64		d_ino_softlimit;/* preferred inode limit */
128762306a36Sopenharmony_ci	__be64		d_bcount;	/* disk blocks owned by the user */
128862306a36Sopenharmony_ci	__be64		d_icount;	/* inodes owned by the user */
128962306a36Sopenharmony_ci	__be32		d_itimer;	/* zero if within inode limits if not,
129062306a36Sopenharmony_ci					   this is when we refuse service */
129162306a36Sopenharmony_ci	__be32		d_btimer;	/* similar to above; for disk blocks */
129262306a36Sopenharmony_ci	__be16		d_iwarns;	/* warnings issued wrt num inodes */
129362306a36Sopenharmony_ci	__be16		d_bwarns;	/* warnings issued wrt disk blocks */
129462306a36Sopenharmony_ci	__be32		d_pad0;		/* 64 bit align */
129562306a36Sopenharmony_ci	__be64		d_rtb_hardlimit;/* absolute limit on realtime blks */
129662306a36Sopenharmony_ci	__be64		d_rtb_softlimit;/* preferred limit on RT disk blks */
129762306a36Sopenharmony_ci	__be64		d_rtbcount;	/* realtime blocks owned */
129862306a36Sopenharmony_ci	__be32		d_rtbtimer;	/* similar to above; for RT disk blocks */
129962306a36Sopenharmony_ci	__be16		d_rtbwarns;	/* warnings issued wrt RT disk blocks */
130062306a36Sopenharmony_ci	__be16		d_pad;
130162306a36Sopenharmony_ci};
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_ci/*
130462306a36Sopenharmony_ci * This is what goes on disk. This is separated from the xfs_disk_dquot because
130562306a36Sopenharmony_ci * carrying the unnecessary padding would be a waste of memory.
130662306a36Sopenharmony_ci */
130762306a36Sopenharmony_cistruct xfs_dqblk {
130862306a36Sopenharmony_ci	struct xfs_disk_dquot	dd_diskdq; /* portion living incore as well */
130962306a36Sopenharmony_ci	char			dd_fill[4];/* filling for posterity */
131062306a36Sopenharmony_ci
131162306a36Sopenharmony_ci	/*
131262306a36Sopenharmony_ci	 * These two are only present on filesystems with the CRC bits set.
131362306a36Sopenharmony_ci	 */
131462306a36Sopenharmony_ci	__be32		  dd_crc;	/* checksum */
131562306a36Sopenharmony_ci	__be64		  dd_lsn;	/* last modification in log */
131662306a36Sopenharmony_ci	uuid_t		  dd_uuid;	/* location information */
131762306a36Sopenharmony_ci};
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci#define XFS_DQUOT_CRC_OFF	offsetof(struct xfs_dqblk, dd_crc)
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci/*
132262306a36Sopenharmony_ci * This defines the unit of allocation of dquots.
132362306a36Sopenharmony_ci *
132462306a36Sopenharmony_ci * Currently, it is just one file system block, and a 4K blk contains 30
132562306a36Sopenharmony_ci * (136 * 30 = 4080) dquots. It's probably not worth trying to make
132662306a36Sopenharmony_ci * this more dynamic.
132762306a36Sopenharmony_ci *
132862306a36Sopenharmony_ci * However, if this number is changed, we have to make sure that we don't
132962306a36Sopenharmony_ci * implicitly assume that we do allocations in chunks of a single filesystem
133062306a36Sopenharmony_ci * block in the dquot/xqm code.
133162306a36Sopenharmony_ci *
133262306a36Sopenharmony_ci * This is part of the ondisk format because the structure size is not a power
133362306a36Sopenharmony_ci * of two, which leaves slack at the end of the disk block.
133462306a36Sopenharmony_ci */
133562306a36Sopenharmony_ci#define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_ci/*
133862306a36Sopenharmony_ci * Remote symlink format and access functions.
133962306a36Sopenharmony_ci */
134062306a36Sopenharmony_ci#define XFS_SYMLINK_MAGIC	0x58534c4d	/* XSLM */
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_cistruct xfs_dsymlink_hdr {
134362306a36Sopenharmony_ci	__be32	sl_magic;
134462306a36Sopenharmony_ci	__be32	sl_offset;
134562306a36Sopenharmony_ci	__be32	sl_bytes;
134662306a36Sopenharmony_ci	__be32	sl_crc;
134762306a36Sopenharmony_ci	uuid_t	sl_uuid;
134862306a36Sopenharmony_ci	__be64	sl_owner;
134962306a36Sopenharmony_ci	__be64	sl_blkno;
135062306a36Sopenharmony_ci	__be64	sl_lsn;
135162306a36Sopenharmony_ci};
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_ci#define XFS_SYMLINK_CRC_OFF	offsetof(struct xfs_dsymlink_hdr, sl_crc)
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci#define XFS_SYMLINK_MAXLEN	1024
135662306a36Sopenharmony_ci/*
135762306a36Sopenharmony_ci * The maximum pathlen is 1024 bytes. Since the minimum file system
135862306a36Sopenharmony_ci * blocksize is 512 bytes, we can get a max of 3 extents back from
135962306a36Sopenharmony_ci * bmapi when crc headers are taken into account.
136062306a36Sopenharmony_ci */
136162306a36Sopenharmony_ci#define XFS_SYMLINK_MAPS 3
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci#define XFS_SYMLINK_BUF_SPACE(mp, bufsize)	\
136462306a36Sopenharmony_ci	((bufsize) - (xfs_has_crc((mp)) ? \
136562306a36Sopenharmony_ci			sizeof(struct xfs_dsymlink_hdr) : 0))
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci/*
136962306a36Sopenharmony_ci * Allocation Btree format definitions
137062306a36Sopenharmony_ci *
137162306a36Sopenharmony_ci * There are two on-disk btrees, one sorted by blockno and one sorted
137262306a36Sopenharmony_ci * by blockcount and blockno.  All blocks look the same to make the code
137362306a36Sopenharmony_ci * simpler; if we have time later, we'll make the optimizations.
137462306a36Sopenharmony_ci */
137562306a36Sopenharmony_ci#define	XFS_ABTB_MAGIC		0x41425442	/* 'ABTB' for bno tree */
137662306a36Sopenharmony_ci#define	XFS_ABTB_CRC_MAGIC	0x41423342	/* 'AB3B' */
137762306a36Sopenharmony_ci#define	XFS_ABTC_MAGIC		0x41425443	/* 'ABTC' for cnt tree */
137862306a36Sopenharmony_ci#define	XFS_ABTC_CRC_MAGIC	0x41423343	/* 'AB3C' */
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci/*
138162306a36Sopenharmony_ci * Data record/key structure
138262306a36Sopenharmony_ci */
138362306a36Sopenharmony_citypedef struct xfs_alloc_rec {
138462306a36Sopenharmony_ci	__be32		ar_startblock;	/* starting block number */
138562306a36Sopenharmony_ci	__be32		ar_blockcount;	/* count of free blocks */
138662306a36Sopenharmony_ci} xfs_alloc_rec_t, xfs_alloc_key_t;
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_citypedef struct xfs_alloc_rec_incore {
138962306a36Sopenharmony_ci	xfs_agblock_t	ar_startblock;	/* starting block number */
139062306a36Sopenharmony_ci	xfs_extlen_t	ar_blockcount;	/* count of free blocks */
139162306a36Sopenharmony_ci} xfs_alloc_rec_incore_t;
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci/* btree pointer type */
139462306a36Sopenharmony_citypedef __be32 xfs_alloc_ptr_t;
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci/*
139762306a36Sopenharmony_ci * Block numbers in the AG:
139862306a36Sopenharmony_ci * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3.
139962306a36Sopenharmony_ci */
140062306a36Sopenharmony_ci#define	XFS_BNO_BLOCK(mp)	((xfs_agblock_t)(XFS_AGFL_BLOCK(mp) + 1))
140162306a36Sopenharmony_ci#define	XFS_CNT_BLOCK(mp)	((xfs_agblock_t)(XFS_BNO_BLOCK(mp) + 1))
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_ci/*
140562306a36Sopenharmony_ci * Inode Allocation Btree format definitions
140662306a36Sopenharmony_ci *
140762306a36Sopenharmony_ci * There is a btree for the inode map per allocation group.
140862306a36Sopenharmony_ci */
140962306a36Sopenharmony_ci#define	XFS_IBT_MAGIC		0x49414254	/* 'IABT' */
141062306a36Sopenharmony_ci#define	XFS_IBT_CRC_MAGIC	0x49414233	/* 'IAB3' */
141162306a36Sopenharmony_ci#define	XFS_FIBT_MAGIC		0x46494254	/* 'FIBT' */
141262306a36Sopenharmony_ci#define	XFS_FIBT_CRC_MAGIC	0x46494233	/* 'FIB3' */
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_citypedef uint64_t	xfs_inofree_t;
141562306a36Sopenharmony_ci#define	XFS_INODES_PER_CHUNK		(NBBY * sizeof(xfs_inofree_t))
141662306a36Sopenharmony_ci#define	XFS_INODES_PER_CHUNK_LOG	(XFS_NBBYLOG + 3)
141762306a36Sopenharmony_ci#define	XFS_INOBT_ALL_FREE		((xfs_inofree_t)-1)
141862306a36Sopenharmony_ci#define	XFS_INOBT_MASK(i)		((xfs_inofree_t)1 << (i))
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci#define XFS_INOBT_HOLEMASK_FULL		0	/* holemask for full chunk */
142162306a36Sopenharmony_ci#define XFS_INOBT_HOLEMASK_BITS		(NBBY * sizeof(uint16_t))
142262306a36Sopenharmony_ci#define XFS_INODES_PER_HOLEMASK_BIT	\
142362306a36Sopenharmony_ci	(XFS_INODES_PER_CHUNK / (NBBY * sizeof(uint16_t)))
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_cistatic inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
142662306a36Sopenharmony_ci{
142762306a36Sopenharmony_ci	return ((n >= XFS_INODES_PER_CHUNK ? 0 : XFS_INOBT_MASK(n)) - 1) << i;
142862306a36Sopenharmony_ci}
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci/*
143162306a36Sopenharmony_ci * The on-disk inode record structure has two formats. The original "full"
143262306a36Sopenharmony_ci * format uses a 4-byte freecount. The "sparse" format uses a 1-byte freecount
143362306a36Sopenharmony_ci * and replaces the 3 high-order freecount bytes wth the holemask and inode
143462306a36Sopenharmony_ci * count.
143562306a36Sopenharmony_ci *
143662306a36Sopenharmony_ci * The holemask of the sparse record format allows an inode chunk to have holes
143762306a36Sopenharmony_ci * that refer to blocks not owned by the inode record. This facilitates inode
143862306a36Sopenharmony_ci * allocation in the event of severe free space fragmentation.
143962306a36Sopenharmony_ci */
144062306a36Sopenharmony_citypedef struct xfs_inobt_rec {
144162306a36Sopenharmony_ci	__be32		ir_startino;	/* starting inode number */
144262306a36Sopenharmony_ci	union {
144362306a36Sopenharmony_ci		struct {
144462306a36Sopenharmony_ci			__be32	ir_freecount;	/* count of free inodes */
144562306a36Sopenharmony_ci		} f;
144662306a36Sopenharmony_ci		struct {
144762306a36Sopenharmony_ci			__be16	ir_holemask;/* hole mask for sparse chunks */
144862306a36Sopenharmony_ci			__u8	ir_count;	/* total inode count */
144962306a36Sopenharmony_ci			__u8	ir_freecount;	/* count of free inodes */
145062306a36Sopenharmony_ci		} sp;
145162306a36Sopenharmony_ci	} ir_u;
145262306a36Sopenharmony_ci	__be64		ir_free;	/* free inode mask */
145362306a36Sopenharmony_ci} xfs_inobt_rec_t;
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_citypedef struct xfs_inobt_rec_incore {
145662306a36Sopenharmony_ci	xfs_agino_t	ir_startino;	/* starting inode number */
145762306a36Sopenharmony_ci	uint16_t	ir_holemask;	/* hole mask for sparse chunks */
145862306a36Sopenharmony_ci	uint8_t		ir_count;	/* total inode count */
145962306a36Sopenharmony_ci	uint8_t		ir_freecount;	/* count of free inodes (set bits) */
146062306a36Sopenharmony_ci	xfs_inofree_t	ir_free;	/* free inode mask */
146162306a36Sopenharmony_ci} xfs_inobt_rec_incore_t;
146262306a36Sopenharmony_ci
146362306a36Sopenharmony_cistatic inline bool xfs_inobt_issparse(uint16_t holemask)
146462306a36Sopenharmony_ci{
146562306a36Sopenharmony_ci	/* non-zero holemask represents a sparse rec. */
146662306a36Sopenharmony_ci	return holemask;
146762306a36Sopenharmony_ci}
146862306a36Sopenharmony_ci
146962306a36Sopenharmony_ci/*
147062306a36Sopenharmony_ci * Key structure
147162306a36Sopenharmony_ci */
147262306a36Sopenharmony_citypedef struct xfs_inobt_key {
147362306a36Sopenharmony_ci	__be32		ir_startino;	/* starting inode number */
147462306a36Sopenharmony_ci} xfs_inobt_key_t;
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci/* btree pointer type */
147762306a36Sopenharmony_citypedef __be32 xfs_inobt_ptr_t;
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_ci/*
148062306a36Sopenharmony_ci * block numbers in the AG.
148162306a36Sopenharmony_ci */
148262306a36Sopenharmony_ci#define	XFS_IBT_BLOCK(mp)		((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
148362306a36Sopenharmony_ci#define	XFS_FIBT_BLOCK(mp)		((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ci/*
148662306a36Sopenharmony_ci * Reverse mapping btree format definitions
148762306a36Sopenharmony_ci *
148862306a36Sopenharmony_ci * There is a btree for the reverse map per allocation group
148962306a36Sopenharmony_ci */
149062306a36Sopenharmony_ci#define	XFS_RMAP_CRC_MAGIC	0x524d4233	/* 'RMB3' */
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci/*
149362306a36Sopenharmony_ci * Ownership info for an extent.  This is used to create reverse-mapping
149462306a36Sopenharmony_ci * entries.
149562306a36Sopenharmony_ci */
149662306a36Sopenharmony_ci#define XFS_OWNER_INFO_ATTR_FORK	(1 << 0)
149762306a36Sopenharmony_ci#define XFS_OWNER_INFO_BMBT_BLOCK	(1 << 1)
149862306a36Sopenharmony_cistruct xfs_owner_info {
149962306a36Sopenharmony_ci	uint64_t		oi_owner;
150062306a36Sopenharmony_ci	xfs_fileoff_t		oi_offset;
150162306a36Sopenharmony_ci	unsigned int		oi_flags;
150262306a36Sopenharmony_ci};
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_ci/*
150562306a36Sopenharmony_ci * Special owner types.
150662306a36Sopenharmony_ci *
150762306a36Sopenharmony_ci * Seeing as we only support up to 8EB, we have the upper bit of the owner field
150862306a36Sopenharmony_ci * to tell us we have a special owner value. We use these for static metadata
150962306a36Sopenharmony_ci * allocated at mkfs/growfs time, as well as for freespace management metadata.
151062306a36Sopenharmony_ci */
151162306a36Sopenharmony_ci#define XFS_RMAP_OWN_NULL	(-1ULL)	/* No owner, for growfs */
151262306a36Sopenharmony_ci#define XFS_RMAP_OWN_UNKNOWN	(-2ULL)	/* Unknown owner, for EFI recovery */
151362306a36Sopenharmony_ci#define XFS_RMAP_OWN_FS		(-3ULL)	/* static fs metadata */
151462306a36Sopenharmony_ci#define XFS_RMAP_OWN_LOG	(-4ULL)	/* static fs metadata */
151562306a36Sopenharmony_ci#define XFS_RMAP_OWN_AG		(-5ULL)	/* AG freespace btree blocks */
151662306a36Sopenharmony_ci#define XFS_RMAP_OWN_INOBT	(-6ULL)	/* Inode btree blocks */
151762306a36Sopenharmony_ci#define XFS_RMAP_OWN_INODES	(-7ULL)	/* Inode chunk */
151862306a36Sopenharmony_ci#define XFS_RMAP_OWN_REFC	(-8ULL) /* refcount tree */
151962306a36Sopenharmony_ci#define XFS_RMAP_OWN_COW	(-9ULL) /* cow allocations */
152062306a36Sopenharmony_ci#define XFS_RMAP_OWN_MIN	(-10ULL) /* guard */
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci#define XFS_RMAP_NON_INODE_OWNER(owner)	(!!((owner) & (1ULL << 63)))
152362306a36Sopenharmony_ci
152462306a36Sopenharmony_ci/*
152562306a36Sopenharmony_ci * Data record structure
152662306a36Sopenharmony_ci */
152762306a36Sopenharmony_cistruct xfs_rmap_rec {
152862306a36Sopenharmony_ci	__be32		rm_startblock;	/* extent start block */
152962306a36Sopenharmony_ci	__be32		rm_blockcount;	/* extent length */
153062306a36Sopenharmony_ci	__be64		rm_owner;	/* extent owner */
153162306a36Sopenharmony_ci	__be64		rm_offset;	/* offset within the owner */
153262306a36Sopenharmony_ci};
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_ci/*
153562306a36Sopenharmony_ci * rmap btree record
153662306a36Sopenharmony_ci *  rm_offset:63 is the attribute fork flag
153762306a36Sopenharmony_ci *  rm_offset:62 is the bmbt block flag
153862306a36Sopenharmony_ci *  rm_offset:61 is the unwritten extent flag (same as l0:63 in bmbt)
153962306a36Sopenharmony_ci *  rm_offset:54-60 aren't used and should be zero
154062306a36Sopenharmony_ci *  rm_offset:0-53 is the block offset within the inode
154162306a36Sopenharmony_ci */
154262306a36Sopenharmony_ci#define XFS_RMAP_OFF_ATTR_FORK	((uint64_t)1ULL << 63)
154362306a36Sopenharmony_ci#define XFS_RMAP_OFF_BMBT_BLOCK	((uint64_t)1ULL << 62)
154462306a36Sopenharmony_ci#define XFS_RMAP_OFF_UNWRITTEN	((uint64_t)1ULL << 61)
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci#define XFS_RMAP_LEN_MAX	((uint32_t)~0U)
154762306a36Sopenharmony_ci#define XFS_RMAP_OFF_FLAGS	(XFS_RMAP_OFF_ATTR_FORK | \
154862306a36Sopenharmony_ci				 XFS_RMAP_OFF_BMBT_BLOCK | \
154962306a36Sopenharmony_ci				 XFS_RMAP_OFF_UNWRITTEN)
155062306a36Sopenharmony_ci#define XFS_RMAP_OFF_MASK	((uint64_t)0x3FFFFFFFFFFFFFULL)
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci#define XFS_RMAP_OFF(off)		((off) & XFS_RMAP_OFF_MASK)
155362306a36Sopenharmony_ci
155462306a36Sopenharmony_ci#define XFS_RMAP_IS_BMBT_BLOCK(off)	(!!((off) & XFS_RMAP_OFF_BMBT_BLOCK))
155562306a36Sopenharmony_ci#define XFS_RMAP_IS_ATTR_FORK(off)	(!!((off) & XFS_RMAP_OFF_ATTR_FORK))
155662306a36Sopenharmony_ci#define XFS_RMAP_IS_UNWRITTEN(len)	(!!((off) & XFS_RMAP_OFF_UNWRITTEN))
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_ci#define RMAPBT_STARTBLOCK_BITLEN	32
155962306a36Sopenharmony_ci#define RMAPBT_BLOCKCOUNT_BITLEN	32
156062306a36Sopenharmony_ci#define RMAPBT_OWNER_BITLEN		64
156162306a36Sopenharmony_ci#define RMAPBT_ATTRFLAG_BITLEN		1
156262306a36Sopenharmony_ci#define RMAPBT_BMBTFLAG_BITLEN		1
156362306a36Sopenharmony_ci#define RMAPBT_EXNTFLAG_BITLEN		1
156462306a36Sopenharmony_ci#define RMAPBT_UNUSED_OFFSET_BITLEN	7
156562306a36Sopenharmony_ci#define RMAPBT_OFFSET_BITLEN		54
156662306a36Sopenharmony_ci
156762306a36Sopenharmony_ci/*
156862306a36Sopenharmony_ci * Key structure
156962306a36Sopenharmony_ci *
157062306a36Sopenharmony_ci * We don't use the length for lookups
157162306a36Sopenharmony_ci */
157262306a36Sopenharmony_cistruct xfs_rmap_key {
157362306a36Sopenharmony_ci	__be32		rm_startblock;	/* extent start block */
157462306a36Sopenharmony_ci	__be64		rm_owner;	/* extent owner */
157562306a36Sopenharmony_ci	__be64		rm_offset;	/* offset within the owner */
157662306a36Sopenharmony_ci} __attribute__((packed));
157762306a36Sopenharmony_ci
157862306a36Sopenharmony_ci/* btree pointer type */
157962306a36Sopenharmony_citypedef __be32 xfs_rmap_ptr_t;
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_ci#define	XFS_RMAP_BLOCK(mp) \
158262306a36Sopenharmony_ci	(xfs_has_finobt(((mp))) ? \
158362306a36Sopenharmony_ci	 XFS_FIBT_BLOCK(mp) + 1 : \
158462306a36Sopenharmony_ci	 XFS_IBT_BLOCK(mp) + 1)
158562306a36Sopenharmony_ci
158662306a36Sopenharmony_ci/*
158762306a36Sopenharmony_ci * Reference Count Btree format definitions
158862306a36Sopenharmony_ci *
158962306a36Sopenharmony_ci */
159062306a36Sopenharmony_ci#define	XFS_REFC_CRC_MAGIC	0x52334643	/* 'R3FC' */
159162306a36Sopenharmony_ci
159262306a36Sopenharmony_ciunsigned int xfs_refc_block(struct xfs_mount *mp);
159362306a36Sopenharmony_ci
159462306a36Sopenharmony_ci/*
159562306a36Sopenharmony_ci * Data record/key structure
159662306a36Sopenharmony_ci *
159762306a36Sopenharmony_ci * Each record associates a range of physical blocks (starting at
159862306a36Sopenharmony_ci * rc_startblock and ending rc_blockcount blocks later) with a reference
159962306a36Sopenharmony_ci * count (rc_refcount).  Extents that are being used to stage a copy on
160062306a36Sopenharmony_ci * write (CoW) operation are recorded in the refcount btree with a
160162306a36Sopenharmony_ci * refcount of 1.  All other records must have a refcount > 1 and must
160262306a36Sopenharmony_ci * track an extent mapped only by file data forks.
160362306a36Sopenharmony_ci *
160462306a36Sopenharmony_ci * Extents with a single owner (attributes, metadata, non-shared file
160562306a36Sopenharmony_ci * data) are not tracked here.  Free space is also not tracked here.
160662306a36Sopenharmony_ci * This is consistent with pre-reflink XFS.
160762306a36Sopenharmony_ci */
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci/*
161062306a36Sopenharmony_ci * Extents that are being used to stage a copy on write are stored
161162306a36Sopenharmony_ci * in the refcount btree with a refcount of 1 and the upper bit set
161262306a36Sopenharmony_ci * on the startblock.  This speeds up mount time deletion of stale
161362306a36Sopenharmony_ci * staging extents because they're all at the right side of the tree.
161462306a36Sopenharmony_ci */
161562306a36Sopenharmony_ci#define XFS_REFC_COWFLAG		(1U << 31)
161662306a36Sopenharmony_ci#define REFCNTBT_COWFLAG_BITLEN		1
161762306a36Sopenharmony_ci#define REFCNTBT_AGBLOCK_BITLEN		31
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_cistruct xfs_refcount_rec {
162062306a36Sopenharmony_ci	__be32		rc_startblock;	/* starting block number */
162162306a36Sopenharmony_ci	__be32		rc_blockcount;	/* count of blocks */
162262306a36Sopenharmony_ci	__be32		rc_refcount;	/* number of inodes linked here */
162362306a36Sopenharmony_ci};
162462306a36Sopenharmony_ci
162562306a36Sopenharmony_cistruct xfs_refcount_key {
162662306a36Sopenharmony_ci	__be32		rc_startblock;	/* starting block number */
162762306a36Sopenharmony_ci};
162862306a36Sopenharmony_ci
162962306a36Sopenharmony_ci#define MAXREFCOUNT	((xfs_nlink_t)~0U)
163062306a36Sopenharmony_ci#define MAXREFCEXTLEN	((xfs_extlen_t)~0U)
163162306a36Sopenharmony_ci
163262306a36Sopenharmony_ci/* btree pointer type */
163362306a36Sopenharmony_citypedef __be32 xfs_refcount_ptr_t;
163462306a36Sopenharmony_ci
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci/*
163762306a36Sopenharmony_ci * BMAP Btree format definitions
163862306a36Sopenharmony_ci *
163962306a36Sopenharmony_ci * This includes both the root block definition that sits inside an inode fork
164062306a36Sopenharmony_ci * and the record/pointer formats for the leaf/node in the blocks.
164162306a36Sopenharmony_ci */
164262306a36Sopenharmony_ci#define XFS_BMAP_MAGIC		0x424d4150	/* 'BMAP' */
164362306a36Sopenharmony_ci#define XFS_BMAP_CRC_MAGIC	0x424d4133	/* 'BMA3' */
164462306a36Sopenharmony_ci
164562306a36Sopenharmony_ci/*
164662306a36Sopenharmony_ci * Bmap root header, on-disk form only.
164762306a36Sopenharmony_ci */
164862306a36Sopenharmony_citypedef struct xfs_bmdr_block {
164962306a36Sopenharmony_ci	__be16		bb_level;	/* 0 is a leaf */
165062306a36Sopenharmony_ci	__be16		bb_numrecs;	/* current # of data records */
165162306a36Sopenharmony_ci} xfs_bmdr_block_t;
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci/*
165462306a36Sopenharmony_ci * Bmap btree record and extent descriptor.
165562306a36Sopenharmony_ci *  l0:63 is an extent flag (value 1 indicates non-normal).
165662306a36Sopenharmony_ci *  l0:9-62 are startoff.
165762306a36Sopenharmony_ci *  l0:0-8 and l1:21-63 are startblock.
165862306a36Sopenharmony_ci *  l1:0-20 are blockcount.
165962306a36Sopenharmony_ci */
166062306a36Sopenharmony_ci#define BMBT_EXNTFLAG_BITLEN	1
166162306a36Sopenharmony_ci#define BMBT_STARTOFF_BITLEN	54
166262306a36Sopenharmony_ci#define BMBT_STARTBLOCK_BITLEN	52
166362306a36Sopenharmony_ci#define BMBT_BLOCKCOUNT_BITLEN	21
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_ci#define BMBT_STARTOFF_MASK	((1ULL << BMBT_STARTOFF_BITLEN) - 1)
166662306a36Sopenharmony_ci#define BMBT_BLOCKCOUNT_MASK	((1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
166762306a36Sopenharmony_ci
166862306a36Sopenharmony_ci#define XFS_MAX_BMBT_EXTLEN	((xfs_extlen_t)(BMBT_BLOCKCOUNT_MASK))
166962306a36Sopenharmony_ci
167062306a36Sopenharmony_ci/*
167162306a36Sopenharmony_ci * bmbt records have a file offset (block) field that is 54 bits wide, so this
167262306a36Sopenharmony_ci * is the largest xfs_fileoff_t that we ever expect to see.
167362306a36Sopenharmony_ci */
167462306a36Sopenharmony_ci#define XFS_MAX_FILEOFF		(BMBT_STARTOFF_MASK + BMBT_BLOCKCOUNT_MASK)
167562306a36Sopenharmony_ci
167662306a36Sopenharmony_citypedef struct xfs_bmbt_rec {
167762306a36Sopenharmony_ci	__be64			l0, l1;
167862306a36Sopenharmony_ci} xfs_bmbt_rec_t;
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_citypedef uint64_t	xfs_bmbt_rec_base_t;	/* use this for casts */
168162306a36Sopenharmony_citypedef xfs_bmbt_rec_t xfs_bmdr_rec_t;
168262306a36Sopenharmony_ci
168362306a36Sopenharmony_ci/*
168462306a36Sopenharmony_ci * Values and macros for delayed-allocation startblock fields.
168562306a36Sopenharmony_ci */
168662306a36Sopenharmony_ci#define STARTBLOCKVALBITS	17
168762306a36Sopenharmony_ci#define STARTBLOCKMASKBITS	(15 + 20)
168862306a36Sopenharmony_ci#define STARTBLOCKMASK		\
168962306a36Sopenharmony_ci	(((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_cistatic inline int isnullstartblock(xfs_fsblock_t x)
169262306a36Sopenharmony_ci{
169362306a36Sopenharmony_ci	return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK;
169462306a36Sopenharmony_ci}
169562306a36Sopenharmony_ci
169662306a36Sopenharmony_cistatic inline xfs_fsblock_t nullstartblock(int k)
169762306a36Sopenharmony_ci{
169862306a36Sopenharmony_ci	ASSERT(k < (1 << STARTBLOCKVALBITS));
169962306a36Sopenharmony_ci	return STARTBLOCKMASK | (k);
170062306a36Sopenharmony_ci}
170162306a36Sopenharmony_ci
170262306a36Sopenharmony_cistatic inline xfs_filblks_t startblockval(xfs_fsblock_t x)
170362306a36Sopenharmony_ci{
170462306a36Sopenharmony_ci	return (xfs_filblks_t)((x) & ~STARTBLOCKMASK);
170562306a36Sopenharmony_ci}
170662306a36Sopenharmony_ci
170762306a36Sopenharmony_ci/*
170862306a36Sopenharmony_ci * Key structure for non-leaf levels of the tree.
170962306a36Sopenharmony_ci */
171062306a36Sopenharmony_citypedef struct xfs_bmbt_key {
171162306a36Sopenharmony_ci	__be64		br_startoff;	/* starting file offset */
171262306a36Sopenharmony_ci} xfs_bmbt_key_t, xfs_bmdr_key_t;
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci/* btree pointer type */
171562306a36Sopenharmony_citypedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_ci
171862306a36Sopenharmony_ci/*
171962306a36Sopenharmony_ci * Generic Btree block format definitions
172062306a36Sopenharmony_ci *
172162306a36Sopenharmony_ci * This is a combination of the actual format used on disk for short and long
172262306a36Sopenharmony_ci * format btrees.  The first three fields are shared by both format, but the
172362306a36Sopenharmony_ci * pointers are different and should be used with care.
172462306a36Sopenharmony_ci *
172562306a36Sopenharmony_ci * To get the size of the actual short or long form headers please use the size
172662306a36Sopenharmony_ci * macros below.  Never use sizeof(xfs_btree_block).
172762306a36Sopenharmony_ci *
172862306a36Sopenharmony_ci * The blkno, crc, lsn, owner and uuid fields are only available in filesystems
172962306a36Sopenharmony_ci * with the crc feature bit, and all accesses to them must be conditional on
173062306a36Sopenharmony_ci * that flag.
173162306a36Sopenharmony_ci */
173262306a36Sopenharmony_ci/* short form block header */
173362306a36Sopenharmony_cistruct xfs_btree_block_shdr {
173462306a36Sopenharmony_ci	__be32		bb_leftsib;
173562306a36Sopenharmony_ci	__be32		bb_rightsib;
173662306a36Sopenharmony_ci
173762306a36Sopenharmony_ci	__be64		bb_blkno;
173862306a36Sopenharmony_ci	__be64		bb_lsn;
173962306a36Sopenharmony_ci	uuid_t		bb_uuid;
174062306a36Sopenharmony_ci	__be32		bb_owner;
174162306a36Sopenharmony_ci	__le32		bb_crc;
174262306a36Sopenharmony_ci};
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_ci/* long form block header */
174562306a36Sopenharmony_cistruct xfs_btree_block_lhdr {
174662306a36Sopenharmony_ci	__be64		bb_leftsib;
174762306a36Sopenharmony_ci	__be64		bb_rightsib;
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci	__be64		bb_blkno;
175062306a36Sopenharmony_ci	__be64		bb_lsn;
175162306a36Sopenharmony_ci	uuid_t		bb_uuid;
175262306a36Sopenharmony_ci	__be64		bb_owner;
175362306a36Sopenharmony_ci	__le32		bb_crc;
175462306a36Sopenharmony_ci	__be32		bb_pad; /* padding for alignment */
175562306a36Sopenharmony_ci};
175662306a36Sopenharmony_ci
175762306a36Sopenharmony_cistruct xfs_btree_block {
175862306a36Sopenharmony_ci	__be32		bb_magic;	/* magic number for block type */
175962306a36Sopenharmony_ci	__be16		bb_level;	/* 0 is a leaf */
176062306a36Sopenharmony_ci	__be16		bb_numrecs;	/* current # of data records */
176162306a36Sopenharmony_ci	union {
176262306a36Sopenharmony_ci		struct xfs_btree_block_shdr s;
176362306a36Sopenharmony_ci		struct xfs_btree_block_lhdr l;
176462306a36Sopenharmony_ci	} bb_u;				/* rest */
176562306a36Sopenharmony_ci};
176662306a36Sopenharmony_ci
176762306a36Sopenharmony_ci/* size of a short form block */
176862306a36Sopenharmony_ci#define XFS_BTREE_SBLOCK_LEN \
176962306a36Sopenharmony_ci	(offsetof(struct xfs_btree_block, bb_u) + \
177062306a36Sopenharmony_ci	 offsetof(struct xfs_btree_block_shdr, bb_blkno))
177162306a36Sopenharmony_ci/* size of a long form block */
177262306a36Sopenharmony_ci#define XFS_BTREE_LBLOCK_LEN \
177362306a36Sopenharmony_ci	(offsetof(struct xfs_btree_block, bb_u) + \
177462306a36Sopenharmony_ci	 offsetof(struct xfs_btree_block_lhdr, bb_blkno))
177562306a36Sopenharmony_ci
177662306a36Sopenharmony_ci/* sizes of CRC enabled btree blocks */
177762306a36Sopenharmony_ci#define XFS_BTREE_SBLOCK_CRC_LEN \
177862306a36Sopenharmony_ci	(offsetof(struct xfs_btree_block, bb_u) + \
177962306a36Sopenharmony_ci	 sizeof(struct xfs_btree_block_shdr))
178062306a36Sopenharmony_ci#define XFS_BTREE_LBLOCK_CRC_LEN \
178162306a36Sopenharmony_ci	(offsetof(struct xfs_btree_block, bb_u) + \
178262306a36Sopenharmony_ci	 sizeof(struct xfs_btree_block_lhdr))
178362306a36Sopenharmony_ci
178462306a36Sopenharmony_ci#define XFS_BTREE_SBLOCK_CRC_OFF \
178562306a36Sopenharmony_ci	offsetof(struct xfs_btree_block, bb_u.s.bb_crc)
178662306a36Sopenharmony_ci#define XFS_BTREE_LBLOCK_CRC_OFF \
178762306a36Sopenharmony_ci	offsetof(struct xfs_btree_block, bb_u.l.bb_crc)
178862306a36Sopenharmony_ci
178962306a36Sopenharmony_ci/*
179062306a36Sopenharmony_ci * On-disk XFS access control list structure.
179162306a36Sopenharmony_ci */
179262306a36Sopenharmony_cistruct xfs_acl_entry {
179362306a36Sopenharmony_ci	__be32	ae_tag;
179462306a36Sopenharmony_ci	__be32	ae_id;
179562306a36Sopenharmony_ci	__be16	ae_perm;
179662306a36Sopenharmony_ci	__be16	ae_pad;		/* fill the implicit hole in the structure */
179762306a36Sopenharmony_ci};
179862306a36Sopenharmony_ci
179962306a36Sopenharmony_cistruct xfs_acl {
180062306a36Sopenharmony_ci	__be32			acl_cnt;
180162306a36Sopenharmony_ci	struct xfs_acl_entry	acl_entry[];
180262306a36Sopenharmony_ci};
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_ci/*
180562306a36Sopenharmony_ci * The number of ACL entries allowed is defined by the on-disk format.
180662306a36Sopenharmony_ci * For v4 superblocks, that is limited to 25 entries. For v5 superblocks, it is
180762306a36Sopenharmony_ci * limited only by the maximum size of the xattr that stores the information.
180862306a36Sopenharmony_ci */
180962306a36Sopenharmony_ci#define XFS_ACL_MAX_ENTRIES(mp)	\
181062306a36Sopenharmony_ci	(xfs_has_crc(mp) \
181162306a36Sopenharmony_ci		?  (XFS_XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
181262306a36Sopenharmony_ci						sizeof(struct xfs_acl_entry) \
181362306a36Sopenharmony_ci		: 25)
181462306a36Sopenharmony_ci
181562306a36Sopenharmony_ci#define XFS_ACL_SIZE(cnt) \
181662306a36Sopenharmony_ci	(sizeof(struct xfs_acl) + \
181762306a36Sopenharmony_ci		sizeof(struct xfs_acl_entry) * cnt)
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ci#define XFS_ACL_MAX_SIZE(mp) \
182062306a36Sopenharmony_ci	XFS_ACL_SIZE(XFS_ACL_MAX_ENTRIES((mp)))
182162306a36Sopenharmony_ci
182262306a36Sopenharmony_ci
182362306a36Sopenharmony_ci/* On-disk XFS extended attribute names */
182462306a36Sopenharmony_ci#define SGI_ACL_FILE		"SGI_ACL_FILE"
182562306a36Sopenharmony_ci#define SGI_ACL_DEFAULT		"SGI_ACL_DEFAULT"
182662306a36Sopenharmony_ci#define SGI_ACL_FILE_SIZE	(sizeof(SGI_ACL_FILE)-1)
182762306a36Sopenharmony_ci#define SGI_ACL_DEFAULT_SIZE	(sizeof(SGI_ACL_DEFAULT)-1)
182862306a36Sopenharmony_ci
182962306a36Sopenharmony_ci#endif /* __XFS_FORMAT_H__ */
1830