support arbitrary number of files in each folder (previously 64)

This commit is contained in:
Ziao 2023-11-18 19:25:53 -08:00
parent 1259cf5487
commit 1e735ea7d0
3 changed files with 59 additions and 29 deletions

View File

@ -14,6 +14,7 @@ class FilesOperation {
void initialize_rootinode(); void initialize_rootinode();
void printDirectory(u_int64_t); 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);
// int unlink_inode(u_int64_t inode_number);
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);
u_int64_t fischl_mknod(const char*, mode_t); u_int64_t fischl_mknod(const char*, mode_t);

View File

@ -137,6 +137,7 @@ void FilesOperation::initialize_rootinode() {
} }
void FilesOperation::printDirectory(u_int64_t inode_number) { void FilesOperation::printDirectory(u_int64_t inode_number) {
// limit to first datablock
INode inode; INode inode;
inode.inode_construct(inode_number, disk); inode.inode_construct(inode_number, disk);
char buffer[IO_BLOCK_SIZE] = {0}; char buffer[IO_BLOCK_SIZE] = {0};
@ -144,7 +145,7 @@ void FilesOperation::printDirectory(u_int64_t inode_number) {
DirectoryEntry ent; DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){ for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){
ent.deserialize(buffer+i); ent.deserialize(buffer+i);
printf("%d(%s)\t", i, ent.file_name); if (ent.inode_number) printf("%s\t%llu;\t", ent.file_name, ent.inode_number);
} }
printf("\n"); printf("\n");
} }
@ -161,29 +162,39 @@ u_int64_t FilesOperation::create_new_inode(u_int64_t parent_inode_number, const
printf("Parent Inode is not a directory\n"); printf("Parent Inode is not a directory\n");
return -1; return -1;
} }
char buffer[IO_BLOCK_SIZE] = {0};
if (inode.size > 0) read_datablock(inode, 0, buffer);
// do create inode
u_int64_t new_inode_number = 0; u_int64_t new_inode_number = 0;
DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){ char rw_buffer[IO_BLOCK_SIZE] = {0};
ent.deserialize(buffer+i); for (u_int64_t idx=0; idx<inode.size; idx++) {
if (ent.inode_number == 0) { read_datablock(inode, idx, rw_buffer);
new_inode_number = inop.inode_allocate(disk); DirectoryEntry ent;
ent.inode_number = new_inode_number; for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){
strcpy(ent.file_name, name); ent.deserialize(rw_buffer+i);
ent.serialize(buffer+i); if (ent.inode_number == 0) {
new_inode_number = inop.inode_allocate(disk);
ent.inode_number = new_inode_number;
strcpy(ent.file_name, name);
ent.serialize(rw_buffer+i);
break;
}
}
if (new_inode_number) {
write_datablock(inode, idx, rw_buffer);
break; break;
} }
} }
if (new_inode_number == 0) {
perror("Failed to create file in directory: First datablock full"); if (!new_inode_number) {
return -1; char write_buffer[IO_BLOCK_SIZE] = {0};
} else { DirectoryEntry ent;
write_datablock(inode, 0, buffer); new_inode_number = inop.inode_allocate(disk);
ent.inode_number = new_inode_number;
strcpy(ent.file_name, name);
ent.serialize(write_buffer);
write_datablock(inode, inode.size, write_buffer);
inode.inode_save(disk);
} }
inode.inode_save(disk);
// initialize new file // initialize new file
INode *get_inode = new_inode(new_inode_number, mode); INode *get_inode = new_inode(new_inode_number, mode);
@ -212,16 +223,20 @@ u_int64_t FilesOperation::namei(const char* path) {
printf("namei: %s is not a non-empty directory\n", current_dirname.c_str()); printf("namei: %s is not a non-empty directory\n", current_dirname.c_str());
return -1; return -1;
} }
char buffer[IO_BLOCK_SIZE] = {0};
read_datablock(inode, 0, buffer);
u_int64_t new_inode_number = 0; u_int64_t new_inode_number = 0;
DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){ char buffer[IO_BLOCK_SIZE] = {0};
ent.deserialize(buffer+i); for(u_int64_t idx=0; idx<inode.size; idx++) {
if (strcmp(ent.file_name, new_name.c_str()) == 0) { read_datablock(inode, idx, buffer);
new_inode_number = ent.inode_number; DirectoryEntry ent;
break; for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){
ent.deserialize(buffer+i);
if (strcmp(ent.file_name, new_name.c_str()) == 0) {
new_inode_number = ent.inode_number;
break;
}
} }
if (new_inode_number) break;
} }
if (!new_inode_number) { if (!new_inode_number) {
printf("namei: no name matching %s under directory %s\n", new_name.c_str(), current_dirname.c_str()); printf("namei: no name matching %s under directory %s\n", new_name.c_str(), current_dirname.c_str());
@ -238,7 +253,6 @@ u_int64_t FilesOperation::namei(const char* path) {
// path = "/notnonemptydir/foo" should raise error // path = "/notnonemptydir/foo" should raise error
} }
/**/
u_int64_t FilesOperation::fischl_mkdir(const char* path, mode_t mode) { u_int64_t FilesOperation::fischl_mkdir(const char* path, mode_t mode) {
//check path //check path
char *pathdup = strdup(path); char *pathdup = strdup(path);

View File

@ -1,5 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string>
#include <assert.h> #include <assert.h>
#include "files.h" #include "files.h"
@ -19,8 +19,10 @@ int main(int argc, char *argv[]) {
printf("/test is inode %llu, it is a file\n", file1); printf("/test is inode %llu, it is a file\n", file1);
u_int64_t file2 = fsop.fischl_mkdir("/foo",0); u_int64_t file2 = fsop.fischl_mkdir("/foo",0);
printf("/foo is inode %llu, it is a directory\n", file2); printf("/foo is inode %llu, it is a directory\n", file2);
fsop.printDirectory(1);
u_int64_t file3 = fsop.fischl_mkdir("/foo/bar",0); u_int64_t file3 = fsop.fischl_mkdir("/foo/bar",0);
printf("/foo/bar is inode %llu, it is a directory\n", file3); printf("/foo/bar is inode %llu, it is a directory\n", file3);
fsop.printDirectory(file2);
u_int64_t file4 = fsop.fischl_mknod("/foo/bar/baz",0); u_int64_t file4 = fsop.fischl_mknod("/foo/bar/baz",0);
printf("/foo/bar/baz is inode %llu, it is a file\n", file4); printf("/foo/bar/baz is inode %llu, it is a file\n", file4);
// the following three testcases will fail // the following three testcases will fail
@ -73,4 +75,17 @@ int main(int argc, char *argv[]) {
assert(read_buffer[0] == '4'); assert(read_buffer[0] == '4');
fsop.read_datablock(inode_read, 101, read_buffer); fsop.read_datablock(inode_read, 101, read_buffer);
assert(read_buffer[0] == '5'); assert(read_buffer[0] == '5');
// pressure test create directory
printf("=== Part 5: pressure test create files ===\n");
u_int64_t file_pressure = fsop.fischl_mkdir("/pressure", 0);
u_int64_t inode_numbers[700];
std::string prefix = "/pressure/";
for(int i=0;i<700;i++){
inode_numbers[i] = fsop.fischl_mkdir((prefix+std::to_string(i)).c_str(), 0);
}
for(int i=0;i<700;i++){
u_int64_t inode_number = fsop.namei((prefix+std::to_string(i)).c_str());
assert(inode_number == inode_numbers[i]);
}
} }