diskfs.h (7189B)
1 /* DiskFS - Simple Filesystem for ATA drives in LuajitOS 2 * 3 * A basic filesystem supporting files and directories on ATA drives. 4 * Mounted at /mnt/hd0, /mnt/hd1, etc. 5 * 6 * Disk layout: 7 * - Sector 0: Superblock (magic, version, root dir sector, free list head) 8 * - Sector 1-N: Directory entries and file data 9 * 10 * Each directory entry is 64 bytes: 11 * - 32 bytes: filename (null-terminated) 12 * - 4 bytes: type (0=free, 1=file, 2=dir) 13 * - 4 bytes: size (for files) or first entry sector (for dirs) 14 * - 4 bytes: first data sector 15 * - 4 bytes: parent directory sector 16 * - 16 bytes: reserved 17 * 18 * File data uses linked sectors (last 4 bytes of each sector = next sector, 0 = end) 19 */ 20 21 #ifndef DISKFS_H 22 #define DISKFS_H 23 24 #include <stdint.h> 25 #include <stddef.h> 26 27 /* Magic number for formatted disks */ 28 #define DISKFS_MAGIC 0x4C4A4653 /* "LJFS" */ 29 #define DISKFS_VERSION 1 30 31 /* Sector sizes */ 32 #define DISKFS_SECTOR_SIZE 512 33 #define DISKFS_DATA_PER_SECTOR (DISKFS_SECTOR_SIZE - 4) /* 508 bytes data + 4 bytes next ptr */ 34 35 /* Entry types */ 36 #define DISKFS_TYPE_FREE 0 37 #define DISKFS_TYPE_FILE 1 38 #define DISKFS_TYPE_DIR 2 39 40 /* Directory entry size */ 41 #define DISKFS_ENTRY_SIZE 64 42 #define DISKFS_ENTRIES_PER_SECTOR (DISKFS_SECTOR_SIZE / DISKFS_ENTRY_SIZE) /* 8 entries per sector */ 43 #define DISKFS_NAME_MAX 31 44 45 /* Special sectors */ 46 #define DISKFS_SUPERBLOCK_SECTOR 0 47 #define DISKFS_ROOT_DIR_SECTOR 1 48 49 /* Error codes */ 50 #define DISKFS_OK 0 51 #define DISKFS_ERR_NOT_FORMATTED -1 52 #define DISKFS_ERR_IO -2 53 #define DISKFS_ERR_NOT_FOUND -3 54 #define DISKFS_ERR_EXISTS -4 55 #define DISKFS_ERR_FULL -5 56 #define DISKFS_ERR_NOT_DIR -6 57 #define DISKFS_ERR_NOT_FILE -7 58 #define DISKFS_ERR_INVALID -8 59 #define DISKFS_ERR_NOT_EMPTY -9 60 #define DISKFS_ERR_NAME_TOO_LONG -10 61 62 /* Superblock structure (sector 0) */ 63 typedef struct __attribute__((packed)) { 64 uint32_t magic; /* DISKFS_MAGIC */ 65 uint32_t version; /* DISKFS_VERSION */ 66 uint32_t total_sectors; /* Total sectors on disk */ 67 uint32_t free_sectors; /* Number of free sectors */ 68 uint32_t root_dir_sector; /* Root directory sector */ 69 uint32_t free_list_head; /* First free sector (linked list) */ 70 uint8_t volume_name[32]; /* Volume label */ 71 uint8_t reserved[512 - 56]; /* Padding to 512 bytes */ 72 } diskfs_superblock_t; 73 74 /* Directory entry structure (64 bytes) */ 75 typedef struct __attribute__((packed)) { 76 char name[32]; /* Filename (null-terminated) */ 77 uint32_t type; /* DISKFS_TYPE_* */ 78 uint32_t size; /* File size in bytes, or entry count for dirs */ 79 uint32_t first_sector; /* First data/content sector */ 80 uint32_t parent_sector; /* Parent directory sector */ 81 uint8_t reserved[16]; /* Reserved for future use */ 82 } diskfs_entry_t; 83 84 /* Mount point info */ 85 typedef struct { 86 uint8_t bus; /* ATA bus */ 87 uint8_t drive; /* ATA drive */ 88 uint8_t mounted; /* Is mounted? */ 89 uint8_t formatted; /* Is formatted with DISKFS? */ 90 uint32_t total_sectors; /* Total sectors */ 91 uint32_t free_sectors; /* Free sectors */ 92 char volume_name[32]; /* Volume label */ 93 } diskfs_mount_t; 94 95 /* File handle */ 96 typedef struct { 97 uint8_t bus; /* ATA bus */ 98 uint8_t drive; /* ATA drive */ 99 uint8_t is_open; /* Handle is valid */ 100 uint8_t mode; /* 'r', 'w', 'a' */ 101 uint32_t entry_sector; /* Sector containing directory entry */ 102 uint32_t entry_index; /* Index within sector */ 103 uint32_t size; /* File size */ 104 uint32_t position; /* Current read/write position */ 105 uint32_t first_sector; /* First data sector */ 106 uint32_t current_sector; /* Current data sector */ 107 uint32_t sector_offset; /* Offset within current sector */ 108 } diskfs_handle_t; 109 110 /* Maximum mounted drives */ 111 #define DISKFS_MAX_MOUNTS 4 112 113 /* API Functions */ 114 115 /** 116 * Initialize diskfs and detect formatted drives 117 */ 118 void diskfs_init(void); 119 120 /** 121 * Format a drive with DISKFS 122 * @param bus ATA bus (0=primary, 1=secondary) 123 * @param drive ATA drive (0=master, 1=slave) 124 * @param volume_name Volume label (max 31 chars) 125 * @return DISKFS_OK on success 126 */ 127 int diskfs_format(uint8_t bus, uint8_t drive, const char* volume_name); 128 129 /** 130 * Mount a drive 131 * @param bus ATA bus 132 * @param drive ATA drive 133 * @return DISKFS_OK on success 134 */ 135 int diskfs_mount(uint8_t bus, uint8_t drive); 136 137 /** 138 * Check if a path is a diskfs path (/mnt/hdX/...) 139 * @param path Path to check 140 * @param bus Output: bus number 141 * @param drive Output: drive number 142 * @param subpath Output: path within the drive (without /mnt/hdX prefix) 143 * @return 1 if diskfs path, 0 otherwise 144 */ 145 int diskfs_is_diskfs_path(const char* path, uint8_t* bus, uint8_t* drive, const char** subpath); 146 147 /** 148 * Check if a file/directory exists 149 * @param bus ATA bus 150 * @param drive ATA drive 151 * @param path Path within the drive 152 * @return 1 if exists, 0 if not 153 */ 154 int diskfs_exists(uint8_t bus, uint8_t drive, const char* path); 155 156 /** 157 * Check if path is a directory 158 */ 159 int diskfs_is_dir(uint8_t bus, uint8_t drive, const char* path); 160 161 /** 162 * Check if path is a file 163 */ 164 int diskfs_is_file(uint8_t bus, uint8_t drive, const char* path); 165 166 /** 167 * Create a directory 168 * @param bus ATA bus 169 * @param drive ATA drive 170 * @param path Path to create 171 * @return DISKFS_OK on success 172 */ 173 int diskfs_mkdir(uint8_t bus, uint8_t drive, const char* path); 174 175 /** 176 * Create/open a file 177 * @param bus ATA bus 178 * @param drive ATA drive 179 * @param path File path 180 * @param mode "r", "w", "a" 181 * @return Handle or NULL on error 182 */ 183 diskfs_handle_t* diskfs_open(uint8_t bus, uint8_t drive, const char* path, const char* mode); 184 185 /** 186 * Read from file 187 */ 188 int diskfs_read(diskfs_handle_t* handle, void* buffer, uint32_t size, uint32_t* bytes_read); 189 190 /** 191 * Write to file 192 */ 193 int diskfs_write(diskfs_handle_t* handle, const void* data, uint32_t size); 194 195 /** 196 * Close file handle 197 */ 198 void diskfs_close(diskfs_handle_t* handle); 199 200 /** 201 * Delete a file or empty directory 202 */ 203 int diskfs_remove(uint8_t bus, uint8_t drive, const char* path); 204 205 /** 206 * List directory contents 207 * @param bus ATA bus 208 * @param drive ATA drive 209 * @param path Directory path 210 * @param names Output: array of names (caller must free) 211 * @param types Output: array of types (DISKFS_TYPE_*) 212 * @param count Output: number of entries 213 * @return DISKFS_OK on success 214 */ 215 int diskfs_list(uint8_t bus, uint8_t drive, const char* path, 216 char*** names, uint32_t** types, uint32_t* count); 217 218 /** 219 * Free directory listing 220 */ 221 void diskfs_free_list(char** names, uint32_t* types, uint32_t count); 222 223 /** 224 * Get file size 225 */ 226 int diskfs_get_size(uint8_t bus, uint8_t drive, const char* path, uint32_t* size); 227 228 /** 229 * Get mount info 230 */ 231 diskfs_mount_t* diskfs_get_mount(uint8_t bus, uint8_t drive); 232 233 /** 234 * Get error string 235 */ 236 const char* diskfs_error_string(int error); 237 238 /* Lua bindings */ 239 struct lua_State; 240 int luaopen_diskfs(struct lua_State* L); 241 242 #endif /* DISKFS_H */