Nachos文件系统实验四:动态扩展与时间戳实现详解
1. 实验目的与要求
实验背景
Nachos原始文件系统存在两个主要限制:
- 固定文件大小:文件创建时确定大小,无法动态扩展
- 缺乏时间戳:没有文件创建/修改时间记录
实验目标
- 实现文件动态扩展:允许文件在写入时动态增长
- 添加最后修改时间:记录文件元数据,提升文件系统完整性
2. 原文件系统架构分析
应用程序
↓ (文件名)
文件系统 (FileSystem)
↓ (目录查找)
文件头 (FileHeader) ←→ 数据扇区
↓ (OpenFile封装)
读写操作
2.2 关键文件作用分析
filehdr.h/cc - 文件头(i-node等效)
宏观作用:管理文件元数据和数据块索引
int numBytes; // 文件字节数(保留)
int numSectors; // 扇区数(冗余,被替换)
int dataSectors[30]; // 直接索引表,指向数据扇区
关键方法:
Allocate(): 初始空间分配Deallocate(): 空间释放ByteToSector(): 逻辑地址到物理扇区转换
filesys.h/cc - 文件系统核心
宏观作用:管理整个文件系统操作
核心组件:
OpenFile* freeMapFile; // 位图文件(扇区分配管理)
OpenFile* directoryFile; // 目录文件(文件名映射)
关键操作流程:
- 创建文件:分配文件头扇区 → 分配数据扇区 → 目录注册
- 打开文件:目录查找 → 加载文件头 → 创建OpenFile对象
openfile.h/cc - 文件操作接口
宏观作用:提供文件读写抽象层
核心机制:
- 文件头内存缓存
- 当前位置跟踪
- 扇区边界处理
3. 详细代码修改实现
3.1 文件头结构重构(对应要求2)
修改文件: filehdr.h, filehdr.cc
原始问题:numSectors字段冗余,可通过numBytes计算得到
// filehdr.h - 结构修改
class FileHeader {
public:
// 新增时间管理接口
time_t GetModTime();
void SetModTime(time_t modTime);
private:
int numBytes;
int lastModifiedTime; // 替换原来的numSectors
int dataSectors[NumDirect];
};
// filehdr.cc - 时间管理实现
time_t FileHeader::GetModTime() {
return (time_t)lastModifiedTime;
}
void FileHeader::SetModTime(time_t modTime) {
lastModifiedTime = (int)modTime;
}
智能打印实现:
void FileHeader::Print(bool showTime) {
int numSectors = divRoundUp(numBytes, SectorSize);
if (showTime) {
printf("文件头内容。文件大小:%d。最后修改时间:%s",
numBytes, ctime((time_t*)&lastModifiedTime));
// 显示文件内容...
} else {
printf("文件头内容。文件大小:%d。文件块:\n", numBytes);
// 仅显示扇区信息...
}
}
3.2 动态扩展机制实现(对应要求1)
修改文件: openfile.h, openfile.cc
核心突破:将写入时的截断逻辑改为扩展逻辑
关键修改:
// openfile.h - 添加文件头扇区记录
class OpenFile {
private:
FileHeader *hdr;
int seekPosition;
int hdrSector; // 新增:记录文件头位置
};
// openfile.cc - 动态扩展逻辑
int OpenFile::WriteAt(char *from, int numBytes, int position) {
int fileLength = hdr->FileLength();
// 修改1:允许在文件末尾写入(原逻辑禁止)
if ((numBytes <= 0) || (position > fileLength))
return 0;
// 修改2:动态扩展检测(原逻辑直接截断)
if ((position + numBytes) > fileLength) {
int newLength = position + numBytes;
int newSectors = divRoundUp(newLength, SectorSize);
int currentSectors = divRoundUp(fileLength, SectorSize);
// 扇区分配逻辑
if (newSectors > currentSectors) {
BitMap *freeMap = new BitMap(NumSectors);
freeMap->FetchFrom(fileSystem->GetFreeMapFile());
for (int i = currentSectors; i < newSectors; i++) {
int sector = freeMap->Find();
hdr->SetDataSector(i, sector); // 动态分配新扇区
}
freeMap->WriteBack(fileSystem->GetFreeMapFile());
delete freeMap;
}
hdr->SetNumBytes(newLength); // 更新文件大小
hdr->SetModTime(time(NULL)); // 更新时间戳
hdr->WriteBack(hdrSector); // 写回磁盘
}
// 执行实际写入操作...
}
3.3 文件系统显示优化
修改文件: filesys.cc, directory.h
智能显示逻辑:
void FileSystem::Print() {
// 系统文件不显示时间
bitHdr->Print(false); // 位图文件
dirHdr->Print(false); // 目录文件
// 普通文件显示时间
for (int i = 0; i < directory->GetTableSize(); i++) {
if (directory->IsEntryInUse(i)) {
int sector = directory->GetSectorByIndex(i);
bool isSystemFile = (sector == FreeMapSector || sector == DirectorySector);
if (isSystemFile) {
hdr->Print(false); // 系统文件
} else {
hdr->Print(true); // 普通文件(显示时间)
}
}
}
}
实验验证结果




1244

被折叠的 条评论
为什么被折叠?



