From 1259cf5487daa3e8e47b0106f20d50dc9632ba5a Mon Sep 17 00:00:00 2001 From: Ziao <1575538687@qq.com> Date: Sat, 18 Nov 2023 17:42:36 -0800 Subject: [PATCH] fix bug for indirect datablock r/w, add . and .. to every directory --- include/files.h | 6 ++++-- include/rawdisk.h | 2 +- lib/files.cpp | 38 ++++++++++++++++++++++++++++++++++++-- test/layer2_API.cpp | 10 ++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/include/files.h b/include/files.h index 98defa7..0f51c6a 100644 --- a/include/files.h +++ b/include/files.h @@ -5,12 +5,14 @@ class FilesOperation { RawDisk& disk; INodeOperation inop; 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: FilesOperation(RawDisk&); int read_datablock(const INode& inode, u_int64_t index, char* buffer); - int write_datablock(INode& inode, u_int64_t index, char* buffer); - INode* new_inode(u_int64_t inode_number, u_int64_t permissions); + int write_datablock(INode& inode, u_int64_t index, const char* buffer); 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 namei(const char* path); u_int64_t fischl_mkdir(const char*, mode_t); diff --git a/include/rawdisk.h b/include/rawdisk.h index 4cccf70..b45d419 100644 --- a/include/rawdisk.h +++ b/include/rawdisk.h @@ -64,7 +64,7 @@ public: } // 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) { perror("Error seeking to offset"); return -1; diff --git a/lib/files.cpp b/lib/files.cpp index bec0a66..48c31f9 100644 --- a/lib/files.cpp +++ b/lib/files.cpp @@ -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); } -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) { u_int64_t ret = inode.datablock_allocate(disk); 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)) { 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) { @@ -110,14 +110,45 @@ INode* FilesOperation::new_inode(u_int64_t inode_number, u_int64_t permissions) 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() { // this method must be called explicitly right after initializion root_inode = inop.inode_allocate(disk); printf("Info: root inode number: %llu\n", root_inode); INode *get_inode = new_inode(root_inode, S_IFDIR); + create_dot_dotdot(get_inode, root_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) { // trys to create a file under parent directory 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 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; return new_inode_number; } diff --git a/test/layer2_API.cpp b/test/layer2_API.cpp index e31b52d..91d0202 100644 --- a/test/layer2_API.cpp +++ b/test/layer2_API.cpp @@ -41,6 +41,8 @@ int main(int argc, char *argv[]) { inode.inode_construct(file4, *H); buffer[0] = '4'; fsop.write_datablock(inode, 3, buffer); + buffer[0] = '5'; + fsop.write_datablock(inode, 101, buffer); inode.inode_save(*H); // 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"); printf("inode number for \"/foo/bar/baz\" is %llu\n", file_baz); 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) printf("=== Part 4: read from files ===\n"); @@ -63,4 +71,6 @@ int main(int argc, char *argv[]) { inode_read.inode_construct(file_baz, *H); fsop.read_datablock(inode_read, 3, read_buffer); assert(read_buffer[0] == '4'); + fsop.read_datablock(inode_read, 101, read_buffer); + assert(read_buffer[0] == '5'); } \ No newline at end of file