1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2*4882a593Smuzhiyun #ifndef _UAPI__CRAMFS_H 3*4882a593Smuzhiyun #define _UAPI__CRAMFS_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #include <linux/types.h> 6*4882a593Smuzhiyun #include <linux/magic.h> 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #define CRAMFS_SIGNATURE "Compressed ROMFS" 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun /* 11*4882a593Smuzhiyun * Width of various bitfields in struct cramfs_inode. 12*4882a593Smuzhiyun * Primarily used to generate warnings in mkcramfs. 13*4882a593Smuzhiyun */ 14*4882a593Smuzhiyun #define CRAMFS_MODE_WIDTH 16 15*4882a593Smuzhiyun #define CRAMFS_UID_WIDTH 16 16*4882a593Smuzhiyun #define CRAMFS_SIZE_WIDTH 24 17*4882a593Smuzhiyun #define CRAMFS_GID_WIDTH 8 18*4882a593Smuzhiyun #define CRAMFS_NAMELEN_WIDTH 6 19*4882a593Smuzhiyun #define CRAMFS_OFFSET_WIDTH 26 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun /* 22*4882a593Smuzhiyun * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs 23*4882a593Smuzhiyun * path length is 63 << 2 = 252. 24*4882a593Smuzhiyun */ 25*4882a593Smuzhiyun #define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2) 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun /* 28*4882a593Smuzhiyun * Reasonably terse representation of the inode data. 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun struct cramfs_inode { 31*4882a593Smuzhiyun __u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH; 32*4882a593Smuzhiyun /* SIZE for device files is i_rdev */ 33*4882a593Smuzhiyun __u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH; 34*4882a593Smuzhiyun /* NAMELEN is the length of the file name, divided by 4 and 35*4882a593Smuzhiyun rounded up. (cramfs doesn't support hard links.) */ 36*4882a593Smuzhiyun /* OFFSET: For symlinks and non-empty regular files, this 37*4882a593Smuzhiyun contains the offset (divided by 4) of the file data in 38*4882a593Smuzhiyun compressed form (starting with an array of block pointers; 39*4882a593Smuzhiyun see README). For non-empty directories it is the offset 40*4882a593Smuzhiyun (divided by 4) of the inode of the first file in that 41*4882a593Smuzhiyun directory. For anything else, offset is zero. */ 42*4882a593Smuzhiyun __u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH; 43*4882a593Smuzhiyun }; 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun struct cramfs_info { 46*4882a593Smuzhiyun __u32 crc; 47*4882a593Smuzhiyun __u32 edition; 48*4882a593Smuzhiyun __u32 blocks; 49*4882a593Smuzhiyun __u32 files; 50*4882a593Smuzhiyun }; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* 53*4882a593Smuzhiyun * Superblock information at the beginning of the FS. 54*4882a593Smuzhiyun */ 55*4882a593Smuzhiyun struct cramfs_super { 56*4882a593Smuzhiyun __u32 magic; /* 0x28cd3d45 - random number */ 57*4882a593Smuzhiyun __u32 size; /* length in bytes */ 58*4882a593Smuzhiyun __u32 flags; /* feature flags */ 59*4882a593Smuzhiyun __u32 future; /* reserved for future use */ 60*4882a593Smuzhiyun __u8 signature[16]; /* "Compressed ROMFS" */ 61*4882a593Smuzhiyun struct cramfs_info fsid; /* unique filesystem info */ 62*4882a593Smuzhiyun __u8 name[16]; /* user-defined name */ 63*4882a593Smuzhiyun struct cramfs_inode root; /* root inode data */ 64*4882a593Smuzhiyun }; 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun /* 67*4882a593Smuzhiyun * Feature flags 68*4882a593Smuzhiyun * 69*4882a593Smuzhiyun * 0x00000000 - 0x000000ff: features that work for all past kernels 70*4882a593Smuzhiyun * 0x00000100 - 0xffffffff: features that don't work for past kernels 71*4882a593Smuzhiyun */ 72*4882a593Smuzhiyun #define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */ 73*4882a593Smuzhiyun #define CRAMFS_FLAG_SORTED_DIRS 0x00000002 /* sorted dirs */ 74*4882a593Smuzhiyun #define CRAMFS_FLAG_HOLES 0x00000100 /* support for holes */ 75*4882a593Smuzhiyun #define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200 /* reserved */ 76*4882a593Smuzhiyun #define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400 /* shifted root fs */ 77*4882a593Smuzhiyun #define CRAMFS_FLAG_EXT_BLOCK_POINTERS 0x00000800 /* block pointer extensions */ 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun /* 80*4882a593Smuzhiyun * Valid values in super.flags. Currently we refuse to mount 81*4882a593Smuzhiyun * if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be 82*4882a593Smuzhiyun * changed to test super.future instead. 83*4882a593Smuzhiyun */ 84*4882a593Smuzhiyun #define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \ 85*4882a593Smuzhiyun | CRAMFS_FLAG_HOLES \ 86*4882a593Smuzhiyun | CRAMFS_FLAG_WRONG_SIGNATURE \ 87*4882a593Smuzhiyun | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET \ 88*4882a593Smuzhiyun | CRAMFS_FLAG_EXT_BLOCK_POINTERS ) 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /* 91*4882a593Smuzhiyun * Block pointer flags 92*4882a593Smuzhiyun * 93*4882a593Smuzhiyun * The maximum block offset that needs to be represented is roughly: 94*4882a593Smuzhiyun * 95*4882a593Smuzhiyun * (1 << CRAMFS_OFFSET_WIDTH) * 4 + 96*4882a593Smuzhiyun * (1 << CRAMFS_SIZE_WIDTH) / PAGE_SIZE * (4 + PAGE_SIZE) 97*4882a593Smuzhiyun * = 0x11004000 98*4882a593Smuzhiyun * 99*4882a593Smuzhiyun * That leaves room for 3 flag bits in the block pointer table. 100*4882a593Smuzhiyun */ 101*4882a593Smuzhiyun #define CRAMFS_BLK_FLAG_UNCOMPRESSED (1 << 31) 102*4882a593Smuzhiyun #define CRAMFS_BLK_FLAG_DIRECT_PTR (1 << 30) 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun #define CRAMFS_BLK_FLAGS ( CRAMFS_BLK_FLAG_UNCOMPRESSED \ 105*4882a593Smuzhiyun | CRAMFS_BLK_FLAG_DIRECT_PTR ) 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* 108*4882a593Smuzhiyun * Direct blocks are at least 4-byte aligned. 109*4882a593Smuzhiyun * Pointers to direct blocks are shifted down by 2 bits. 110*4882a593Smuzhiyun */ 111*4882a593Smuzhiyun #define CRAMFS_BLK_DIRECT_PTR_SHIFT 2 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun #endif /* _UAPI__CRAMFS_H */ 114