# Copyright (C) 2022 Jeremiah Orians # This file is part of GFK # # GFK is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # GFK is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GFK If not, see . A versioning Copy on Write Filesystem with extensive checksumming and sanity checking. Is expected to be implemented by a single threaded process which will only perform one write operation at a time. A BITMAP.SYS file may be created if the free block bitmap doesn't fit in memory and a BADBLK.SYS may be created if bad blocks are detected or discovered by any means (as the blocks themselves might not be reliable enough to identify themselves). Designed for 4096byte Blocks. The reserved sectors are such that BLOCK 0 is a full BLOCK in size and encompasses the boot sector. BLOCK_IDs are created from sector zero up to the end of the disk. BLOCK_ID is defined as the physical block index of the on-disk storage medium. Each BLOCK_ID is statically bound to its physical sector range and must always represent the same physical block. Implementations must not remap, renumber or reassign BLOCK_IDs. Blocks that are no longer pointed by the root may be garbage collected and reused at any time. There are only a handful of Block types: BOOT (only for sector 0) DIRECTORY (TAG: 0x4C444552) FILE (TAG: 0x46494C45) EXTENSION (TAG: 0x45585444) DATA (TAG: 0x44415441) BADBLOCK (TAG: 0xFFFFFFFF) FREEBLOCK (TAG: 0x00000000) METADATA (TAG: 0x4D455441) [not required to be supported] The interpretation of all fields greater than 1 byte depends upon the FILE_SYSTEM_BYTE_ORDER being BIG_ENDIAN (0x42494745) or LITTLE_ENDIAN (0x45474942) The Boot Block (sector 0) layout: 000-002: Instructions to jump to boot code 003-004: Bytes/sector (Usually 0x0200 = 512 or 0x1000 = 4096) 005 : Size of reserved area in sectors (usually 0 or 7) 006 : Sectors/Block (# = 2^N; usually 0x00 to denote 1 or 0x03 to denote 8) 007 : Media type (0xf0=removable disk, 0xf8=fixed disk) 008-00F: # of Blocks on Disk 010-017: DISK_ID 018-01B: FILE_SYSTEM_BYTE_ORDER 01C-1FD: For use by bootcode or a microkernel 1FE-1FF: Signature value (0xAA55) 200-FFF: Reserved sectors or for use by a bootstrap kernel The first Block available after the boot sector is the newest MASTER_DIRECTORY, which is just another standard directory block. If versioning support is not enabled VERSION needs to be kept at zero. If versioning support is enabled the highest value is the CURRENT version. The Root directory is identified by the magic name: [M.F.D:/] and the DIRECTORY_ID of ZERO; A directory may not point to a directory that has the same DIRECTORY_ID unless versioning support is enabled and that the directory being pointed to is an older version of directory with a lower version number. This is to allow efficient removal of old versions on a by folder and by file basis. A DIRECTORY can point to multiple files and multiple subdirectories but the DIRECTORY_IDs and FILE_IDs must be unique unless versioning support is enabled. If no version number is supplied, then the most recent version of the file is assumed. Directories can not link to other directories in a loop and there are no hard, soft or symbolic links. DIRECTORY BLOCK layout: 000-007: BLOCK_ID (to make detection of wrong block being returned possible) 008-00B: Block type TAG (TAG: DIRECTORY) 00C-011: DIRECTORY_ID 012-013: VERSION 014-01B: Count of items 01C : Name Length (250 max) 01D-117: Space reserved for the name 118-11F: BLOCK_POINTER [1] 120-127: Checksum of the target block [2] ... : multiple block pointers and their checksums FE8-FEF: BLOCK_POINTER [1] FF0-FF7: Checksum of the target block [2] FF8-FFF: Checksum of this block[0] [0] note self block checksum values assume bytes used to hold the checksum are zero when the checksum is calculated and zero'd prior to being checked. [1] A value of zero means NULL, no follow. [2] Actual checksum of block after checksum field is populated FILE BLOCK Layout: 000-007: BLOCK_ID (to make detection of wrong block being returned possible) 008-00B: Block type TAG (TAG: FILE) 00C-011: FILE_ID 012-013: VERSION 014-01B: Size of file in Bytes 01C : Name Length (250 max) 01D-117: Space reserved for the name 118-11F: BLOCK_POINTER [1] 120-127: Checksum of the target block [2] ... : multiple block pointers and their checksums FE8-FEF: BLOCK_POINTER [1] FF0-FF7: Checksum of the target block [2] FF8-FFF: Checksum of this block[0] Extension blocks are expected to be treated as fixed fanout nodes for FILES and DIRECTORIES. Implementations may opt to order the pointers for faster lookup. When the pointers in a DIRECTORY/FILE/METADATA are full, a new extension block is to be created and the pointers to non-extension blocks are moved into that block. The moved pointers in the DIRECTORY/FILE/METADATA block are zero'd and the first available pointer will then point to that newly created extension block. When all pointers in an DIRECTORY/FILE/METADATA block are to Extension blocks; all extension blocks are moved from the DIRECTORY/FILE/METADATA into a new extension block and the DIRECTORY/FILE/METADATA pointers all zero'd and the first pointer set to the newly created extension block which then may be rebalanced. EXTENSION BLOCK layout: 000-007: BLOCK_ID (to make detection of wrong block being returned possible) 008-00B: Block type TAG (TAG: EXTENSION) 00C-00F: Block type being extended TAG (TAG: DIRECTORY/FILE/METADATA) 010-015: DIRECTORY_ID/FILE_ID/METADATA_ID being extended 016-017: VERSION 018-01F: BLOCK_POINTER [1] 020-027: Checksum of the target block [2] ... : multiple block pointers and their checksums FE8-FEF: BLOCK_POINTER [1] FF0-FF7: Checksum of the target block [2] FF8-FFF: Checksum of this block[0] DATA BLOCK layout: 000-007: BLOCK_ID (to make detection of wrong block being returned possible) 008-00B: Block type TAG (TAG: DATA) 00C-00F: type of contents TAG (TAG: FILE/METADATA) 010-017: Sequence # 014-FF7: DATA FF8-FFF: Checksum of this block[0] If data block contents, sequences and type are the same between versions, they may be shared. Sequence numbers *MUST* be dense and missing numbers would indicate lost data. FREE BLOCK layout: 000-007: BLOCK_ID (to make detection of wrong block being returned possible) 008-00B: Block type TAG (TAG: FREE) 00C-FF7: ZEROS FF8-FFF: Checksum of this block[0] BAD BLOCK layout: 000-007: BLOCK_ID (may be Garbage) 008-FFF: 0xFF data repeated METADATA blocks are just files that explicity hold the METADATA for a directory or a FILE in the metadata format version specified. METADATA BLOCK layout: 000-007: BLOCK_ID (to make detection of wrong block being returned possible) 008-00B: Block type TAG (TAG: METADATA) 00C-011: METADATA_ID 012-013: VERSION 014-015: METADATA_FORMAT_VERSION 016-023: FEATURE_FLAGS 024-027: Size of METADATA in Bytes 028-02F: BLOCK_POINTER [1] 030-037: Checksum of the target block [2] ... : multiple block pointers and their checksums FE8-FEF: BLOCK_POINTER [1] FF0-FF7: Checksum of the target block [2] FF8-FFF: Checksum of this block[0] if a DIRECTORY or FILE block directly or indirectly (via an EXTENSION block) points to a METADATA block, that block is about the DIRECTORY or FILE pointing to it. METADATA blocks are forbidden from pointing to DIRECTORY, FILE or other METADATA blocks (directly or indirectly). When files/directories are copied from one filesystem to another, METADATA is not copied and instead the external metadata template is used to populate metadata. The template can specify if to COPY specific fields or to SET them with default values or that the field is explicitly to be OMITTED from the newly created METADATA. Any field without an explicit entry in the template is to be omitted. Copying inside of the filesystem follows the internal metadata template.