162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
262306a36Sopenharmony_ci#ifndef _UAPI__CRAMFS_H
362306a36Sopenharmony_ci#define _UAPI__CRAMFS_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/types.h>
662306a36Sopenharmony_ci#include <linux/magic.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#define CRAMFS_SIGNATURE	"Compressed ROMFS"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/*
1162306a36Sopenharmony_ci * Width of various bitfields in struct cramfs_inode.
1262306a36Sopenharmony_ci * Primarily used to generate warnings in mkcramfs.
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci#define CRAMFS_MODE_WIDTH 16
1562306a36Sopenharmony_ci#define CRAMFS_UID_WIDTH 16
1662306a36Sopenharmony_ci#define CRAMFS_SIZE_WIDTH 24
1762306a36Sopenharmony_ci#define CRAMFS_GID_WIDTH 8
1862306a36Sopenharmony_ci#define CRAMFS_NAMELEN_WIDTH 6
1962306a36Sopenharmony_ci#define CRAMFS_OFFSET_WIDTH 26
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs
2362306a36Sopenharmony_ci * path length is 63 << 2 = 252.
2462306a36Sopenharmony_ci */
2562306a36Sopenharmony_ci#define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2)
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*
2862306a36Sopenharmony_ci * Reasonably terse representation of the inode data.
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_cistruct cramfs_inode {
3162306a36Sopenharmony_ci	__u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH;
3262306a36Sopenharmony_ci	/* SIZE for device files is i_rdev */
3362306a36Sopenharmony_ci	__u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH;
3462306a36Sopenharmony_ci	/* NAMELEN is the length of the file name, divided by 4 and
3562306a36Sopenharmony_ci           rounded up.  (cramfs doesn't support hard links.) */
3662306a36Sopenharmony_ci	/* OFFSET: For symlinks and non-empty regular files, this
3762306a36Sopenharmony_ci	   contains the offset (divided by 4) of the file data in
3862306a36Sopenharmony_ci	   compressed form (starting with an array of block pointers;
3962306a36Sopenharmony_ci	   see README).  For non-empty directories it is the offset
4062306a36Sopenharmony_ci	   (divided by 4) of the inode of the first file in that
4162306a36Sopenharmony_ci	   directory.  For anything else, offset is zero. */
4262306a36Sopenharmony_ci	__u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH;
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistruct cramfs_info {
4662306a36Sopenharmony_ci	__u32 crc;
4762306a36Sopenharmony_ci	__u32 edition;
4862306a36Sopenharmony_ci	__u32 blocks;
4962306a36Sopenharmony_ci	__u32 files;
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/*
5362306a36Sopenharmony_ci * Superblock information at the beginning of the FS.
5462306a36Sopenharmony_ci */
5562306a36Sopenharmony_cistruct cramfs_super {
5662306a36Sopenharmony_ci	__u32 magic;			/* 0x28cd3d45 - random number */
5762306a36Sopenharmony_ci	__u32 size;			/* length in bytes */
5862306a36Sopenharmony_ci	__u32 flags;			/* feature flags */
5962306a36Sopenharmony_ci	__u32 future;			/* reserved for future use */
6062306a36Sopenharmony_ci	__u8 signature[16];		/* "Compressed ROMFS" */
6162306a36Sopenharmony_ci	struct cramfs_info fsid;	/* unique filesystem info */
6262306a36Sopenharmony_ci	__u8 name[16];			/* user-defined name */
6362306a36Sopenharmony_ci	struct cramfs_inode root;	/* root inode data */
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/*
6762306a36Sopenharmony_ci * Feature flags
6862306a36Sopenharmony_ci *
6962306a36Sopenharmony_ci * 0x00000000 - 0x000000ff: features that work for all past kernels
7062306a36Sopenharmony_ci * 0x00000100 - 0xffffffff: features that don't work for past kernels
7162306a36Sopenharmony_ci */
7262306a36Sopenharmony_ci#define CRAMFS_FLAG_FSID_VERSION_2	0x00000001	/* fsid version #2 */
7362306a36Sopenharmony_ci#define CRAMFS_FLAG_SORTED_DIRS		0x00000002	/* sorted dirs */
7462306a36Sopenharmony_ci#define CRAMFS_FLAG_HOLES		0x00000100	/* support for holes */
7562306a36Sopenharmony_ci#define CRAMFS_FLAG_WRONG_SIGNATURE	0x00000200	/* reserved */
7662306a36Sopenharmony_ci#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET	0x00000400	/* shifted root fs */
7762306a36Sopenharmony_ci#define CRAMFS_FLAG_EXT_BLOCK_POINTERS	0x00000800	/* block pointer extensions */
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/*
8062306a36Sopenharmony_ci * Valid values in super.flags.  Currently we refuse to mount
8162306a36Sopenharmony_ci * if (flags & ~CRAMFS_SUPPORTED_FLAGS).  Maybe that should be
8262306a36Sopenharmony_ci * changed to test super.future instead.
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_ci#define CRAMFS_SUPPORTED_FLAGS	( 0x000000ff \
8562306a36Sopenharmony_ci				| CRAMFS_FLAG_HOLES \
8662306a36Sopenharmony_ci				| CRAMFS_FLAG_WRONG_SIGNATURE \
8762306a36Sopenharmony_ci				| CRAMFS_FLAG_SHIFTED_ROOT_OFFSET \
8862306a36Sopenharmony_ci				| CRAMFS_FLAG_EXT_BLOCK_POINTERS )
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci/*
9162306a36Sopenharmony_ci * Block pointer flags
9262306a36Sopenharmony_ci *
9362306a36Sopenharmony_ci * The maximum block offset that needs to be represented is roughly:
9462306a36Sopenharmony_ci *
9562306a36Sopenharmony_ci *   (1 << CRAMFS_OFFSET_WIDTH) * 4 +
9662306a36Sopenharmony_ci *   (1 << CRAMFS_SIZE_WIDTH) / PAGE_SIZE * (4 + PAGE_SIZE)
9762306a36Sopenharmony_ci *   = 0x11004000
9862306a36Sopenharmony_ci *
9962306a36Sopenharmony_ci * That leaves room for 3 flag bits in the block pointer table.
10062306a36Sopenharmony_ci */
10162306a36Sopenharmony_ci#define CRAMFS_BLK_FLAG_UNCOMPRESSED	(1 << 31)
10262306a36Sopenharmony_ci#define CRAMFS_BLK_FLAG_DIRECT_PTR	(1 << 30)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci#define CRAMFS_BLK_FLAGS	( CRAMFS_BLK_FLAG_UNCOMPRESSED \
10562306a36Sopenharmony_ci				| CRAMFS_BLK_FLAG_DIRECT_PTR )
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/*
10862306a36Sopenharmony_ci * Direct blocks are at least 4-byte aligned.
10962306a36Sopenharmony_ci * Pointers to direct blocks are shifted down by 2 bits.
11062306a36Sopenharmony_ci */
11162306a36Sopenharmony_ci#define CRAMFS_BLK_DIRECT_PTR_SHIFT	2
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#endif /* _UAPI__CRAMFS_H */
114