Initial commit

This commit is contained in:
2025-11-06 10:49:44 +08:00
commit 2d16528ac4
20 changed files with 4653 additions and 0 deletions

16
include/disk_io.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include "simplefs.h"
#include <cstdint>
#include <vector>
using DeviceFd = int;
// 读取单个块
int read_block(DeviceFd fd, uint32_t block_num, void* buffer);
// 写入单个块
int write_block(DeviceFd fd, uint32_t block_num, const void* buffer);
// 写入零块
int write_zero_blocks(DeviceFd fd, uint32_t start_block_num, uint32_t count);

33
include/fuse_ops.h Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#include <fuse_lowlevel.h>
#include <fuse.h>
#include "simplefs_context.h"
#include "simplefs.h"
// 获取文件系统上下文
SimpleFS_Context* get_fs_context();
// FUSE操作实现
int simplefs_getattr(const char *path, struct stat *stbuf);
int simplefs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi);
int simplefs_mknod(const char *path, mode_t mode, dev_t rdev);
int simplefs_mkdir(const char *path, mode_t mode);
int simplefs_unlink(const char *path);
int simplefs_rmdir(const char *path);
int simplefs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi);
int simplefs_write(const char *path, const char *buf, size_t size, off_t offset,
struct fuse_file_info *fi);
int simplefs_truncate(const char *path, off_t size);
int simplefs_chmod(const char *path, mode_t mode);
int simplefs_chown(const char *path, uid_t uid, gid_t gid);
int simplefs_utimens(const char *path, const struct timespec tv[2]);
int simplefs_access(const char *path, int mask);
int simplefs_statfs(const char *path, struct statvfs *stbuf);
int simplefs_symlink(const char *target, const char *linkpath);
int simplefs_readlink(const char *path, char *buf, size_t size);
// 初始化FUSE操作结构
void init_fuse_operations(struct fuse_operations *ops);

48
include/metadata.h Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
#include "simplefs.h"
#include "simplefs_context.h"
#include <cstdint>
#include <vector>
#include <string>
// inode管理
uint32_t alloc_inode(SimpleFS_Context& context, mode_t mode);
void free_inode(SimpleFS_Context& context, uint32_t inode_num, mode_t mode_of_freed_inode);
// 块管理
uint32_t alloc_block(SimpleFS_Context& context, uint32_t preferred_group_for_inode = static_cast<uint32_t>(-1));
void free_block(SimpleFS_Context& context, uint32_t block_num);
// inode读写
int write_inode_to_disk(SimpleFS_Context& context, uint32_t inode_num, const SimpleFS_Inode* inode_data);
int read_inode_from_disk(SimpleFS_Context& context, uint32_t inode_num, SimpleFS_Inode* inode_struct);
// 目录操作
int add_dir_entry(SimpleFS_Context& context, SimpleFS_Inode* parent_inode, uint32_t parent_inode_num,
const std::string& entry_name, uint32_t child_inode_num, uint8_t file_type);
int remove_dir_entry(SimpleFS_Context& context, SimpleFS_Inode* parent_inode, uint32_t parent_inode_num, const std::string& entry_name_to_remove);
// 路径解析
void parse_path(const std::string& path, std::string& dirname, std::string& basename);
// 位图操作
void set_bitmap_bit(std::vector<uint8_t>& bitmap_data, uint32_t bit_index);
void clear_bitmap_bit(std::vector<uint8_t>& bitmap_data, uint32_t bit_index);
bool is_bitmap_bit_set(const std::vector<uint8_t>& bitmap_data, uint32_t bit_index);
// 元数据同步
void sync_fs_metadata(SimpleFS_Context& context);
// 权限检查
struct fuse_context;
int check_access(const struct fuse_context* caller_context, const SimpleFS_Inode* inode, int requested_perm);
// 块释放
void free_all_inode_blocks(SimpleFS_Context& context, SimpleFS_Inode* inode);
// 块映射
uint32_t get_or_alloc_dir_block(SimpleFS_Context& context, SimpleFS_Inode* dir_inode, uint32_t dir_inode_num, uint32_t logical_block_idx);
uint32_t map_logical_to_physical_block(SimpleFS_Context& context, const SimpleFS_Inode* inode, uint32_t logical_block_idx);
void release_logical_block_range(SimpleFS_Context& context, SimpleFS_Inode* inode, uint32_t start_lbn, uint32_t end_lbn);

101
include/simplefs.h Normal file
View File

