Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ CTestTestfile.cmake
_deps
CMakeUserPresets.json
build
*.img
# CLion
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
Expand Down
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ if(MSVC)
endif()

# 设置严格的 C 标准
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF) # 使用标准 C,而非 GNU 扩展

Expand All @@ -34,6 +34,9 @@ target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/utils
)

# 启用 POSIX 扩展(strdup, nanosleep 等需要)
target_compile_definitions(${PROJECT_NAME} PRIVATE _POSIX_C_SOURCE=200809L)

# 统一的编译选项
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
add_compile_options(
Expand All @@ -49,7 +52,7 @@ endif()
find_program(CLANG_TIDY clang-tidy)
if(CLANG_TIDY AND CMAKE_EXPORT_COMPILE_COMMANDS)
set_target_properties(${PROJECT_NAME} PROPERTIES
C_CLANG_TIDY "${CLANG_TIDY};--warnings-as-errors=*;--checks=-*,readability-*,bugprone-*"
C_CLANG_TIDY "${CLANG_TIDY}"
)
message(STATUS "clang-tidy enabled: ${CLANG_TIDY}")
else()
Expand Down
26 changes: 26 additions & 0 deletions include/buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef BUFFER_H
#define BUFFER_H

#include "common.h"

/* 初始化缓冲池 */
void initBuffer(void);

/* 获取块号为 blockNo 的缓冲页槽位号
* 若已在缓冲池中则直接返回槽位号
* 若不在则使用 FIFO 置换加载,返回槽位号 */
int getBufferPage(int blockNo);

/* 标记槽位为脏 */
void markDirty(int slot);

/* 将槽位写回磁盘并标记为干净 */
void flushBuffer(int slot);

/* 刷新所有脏页 */
void flushAll(void);

/* 打印缓冲状态(用于可视化) */
void printBufferState(void);

#endif /* BUFFER_H */
100 changes: 93 additions & 7 deletions include/common.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#ifndef COMMON_H
#define COMMON_H

// 前景色
#include <pthread.h>

/* ===================== 颜色宏 ===================== */

/* 前景色 */
#define COLOR_BLACK "\033[30m"
#define COLOR_RED "\033[31m"
#define COLOR_GREEN "\033[32m"
Expand All @@ -11,7 +15,7 @@
#define COLOR_CYAN "\033[36m"
#define COLOR_WHITE "\033[37m"

// 背景色
/* 背景色 */
#define BG_BLACK "\033[40m"
#define BG_RED "\033[41m"
#define BG_GREEN "\033[42m"
Expand All @@ -21,13 +25,95 @@
#define BG_CYAN "\033[46m"
#define BG_WHITE "\033[47m"

// 样式
/* 样式 */
#define BOLD "\033[1m"
#define UNDERLINE "\033[4m"
#define BLINK "\033[5m" // 部分终端不支持
#define REVERSE "\033[7m" // 交换前景背景色
#define BLINK "\033[5m"
#define REVERSE "\033[7m"

// 重置所有属性
#define COLOR_RESET "\033[0m"

#endif
/* ===================== 文件系统常量 ===================== */

#define BLOCK_SIZE 64
#define BLOCK_NUM 1024
#define BUFFER_PAGES 8
#define MAX_NAME 28
#define DIR_ENTRY_SIZE 64
#define ROOT_DIR_BLOCKS 8
#define MAX_DIR_ENTRIES \
((ROOT_DIR_BLOCKS * BLOCK_SIZE) / DIR_ENTRY_SIZE) /* 8 */
#define MAX_SUBDIR_ENTRIES 16
#define MAX_OPEN_FILES 16
#define MAX_PATH 256

/* 填充大小常量 */
#define SB_PAD_SIZE \
(BLOCK_SIZE - (4 * (int)sizeof(int))) /* 64 - 16 = 48 */
#define FB_PAD_SIZE \
(BLOCK_SIZE - (int)sizeof(int)) /* 64 - 4 = 60 */
#define DE_PAD_SIZE 4

/* ===================== 文件类型 ===================== */

#define TYPE_FILE 0
#define TYPE_DIR 1

/* ===================== 数据结构 ===================== */

/* 超级块:磁盘块 0 */
typedef struct {
int freeBlockCount; /* 空闲块总数 */
int freeChainHead; /* 空闲盘区链头 */
int rootDirStart; /* 根目录起始块 */
int rootDirBlocks; /* 根目录占用块数 */
char padding[SB_PAD_SIZE]; /* 填充至 64 字节 */
} SuperBlock;

/* 空闲块链节点(存储在空闲块开头) */
typedef struct {
int next; /* 下一空闲块号,-1 表示链尾 */
char padding[FB_PAD_SIZE]; /* 填充至 64 字节 */
} FreeBlock;

/* 目录项 */
typedef struct {
char name[MAX_NAME]; /* 文件名或目录名 */
int type; /* TYPE_FILE 或 TYPE_DIR */
int size; /* 文件大小(字节) */
int startBlock; /* 起始块号 */
int blockCount; /* 连续块数 */
int subDirStart; /* 子目录项起始块(仅目录有效) */
int subDirBlocks; /* 子目录项占用块数(仅目录有效) */
int openCount; /* 当前打开计数 */
char padding[DE_PAD_SIZE]; /* 对齐至 64 字节 */
} DirEntry;

/* 缓冲页 */
typedef struct {
int blockNo; /* 缓存的块号,-1 表示空槽 */
char data[BLOCK_SIZE]; /* 块数据 */
int dirty; /* 脏位 */
} BufferPage;

/* 打开文件表项 */
typedef struct {
int used; /* 是否正在使用 */
char path[MAX_PATH]; /* 文件路径 */
int offset; /* 当前读写偏移 */
DirEntry *entry; /* 指向目录项指针 (需加锁访问) */
} OpenFileEntry;

/* ===================== 全局变量声明 ===================== */

extern char disk[BLOCK_SIZE * BLOCK_NUM];
extern pthread_mutex_t globalLock;
extern BufferPage bufferPool[BUFFER_PAGES];
extern OpenFileEntry openFileTable[MAX_OPEN_FILES];
extern volatile int vizEnabled;

/* shell 退出信号(在 shell.c 中定义) */
extern volatile int shellShouldExit;
extern volatile int shellExitCode;

#endif /* COMMON_H */
24 changes: 24 additions & 0 deletions include/disk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef DISK_H
#define DISK_H

#include "common.h"

/* 初始化磁盘:构建超级块和空闲盘区链 */
int initDisk(void);

/* 将指定块号的数据读入 buf(不经过缓冲,用于元数据) */
int readDiskBlock(int blockNo, char *buf);

/* 将 buf 写入指定块号(不经过缓冲,用于元数据) */
int writeDiskBlock(int blockNo, const char *buf);

/* 分配 n 个连续块,返回起始块号,失败返回 -1 */
int allocBlocks(int n);

/* 回收从 start 开始的 n 个连续块 */
void freeBlocks(int start, int n);

/* 获取空闲块总数 */
int getFreeBlockCount(void);

#endif /* DISK_H */
54 changes: 54 additions & 0 deletions include/fs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef FS_H
#define FS_H

#include "common.h"

/* 初始化文件系统 */
int initFS(void);

/* 创建文件:分配连续块,插入目录项 */
int createFile(const char *path, int size);

/* 创建子目录 */
int createDir(const char *path);

/* 删除文件:回收块,检查是否被打开 */
int deleteFile(const char *path);

/* 删除子目录(目录必须为空) */
int deleteDir(const char *path);

/* 显示目录内容 */
int listDir(const char *path);

/* 根据路径查找目录项(返回指针指向磁盘数组内,需持有锁) */
DirEntry *findEntry(const char *path);

/* 打开文件,返回文件描述符 */
int openFile(const char *path);

/* 关闭文件 */
int closeFile(int fileDesc);

/* 从文件读取数据(通过缓冲页) */
int readFile(int fileDesc, char *buf, int size);

/* 向文件写入数据(通过缓冲页) */
int writeFile(int fileDesc, const char *buf, int size);

/* 文件系统命令处理函数 */
int doMkfile(int argc, char **argv);
int doMkdir(int argc, char **argv);
int doRm(int argc, char **argv);
int doRmdir(int argc, char **argv);
int doLs(int argc, char **argv);
int doRead(int argc, char **argv);
int doWrite(int argc, char **argv);
int doDf(int argc, char **argv);
int doOpen(int argc, char **argv);
int doClose(int argc, char **argv);

/* 文件系统关闭(刷新缓冲) */
void fsShutdown(void);

#endif /* FS_H */
9 changes: 9 additions & 0 deletions include/persistence.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef PERSISTENCE_H
#define PERSISTENCE_H
/* Dump 整个磁盘到文件 */
int dumpDisk(const char *filename);

/* 从文件恢复整个磁盘 */
int restoreDisk(const char *filename);

#endif // !PERSISTENCE_
26 changes: 17 additions & 9 deletions include/shell.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
#ifndef SHELL_H
#define SHELL_H

#include <pthread.h>

#define BUFFER_SIZE 1024
#define ARGV_SIZE 64
#define USERNAME_MAX 1024
#define CMDSIZE_MAX 128
#define SHELL_EXIT_REQUESTED 100 // 内部约定:请求退出Shell
#define SHELL_EXIT_REQUESTED 100 /* 内部约定:请求退出Shell */

typedef int(cmdHandler)(int argc, char **argv);

typedef struct {
int argc;
char **argv;
cmdHandler *handler;
} CommandArgs;

typedef struct {
const char *name;
const char *help;
Expand All @@ -22,11 +32,9 @@ extern ShellCmdEntry cmdBucket[CMDSIZE_MAX];
int shellInit(char *username);
int shellLoop();

static int shellCommandFound(const char *cmdName);
static int shellRegister(const char *cmdName, cmdHandler *cmdFunc,
const char *helpText);
static int shellExec(char *executeable, int argc, char **argv);
static int doEcho(int argc, char **argv);
static int doHelp(int argc, char **argv);
static int doExit(int argc, char **argv);
#endif // !SHELL_H
int shellCommandFound(const char *cmdName);
int shellRegister(const char *cmdName, cmdHandler *cmdFunc,
const char *helpText);
int shellExec(char *executeable, int argc, char **argv);

#endif /* !SHELL_H */
15 changes: 15 additions & 0 deletions include/viz.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef VIZ_H
#define VIZ_H

#include "common.h"

/* 启动可视化线程 */
int vizStart(void);

/* 停止可视化线程 */
void vizStop(void);

/* 命令处理函数 */
int doViz(int argc, char **argv);

#endif /* VIZ_H */
Loading
Loading