fix bug for indirect datablock r/w, add . and .. to every directory
This commit is contained in:
parent
dcf0601039
commit
1259cf5487
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user