fix bug for indirect datablock r/w, add . and .. to every directory

This commit is contained in:
Ziao 2023-11-18 17:42:36 -08:00
parent dcf0601039
commit 1259cf5487
4 changed files with 51 additions and 5 deletions

View File

@ -5,12 +5,14 @@ class FilesOperation {
RawDisk& disk; RawDisk& disk;
INodeOperation inop; INodeOperation inop;
u_int64_t root_inode; u_int64_t root_inode;
INode* new_inode(u_int64_t inode_number, u_int64_t permissions);
void create_dot_dotdot(INode*, u_int64_t);
public: public:
FilesOperation(RawDisk&); FilesOperation(RawDisk&);
int read_datablock(const INode& inode, u_int64_t index, char* buffer); int read_datablock(const INode& inode, u_int64_t index, char* buffer);
int write_datablock(INode& inode, u_int64_t index, char* buffer); int write_datablock(INode& inode, u_int64_t index, const char* buffer);
INode* new_inode(u_int64_t inode_number, u_int64_t permissions);
void initialize_rootinode(); void initialize_rootinode();
void printDirectory(u_int64_t);
u_int64_t create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode); u_int64_t create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode);
u_int64_t namei(const char* path); u_int64_t namei(const char* path);
u_int64_t fischl_mkdir(const char*, mode_t); u_int64_t fischl_mkdir(const char*, mode_t);

View File

@ -64,7 +64,7 @@ public:
} }
// Write a specified number of bytes at a given byte offset // Write a specified number of bytes at a given byte offset
int rawdisk_write(u_int64_t offset, char *buffer, size_t length) { int rawdisk_write(u_int64_t offset, const char *buffer, size_t length) {
if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) {
perror("Error seeking to offset"); perror("Error seeking to offset");
return -1; return -1;

View File

@ -85,7 +85,7 @@ int FilesOperation::read_datablock(const INode& inode, u_int64_t index, char* bu
return disk.rawdisk_read(read_offset, buffer, IO_BLOCK_SIZE); return disk.rawdisk_read(read_offset, buffer, IO_BLOCK_SIZE);
} }
int FilesOperation::write_datablock(INode& inode, u_int64_t index, char* buffer) { int FilesOperation::write_datablock(INode& inode, u_int64_t index, const char* buffer) {
while (index >= inode.size) { while (index >= inode.size) {
u_int64_t ret = inode.datablock_allocate(disk); u_int64_t ret = inode.datablock_allocate(disk);
inode.size += 1; inode.size += 1;
@ -94,7 +94,7 @@ int FilesOperation::write_datablock(INode& inode, u_int64_t index, char* buffer)
if (write_offset == (u_int64_t)(-1)) { if (write_offset == (u_int64_t)(-1)) {
return -1; return -1;
} }
return disk.rawdisk_read(write_offset, buffer, IO_BLOCK_SIZE); return disk.rawdisk_write(write_offset, buffer, IO_BLOCK_SIZE);
} }
INode* FilesOperation::new_inode(u_int64_t inode_number, u_int64_t permissions) { INode* FilesOperation::new_inode(u_int64_t inode_number, u_int64_t permissions) {
@ -110,14 +110,45 @@ INode* FilesOperation::new_inode(u_int64_t inode_number, u_int64_t permissions)
return inode; return inode;
} }
void FilesOperation::create_dot_dotdot(INode* inode, u_int64_t parent_inode_number) {
if(inode->size != 0) {
printf("Error: create_dot_dotdot should only be called on new inode for directory\n");
}
char buffer[IO_BLOCK_SIZE] = {0};
DirectoryEntry dot;
dot.inode_number = inode->block_number;
strcpy(dot.file_name, ".");
dot.serialize(buffer);
DirectoryEntry dotdot;
dotdot.inode_number = parent_inode_number;
strcpy(dotdot.file_name, "..");
dotdot.serialize(buffer+64);
int ret = write_datablock(*inode, 0, buffer);
inode->inode_save(disk);
}
void FilesOperation::initialize_rootinode() { void FilesOperation::initialize_rootinode() {
// this method must be called explicitly right after initializion // this method must be called explicitly right after initializion
root_inode = inop.inode_allocate(disk); root_inode = inop.inode_allocate(disk);
printf("Info: root inode number: %llu\n", root_inode); printf("Info: root inode number: %llu\n", root_inode);
INode *get_inode = new_inode(root_inode, S_IFDIR); INode *get_inode = new_inode(root_inode, S_IFDIR);
create_dot_dotdot(get_inode, root_inode);
delete get_inode; delete get_inode;
} }
void FilesOperation::printDirectory(u_int64_t inode_number) {
INode inode;
inode.inode_construct(inode_number, disk);
char buffer[IO_BLOCK_SIZE] = {0};
read_datablock(inode, 0, buffer);
DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){
ent.deserialize(buffer+i);
printf("%d(%s)\t", i, ent.file_name);
}
printf("\n");
}
u_int64_t FilesOperation::create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode) { u_int64_t FilesOperation::create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode) {
// trys to create a file under parent directory // trys to create a file under parent directory
if (strlen(name)>=56) { if (strlen(name)>=56) {
@ -156,6 +187,9 @@ u_int64_t FilesOperation::create_new_inode(u_int64_t parent_inode_number, const
// initialize new file // initialize new file
INode *get_inode = new_inode(new_inode_number, mode); INode *get_inode = new_inode(new_inode_number, mode);
if ((get_inode->permissions & S_IFMT) == S_IFDIR) {
create_dot_dotdot(get_inode, parent_inode_number);
}
delete get_inode; delete get_inode;
return new_inode_number; return new_inode_number;
} }

View File

@ -41,6 +41,8 @@ int main(int argc, char *argv[]) {
inode.inode_construct(file4, *H); inode.inode_construct(file4, *H);
buffer[0] = '4'; buffer[0] = '4';
fsop.write_datablock(inode, 3, buffer); fsop.write_datablock(inode, 3, buffer);
buffer[0] = '5';
fsop.write_datablock(inode, 101, buffer);
inode.inode_save(*H); inode.inode_save(*H);
// TODO: guard against overwriting directory datablocks // TODO: guard against overwriting directory datablocks
@ -52,6 +54,12 @@ int main(int argc, char *argv[]) {
u_int64_t file_baz = fsop.namei("/foo/bar/baz"); u_int64_t file_baz = fsop.namei("/foo/bar/baz");
printf("inode number for \"/foo/bar/baz\" is %llu\n", file_baz); printf("inode number for \"/foo/bar/baz\" is %llu\n", file_baz);
assert(file_baz == file4); assert(file_baz == file4);
u_int64_t file_foo = fsop.namei("/foo/bar/..");
printf("inode number for \"/foo/bar/..\" is %llu\n", file_foo);
assert(file_foo == file2);
u_int64_t file_bar = fsop.namei("/foo/bar/.");
printf("inode number for \"/foo/bar/.\" is %llu\n", file_bar);
assert(file_bar == file3);
// read files (TODO: fischl_read) // read files (TODO: fischl_read)
printf("=== Part 4: read from files ===\n"); printf("=== Part 4: read from files ===\n");
@ -63,4 +71,6 @@ int main(int argc, char *argv[]) {
inode_read.inode_construct(file_baz, *H); inode_read.inode_construct(file_baz, *H);
fsop.read_datablock(inode_read, 3, read_buffer); fsop.read_datablock(inode_read, 3, read_buffer);
assert(read_buffer[0] == '4'); assert(read_buffer[0] == '4');
fsop.read_datablock(inode_read, 101, read_buffer);
assert(read_buffer[0] == '5');
} }