/* * Copyright (c) 2013, 2014, 2015, 2023 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * filesystem.h * Filesystem. */ #ifndef FILESYSTEM_H #define FILESYSTEM_H bool is_8_3(const char* name); void encode_8_3(const char* decoded, char encoded[8 + 3]); void decode_8_3(const char encoded[8 + 3], char decoded[8 + 1 + 3 + 1]); void timespec_to_fat(const struct timespec* ts, uint16_t* date, uint16_t* time, uint8_t* tenths); // TODO: Unify into the above. uint8_t timespec_to_fat_tenths(struct timespec* ts); uint16_t timespec_to_fat_time(struct timespec* ts); uint16_t timespec_to_fat_date(struct timespec* ts); class Device; class Inode; static const size_t INODE_HASH_LENGTH = 1 << 16; class Filesystem { public: Filesystem(Device* device, const char* mount_path); ~Filesystem(); public: Block* bpb_block; struct fat_bpb* bpb; Device* device; const char* mount_path; mode_t mode_reg; mode_t mode_dir; uid_t uid; gid_t gid; uint32_t block_size; uint16_t bytes_per_sector; uint16_t root_dirent_count; uint32_t sectors_per_fat; uint32_t root_inode_id; uint32_t total_sectors; uint32_t fat_sector; // TODO: Rename to lba uint32_t root_sector; // TODO: Rename to lba uint32_t data_sector; // TODO: Rename to lba uint32_t cluster_count; uint32_t cluster_size; uint8_t fat_type; uint32_t eio_cluster; uint32_t eof_cluster; uint32_t free_search; Inode* mru_inode; Inode* lru_inode; Inode* dirty_inode; Inode* hash_inodes[INODE_HASH_LENGTH]; bool dirty; public: Inode* GetInode(uint32_t inode_id, Block* dirent_block = NULL, struct fat_dirent* dirent = NULL); uint32_t AllocateCluster(); void FreeCluster(uint32_t cluster); uint32_t ReadFAT(uint32_t cluster); bool WriteFAT(uint32_t cluster, uint32_t value); uint32_t CalculateFreeCount(); void BeginWrite(); void FinishWrite(); void Sync(); }; #endif