@@ -0,0 +1,101 @@
#pragma once
#include <cstdint>
#include <sys/types.h>
#pragma pack(push, 1)
// 文件系统常量定义
constexpr uint16_t SIMPLEFS_MAGIC = 0x5350;
constexpr uint32_t SIMPLEFS_BLOCK_SIZE = 4096;
constexpr uint32_t SIMPLEFS_ROOT_INODE_NUM = 2;
constexpr uint32_t SIMPLEFS_INODE_SIZE = 128;
constexpr uint32_t SIMPLEFS_NUM_DIRECT_BLOCKS = 12;
constexpr uint32_t SIMPLEFS_NUM_INDIRECT_BLOCKS = 1;
constexpr uint32_t SIMPLEFS_NUM_D_INDIRECT_BLOCKS = 1;
constexpr uint32_t SIMPLEFS_NUM_T_INDIRECT_BLOCKS = 1;
constexpr uint32_t SIMPLEFS_INODE_BLOCK_PTRS = SIMPLEFS_NUM_DIRECT_BLOCKS + \
SIMPLEFS_NUM_INDIRECT_BLOCKS + \
SIMPLEFS_NUM_D_INDIRECT_BLOCKS + \
SIMPLEFS_NUM_T_INDIRECT_BLOCKS;
constexpr uint32_t SIMPLEFS_MAX_FILENAME_LEN = 255;
// 文件类型常量
#ifndef S_IFMT
#define S_IFMT 0xF000 // 文件类型掩码
#define S_IFSOCK 0xC000 // 套接字
#define S_IFLNK 0xA000 // 符号链接
#define S_IFREG 0x8000 // 普通文件
#define S_IFBLK 0x6000 // 块设备
#define S_IFDIR 0x4000 // 目录
#define S_IFCHR 0x2000 // 字符设备
#define S_IFIFO 0x1000 // 管道
#endif
// 超级块结构
struct SimpleFS_SuperBlock {
uint16_t s_magic; // 魔数
uint32_t s_inodes_count; // 总inode数
uint32_t s_blocks_count; // 总块数
uint32_t s_free_blocks_count; // 空闲块数
uint32_t s_free_inodes_count; // 空闲inode数
uint32_t s_first_data_block; // 首个数据块
uint32_t s_log_block_size; // 块大小的对数值
uint32_t s_blocks_per_group; // 每组块数
uint32_t s_inodes_per_group; // 每组inode数
uint32_t s_mtime; // 最后挂载时间
uint32_t s_wtime; // 最后写入时间
uint16_t s_mnt_count; // 挂载次数
uint16_t s_max_mnt_count; // 最大挂载次数
uint16_t s_state; // 文件系统状态
uint16_t s_errors; // 错误处理方式
uint32_t s_first_ino; // 首个非保留inode号
uint16_t s_inode_size; // inode大小
uint16_t s_block_group_nr; // 块组号
uint32_t s_root_inode; // 根inode号
uint8_t s_padding[962]; // 填充到1024字节
};
static_assert(sizeof(SimpleFS_SuperBlock) == 1024, "超级块大小必须为1024字节");
// 块组描述符结构
struct SimpleFS_GroupDesc {
uint32_t bg_block_bitmap; // 块位图块号
uint32_t bg_inode_bitmap; // inode位图块号
uint32_t bg_inode_table; // inode表起始块号
uint16_t bg_free_blocks_count; // 空闲块数
uint16_t bg_free_inodes_count; // 空闲inode数
uint16_t bg_used_dirs_count; // 已使用目录数
uint8_t bg_padding[14]; // 填充到32字节
};
static_assert(sizeof(SimpleFS_GroupDesc) == 32, "块组描述符大小必须为32字节");
// inode结构
struct SimpleFS_Inode {
uint16_t i_mode; // 文件模式
uint16_t i_uid; // 用户ID
uint32_t i_size; // 文件大小
uint32_t i_atime; // 访问时间
uint32_t i_ctime; // 创建时间
uint32_t i_mtime; // 修改时间
uint32_t i_dtime; // 删除时间
uint16_t i_gid; // 组ID
uint16_t i_links_count; // 硬链接数
uint32_t i_blocks; // 块数
uint32_t i_flags; // 标志
uint32_t i_block[SIMPLEFS_INODE_BLOCK_PTRS]; // 块指针数组
uint8_t i_padding[32]; // 填充到128字节
};
static_assert(sizeof(SimpleFS_Inode) == 128, "inode大小必须为128字节");
// 目录项结构
struct SimpleFS_DirEntry {
uint32_t inode; // inode号
uint16_t rec_len; // 记录长度
uint8_t name_len; // 文件名长度
uint8_t file_type; // 文件类型
char name[SIMPLEFS_MAX_FILENAME_LEN + 1]; // 文件名
};
#pragma pack(pop)

View File

@@ -0,0 +1,13 @@
#pragma once
#include "simplefs.h"
#include "disk_io.h"
#include <vector>
#include <string>
// 文件系统全局上下文
struct SimpleFS_Context {
DeviceFd device_fd;
SimpleFS_SuperBlock sb;
std::vector<SimpleFS_GroupDesc> gdt;
};

27
include/utils.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#include <vector>
#include <string>
#include <cstdint>
#include "simplefs.h"
// 位图操作
void set_bitmap_bit(std::vector<uint8_t>& bitmap_data, uint32_t bit_index);
void clear_bitmap_bit(std::vector<uint8_t>& bitmap_data, uint32_t bit_index);
bool is_bitmap_bit_set(const std::vector<uint8_t>& bitmap_data, uint32_t bit_index);
// 路径解析
void parse_path(const std::string& path, std::string& dirname, std::string& basename);
// 目录项长度计算
inline uint16_t calculate_dir_entry_len(uint8_t name_len) {
uint16_t len = 8 + name_len;
return (len + 3) & ~3U;
}
// 设备类型检查
bool is_block_device(int fd);
// 块组备份检查
bool is_backup_group(uint32_t group_index);