# Membrane SFS - Sovereign Filesystem (Userland Edition) # Phase 37.2: The Glass Vault - Userland Architecture # # This is the CORRECT location for filesystem logic. # Kernel is just a Block Valve - no FS logic there. import ../blk import ../libc const SFS_MAGIC* = 0x32534653'u32 # "SFS2" little endian SEC_SB = 0'u64 SEC_BAM = 1'u64 SEC_DIR = 2'u64 CHUNK_SIZE = 508 EOF_MARKER = 0xFFFFFFFF'u32 DIR_ENTRY_SIZE = 64 MAX_FILENAME = 32 type DirEntry* = object filename*: array[32, char] start_sector*: uint32 size_bytes*: uint32 reserved*: array[24, byte] var sfs_mounted: bool = false var io_buffer: array[512, byte] proc print(s: cstring) = discard libc.write(1, cast[pointer](s), csize_t(s.len)) proc print(s: string) = if s.len > 0: discard libc.write(1, cast[pointer](unsafeAddr s[0]), csize_t(s.len)) # ========================================================= # Helpers # ========================================================= proc sfs_alloc_sector(): uint32 = ## Allocate a free sector using the Block Allocation Map discard blk_read(SEC_BAM, addr io_buffer[0]) for i in 0..<512: if io_buffer[i] != 0xFF: for b in 0..7: if (io_buffer[i] and byte(1 shl b)) == 0: let sec = uint32(i * 8 + b) # Mark as allocated io_buffer[i] = io_buffer[i] or byte(1 shl b) discard blk_write(SEC_BAM, addr io_buffer[0]) return sec return 0 # Disk full # ========================================================= # SFS API (Userland) # ========================================================= proc sfs_mount*(): bool = ## Mount the SFS filesystem print("[SFS-U] Mounting Userland Filesystem...\n") discard blk_read(SEC_SB, addr io_buffer[0]) # Check magic: "SFS2" if io_buffer[0] == byte('S') and io_buffer[1] == byte('F') and io_buffer[2] == byte('S') and io_buffer[3] == byte('2'): print("[SFS-U] Mount SUCCESS. Version 2 (Userland).\n") sfs_mounted = true return true else: print("[SFS-U] Mount FAILED. Invalid Magic.\n") return false proc sfs_is_mounted*(): bool = sfs_mounted proc sfs_list*(): seq[string] = ## List all files in the filesystem result = @[] if not sfs_mounted: return discard blk_read(SEC_DIR, addr io_buffer[0]) for offset in countup(0, 511, DIR_ENTRY_SIZE): if io_buffer[offset] != 0: var name = "" for i in 0.. 0: var sector_buf: array[512, byte] let chunk_size = if remaining > CHUNK_SIZE: CHUNK_SIZE else: remaining copyMem(addr sector_buf[0], cast[pointer](cast[int](data) + data_ptr), chunk_size) remaining -= chunk_size data_ptr += chunk_size # Determine next sector var next_sector = EOF_MARKER if remaining > 0: next_sector = sfs_alloc_sector() if next_sector == 0: next_sector = EOF_MARKER remaining = 0 # Write next pointer at end of sector sector_buf[508] = byte(next_sector and 0xFF) sector_buf[509] = byte((next_sector shr 8) and 0xFF) sector_buf[510] = byte((next_sector shr 16) and 0xFF) sector_buf[511] = byte((next_sector shr 24) and 0xFF) discard blk_write(uint64(current_sector), addr sector_buf[0]) if next_sector == EOF_MARKER: break current_sector = next_sector # Update directory entry discard blk_read(SEC_DIR, addr io_buffer[0]) for i in 0.. max_len: remaining = max_len var total_read = 0 while remaining > 0 and current_sector != EOF_MARKER and current_sector != 0: var sector_buf: array[512, byte] discard blk_read(uint64(current_sector), addr sector_buf[0]) let payload_size = min(remaining, CHUNK_SIZE) copyMem(cast[pointer](dest_addr), addr sector_buf[0], payload_size) dest_addr += payload_size remaining -= payload_size total_read += payload_size # Next sector pointer current_sector = uint32(sector_buf[508]) or (uint32(sector_buf[509]) shl 8) or (uint32(sector_buf[510]) shl 16) or (uint32(sector_buf[511]) shl 24) return total_read