support unlinking files and directories
This commit is contained in:
parent
1e735ea7d0
commit
5dbac3d9e3
@ -14,11 +14,11 @@ 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);
|
||||
void 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);
|
||||
//int fischl_readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags);
|
||||
//int fischl_unlink (const char *);
|
||||
int fischl_unlink (const char *);
|
||||
//int fischl_open (const char *, struct fuse_file_info *);
|
||||
};
|
@ -294,4 +294,77 @@ u_int64_t FilesOperation::fischl_mknod(const char* path, mode_t mode) {
|
||||
u_int64_t ret = create_new_inode(parent_inode_number, newFilename, mode);
|
||||
delete pathdup;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FilesOperation::unlink_inode(u_int64_t inode_number) {
|
||||
INode inode;
|
||||
inode.inode_construct(inode_number, disk);
|
||||
if ((inode.permissions & S_IFMT) == S_IFDIR) {
|
||||
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){
|
||||
if(ent.inode_number && strcmp(ent.file_name,".") && strcmp(ent.file_name,"..")){
|
||||
unlink_inode(ent.inode_number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while(inode.size != 0) {
|
||||
inode.datablock_deallocate(disk);
|
||||
inode.size--;
|
||||
}
|
||||
inop.inode_free(disk, inode_number);
|
||||
}
|
||||
|
||||
int FilesOperation::fischl_unlink(const char* path) {
|
||||
char *pathdup = strdup(path);
|
||||
char *lastSlash = strrchr(pathdup, '/');
|
||||
*lastSlash = '\0';
|
||||
char *filename = lastSlash+1;
|
||||
char *ParentPath = pathdup;
|
||||
if (!strcmp(filename,".")||!strcmp(filename,"..")) {
|
||||
printf("refusing to remove . or ..\n");
|
||||
return -1;
|
||||
}
|
||||
u_int64_t parent_inode = namei(ParentPath);
|
||||
if (parent_inode == (u_int64_t)(-1)) {
|
||||
delete pathdup;
|
||||
return -1;
|
||||
}
|
||||
u_int64_t target_inode = 0;
|
||||
|
||||
// remove its record from parent
|
||||
INode parent_INode;
|
||||
parent_INode.inode_construct(parent_inode, disk);
|
||||
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
||||
for (u_int64_t idx=0; idx<parent_INode.size; idx++) {
|
||||
read_datablock(parent_INode, idx, rw_buffer);
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-64;i+=64){
|
||||
ent.deserialize(rw_buffer+i);
|
||||
if (strcmp(ent.file_name, filename)==0) {
|
||||
target_inode = ent.inode_number;
|
||||
ent.inode_number = 0;
|
||||
ent.serialize(rw_buffer+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (target_inode) {
|
||||
write_datablock(parent_INode, idx, rw_buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove inode itself
|
||||
if (target_inode) {
|
||||
unlink_inode(target_inode);
|
||||
delete pathdup;
|
||||
return 0;
|
||||
} else {
|
||||
printf("cannot find %s in %s", filename, ParentPath);
|
||||
delete pathdup;
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -80,7 +80,7 @@ int main(int argc, char *argv[]) {
|
||||
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/";
|
||||
std::string prefix = "/pressure/No_";
|
||||
for(int i=0;i<700;i++){
|
||||
inode_numbers[i] = fsop.fischl_mkdir((prefix+std::to_string(i)).c_str(), 0);
|
||||
}
|
||||
@ -88,4 +88,18 @@ int main(int argc, char *argv[]) {
|
||||
u_int64_t inode_number = fsop.namei((prefix+std::to_string(i)).c_str());
|
||||
assert(inode_number == inode_numbers[i]);
|
||||
}
|
||||
|
||||
printf("=== Part 6: unlink test ===\n");
|
||||
fsop.printDirectory(file_pressure);
|
||||
for(int i=0;i<700;i+=2){
|
||||
assert(!fsop.fischl_unlink((prefix+std::to_string(i)).c_str()));
|
||||
}
|
||||
for(int i=0;i<4;i+=2){
|
||||
assert(fsop.namei((prefix+std::to_string(i)).c_str())==(u_int64_t)(-1));
|
||||
}
|
||||
for(int i=1;i<700;i+=2){
|
||||
u_int64_t inode_number = fsop.namei((prefix+std::to_string(i)).c_str());
|
||||
assert(inode_number == inode_numbers[i]);
|
||||
}
|
||||
fsop.printDirectory(file_pressure);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user