cramfs 0.1.0

A Rust implementation of the CRAMFS filesystem (read-only)
Documentation
pub(crate) const MAGIC: u32 = 0x28cd3d45;
pub(crate) const PAD_SIZE: u64 = 512;
pub(crate) const PAGE_SIZE: u32 = 4096;

/// Valid values in super.flags.  Currently we refuse to mount
/// if (flags & ~CRAMFS_SUPPORTED_FLAGS).  Maybe that should be
/// changed to test super.future instead.
///
pub(crate) const SUPPORTED_FLAGS: u32 = 0x000000ff
    | FLAG_HOLES
    | FLAG_WRONG_SIGNATURE
    | FLAG_SHIFTED_ROOT_OFFSET
    | FLAG_EXT_BLOCK_POINTERS;

/// Feature flags
///
/// 0x00000000 - 0x000000ff: features that work for all past kernels
/// 0x00000100 - 0xffffffff: features that don't work for past kernels
///
pub(crate) const FLAG_FSID_VERSION_2: u32 = 0x00000001; // fsid version #2 
#[allow(dead_code)]
pub(crate) const FLAG_SORTED_DIRS: u32 = 0x00000002; // sorted dirs 
pub(crate) const FLAG_HOLES: u32 = 0x00000100; // support for holes 
pub(crate) const FLAG_WRONG_SIGNATURE: u32 = 0x00000200; // reserved 
pub(crate) const FLAG_SHIFTED_ROOT_OFFSET: u32 = 0x00000400; // shifted root fs 
pub(crate) const FLAG_EXT_BLOCK_POINTERS: u32 = 0x00000800; // block pointer extensions

/// Common file type mode constants
/// bit mask for the file type bit field
pub const S_IFMT: u32 = 0o170000;
/// directory
pub const S_IFDIR: u32 = 0o040000;
/// regular file
pub const S_IFREG: u32 = 0o100000;
/// symbolic link
pub const S_IFLNK: u32 = 0o120000;
/// FIFO/pipe
pub const S_IFIFO: u32 = 0o010000;
/// block device
pub const S_IFBLK: u32 = 0o060000;
/// character device
pub const S_IFCHR: u32 = 0o020000;
/// socket
pub const S_IFSOCK: u32 = 0o140000;

/// File type check macros
///
#[allow(non_snake_case)]
pub fn S_ISDIR(mode: u32) -> bool {
    (mode & S_IFMT) == S_IFDIR
}

#[allow(non_snake_case)]
pub fn S_ISREG(mode: u32) -> bool {
    (mode & S_IFMT) == S_IFREG
}

#[allow(non_snake_case)]
pub fn S_ISLNK(mode: u32) -> bool {
    (mode & S_IFMT) == S_IFLNK
}

#[allow(non_snake_case)]
pub fn S_ISCHR(mode: u32) -> bool {
    (mode & S_IFMT) == S_IFCHR
}

#[allow(non_snake_case)]
pub fn S_ISBLK(mode: u32) -> bool {
    (mode & S_IFMT) == S_IFBLK
}

#[allow(non_snake_case)]
pub fn S_ISFIFO(mode: u32) -> bool {
    (mode & S_IFMT) == S_IFIFO
}

#[allow(non_snake_case)]
pub fn S_ISSOCK(mode: u32) -> bool {
    (mode & S_IFMT) == S_IFSOCK
}

pub const ROMBUFFER_BITS: u32 = 13;
pub const ROMBUFFERSIZE: u64 = 1 << ROMBUFFER_BITS;
pub const ROMBUFFERMASK: u64 = ROMBUFFERSIZE - 1;

/// Extract the major device number from a device file's size field
pub(crate) fn major(dev: u32) -> u32 {
    (dev >> 8) & 0xfff
}

/// Extract the minor device number from a device file's size field
pub(crate) fn minor(dev: u32) -> u32 {
    (dev & 0xff) | ((dev >> 12) & 0xffffff00)
}

///
/// Block pointer flags
///
/// The maximum block offset that needs to be represented is roughly:
///
///   (1 << CRAMFS_OFFSET_WIDTH) * 4 +
///   (1 << CRAMFS_SIZE_WIDTH) / PAGE_SIZE * (4 + PAGE_SIZE)
///   = 0x11004000
///
/// That leaves room for 3 flag bits in the block pointer table.
///
pub const BLK_FLAG_UNCOMPRESSED: u32 = 1 << 31;
pub const BLK_FLAG_DIRECT_PTR: u32 = 1 << 30;

pub const BLK_FLAGS: u32 = BLK_FLAG_UNCOMPRESSED | BLK_FLAG_DIRECT_PTR;

/// Direct blocks are at least 4-byte aligned.
/// Pointers to direct blocks are shifted down by 2 bits.
///
pub const BLK_DIRECT_PTR_SHIFT: u32 = 2;