support arbitrary number of files in each folder (previously 64)
This commit is contained in:
parent
1259cf5487
commit
1e735ea7d0
@ -14,6 +14,7 @@ class FilesOperation {
|
||||
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);
|
||||
// int unlink_inode(u_int64_t inode_number);
|
||||
u_int64_t namei(const char* path);
|
||||
u_int64_t fischl_mkdir(const char*, mode_t);
|
||||
u_int64_t fischl_mknod(const char*, mode_t);
|
||||
|
@ -137,6 +137,7 @@ void FilesOperation::initialize_rootinode() {
|
||||
}
|
||||
|
||||
void FilesOperation::printDirectory(u_int64_t inode_number) {
|
||||
// limit to first datablock
|
||||
INode inode;
|
||||
inode.inode_construct(inode_number, disk);
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
@ -144,7 +145,7 @@ void FilesOperation::printDirectory(u_int64_t inode_number) {
|
||||
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);
|
||||
if (ent.inode_number) printf("%s\t%llu;\t", ent.file_name, ent.inode_number);
|
||||
}
|
||||
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");
|
||||
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;
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){
|
||||
ent.deserialize(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(buffer+i);
|
||||
|
||||
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
||||
for (u_int64_t idx=0; idx<inode.size; idx++) {
|
||||
read_datablock(inode, idx, rw_buffer);
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){
|
||||
ent.deserialize(rw_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;
|
||||
}
|
||||
}
|
||||
if (new_inode_number == 0) {
|
||||
perror("Failed to create file in directory: First datablock full");
|
||||
return -1;
|
||||
} else {
|
||||
write_datablock(inode, 0, buffer);
|
||||
|
||||
if (!new_inode_number) {
|
||||
char write_buffer[IO_BLOCK_SIZE] = {0};
|
||||
DirectoryEntry ent;
|
||||
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
|
||||
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());
|
||||
return -1;
|
||||
}
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
read_datablock(inode, 0, buffer);
|
||||
u_int64_t new_inode_number = 0;
|
||||
DirectoryEntry ent;
|
||||
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;
|
||||
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
for(u_int64_t idx=0; idx<inode.size; idx++) {
|
||||
read_datablock(inode, idx, buffer);
|
||||
DirectoryEntry ent;
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
/**/
|
||||
u_int64_t FilesOperation::fischl_mkdir(const char* path, mode_t mode) {
|
||||
//check path
|
||||
char *pathdup = strdup(path);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <assert.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);
|
||||
u_int64_t file2 = fsop.fischl_mkdir("/foo",0);
|
||||
printf("/foo is inode %llu, it is a directory\n", file2);
|
||||
fsop.printDirectory(1);
|
||||
u_int64_t file3 = fsop.fischl_mkdir("/foo/bar",0);
|
||||
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);
|
||||
printf("/foo/bar/baz is inode %llu, it is a file\n", file4);
|
||||
// the following three testcases will fail
|
||||
@ -73,4 +75,17 @@ int main(int argc, char *argv[]) {
|
||||
assert(read_buffer[0] == '4');
|
||||
fsop.read_datablock(inode_read, 101, read_buffer);
|
||||
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]);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user