BeFS

From OSDev Wiki
Jump to navigation Jump to search
Filesystems
Virtual Filesystems

VFS

Disk Filesystems
CD/DVD Filesystems
Network Filesystems
Flash Filesystems

Be File System (BeFS) is the native filesystem of BeOS and Haiku. It was designed in the mid-1990s to support the operating system’s core goals: responsiveness, multimedia performance, and pervasive metadata. Unlike many contemporaneous filesystems, BeFS treats files not merely as byte streams, but as structured objects with indexed attributes, enabling database-like queries directly at the filesystem level.

Basic Details

Block Sizes 1024, 2048, 4096, or 8192 bytes
Directory Structures B+ Trees
Max Volume Size 2 Exabytes
Max File Size ~260GB
Max Filename Length 255 Bytes
Filesystem Encoding UTF-8

On-Disk Structure

Superblock

typedef struct disk_super_block
{
char name[B_OS_NAME_LENGTH];
int32 magic1;
int32 fs_byte_order;
uint32 block_size;
uint32 block_shift;
off_t num_blocks;
off_t used_blocks;
int32 inode_size;
int32 magic2;
int32 blocks_per_ag;
int32 ag_shift;
int32 num_ags;
int32 flags;
block_run log_blocks;
off_t log_start;
off_t log_end;
int32 magic3;
inode_addr root_dir;
inode_addr indices;
int32 pad[8];
} disk_super_block;
  • name The human-readable name (volume label) of the BeFS filesystem, limited to 32 characters.
  • magic1 First magic number (0x42465331, ASCII "BFS1") used to identify a valid BeFS superblock.
  • fs_byte_order Indicates the byte order of the filesystem.
  • block_size Size of a filesystem block in bytes (typically a power of 2, such as 1024, 2048, etc.).
  • block_shift Log base 2 of the block size, used for quick block-to-byte conversions.
  • num_blocks Total number of blocks in the filesystem volume.
  • used_blocks Number of blocks currently allocated (used) in the volume.
  • inode_size Size of each inode structure on disk (typically 2048 bytes in modern implementations).
  • magic2 Second magic number (0xdd121031) for additional superblock validation.
  • blocks_per_ag Number of blocks per allocation group.
  • ag_shift Log base 2 of blocks per allocation group, for efficient calculations.
  • num_ags Total number of allocation groups in the filesystem.
  • flags Filesystem flags, including clean/dirty state (e.g., 'BFS_CLEAN' for clean, 'BFS_DIRTY' for dirty).
  • log_blocks Block run describing the location and extent of the journal log blocks.
  • log_start Starting block number of the journal log.
  • log_end Ending block number of the journal log.
  • magic3 Third magic number (0x15b6830e) for further superblock integrity checking.
  • root_dir Address (as an inode_addr/block_run) of the root directory inode.
  • indices Address (as an inode_addr/block_run) of the indices root inode, used for attribute indexing.
  • pad[8] Reserved padding bytes to align the structure.

Block Runs

typedef struct block_run
{
int32 allocation_group;
uint16 start;
uint16 len;
} block_run;

BeFS uses block runs to read and allocate disk blocks.

allocation_group stores allocation group number.

start Indicates the start of the block run within that allocation group.

len Length of the block run.

This limits the size of an allocation group to 65,536 bytes, which in turn limits the max block size to 8192 bytes.

Inode Structure

typedef struct bfs_inode
{
int32 magic1;
inode_addr inode_num;
int32 uid;
int32 gid;
int32 mode;
int32 flags;
bigtime_t create_time;
bigtime_t last_modified_time;
inode_addr parent;
inode_addr attributes;
uint32 type;
int32 inode_size;
binode_etc *etc;
data_stream data;
int32 pad[4];
int32 small_data[1];
} bfs_inode;
  • magic1 Magic number (0x64358428) used to identify a valid BeFS inode structure.
  • inode_num The unique address (block_run/inode_addr) identifying this inode within the filesystem.
  • uid User ID of the inode's owner.
  • gid Group ID of the inode's owner.
  • mode File mode and permissions (similar to Unix stat mode bits).
  • flags Inode flags controlling various behaviors or states.
  • create_time Timestamp (in microseconds since epoch) of when the inode was created.
  • last_modified_time Timestamp (in microseconds since epoch) of the last data modification.
  • parent Address (block_run/inode_addr) of the parent directory inode.
  • attributes Address (block_run/inode_addr) of the directory containing this inode's extended attributes.
  • type Type field, used for special file types (e.g., mail, symbolic links).
  • inode_size Total size of the on-disk inode structure (including variable-length sections).
  • etc Pointer to additional inode-specific data (e.g., for symbolic links or special nodes).
  • data The data_stream structure describing the location and extents of the file's primary data blocks.
  • pad[4] Reserved padding bytes for alignment.
  • small_data[1] Flexible array starting the variable-length small_data section, used for short file names, symbolic link targets, and other small inline attributes.

[1]

OS Support

Currently, BeFS is used by BeOS, Magnussoft ZETA (BeOS derivative), as well as Haiku. It has an experimental driver in the Linux kernel since 2.4.x era.[2]

Because of the well-documented nature it was also used by SkyOS and served as inspiration for AtheOS Filesystem.

Performance Characteristics

BeFS was designed with multithreading and low latency in mind. The filesystem is reentrant and supports fine-grained locking, allowing multiple threads to access different parts of the filesystem concurrently.

Sequential I/O performance is competitive with other filesystems of its era, but BeFS particularly excels at metadata-heavy operations, such as directory scans and attribute queries. However, write performance can degrade under heavy fragmentation, as BeFS does not aggressively optimize data placement beyond basic allocation heuristics.

See Also