Compare commits
2 Commits
main
...
adaptive_n
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f05cf635da | ||
![]() |
26b44b20ba |
@ -24,6 +24,7 @@ public:
|
||||
void unlink_inode(u_int64_t inode_number);
|
||||
u_int64_t disk_namei(const char* path);
|
||||
u_int64_t namei(const char* path);
|
||||
bool dir_empty(u_int64_t inode_number);
|
||||
int fischl_mkdir(const char*, mode_t);
|
||||
int fischl_mknod(const char*, mode_t, dev_t);//for special file
|
||||
int fischl_access(const char* path, int mask);
|
||||
|
@ -12,7 +12,7 @@ class DatablockOperation;
|
||||
|
||||
class Fs {
|
||||
public:
|
||||
Fs(RawDisk *disk);
|
||||
Fs(RawDisk *disk, bool load, u_int64_t user_inode_blocks = 0);
|
||||
~Fs();
|
||||
|
||||
ssize_t read(INode_Data *inode_data, char buf[], size_t count, size_t offset);
|
||||
@ -35,6 +35,8 @@ public:
|
||||
|
||||
int save_free_list_head(u_int64_t new_free_list_head);
|
||||
int save_inode_list_head(u_int64_t new_inode_list_head);
|
||||
void update_num_used_inodes(int delta);
|
||||
void update_num_used_datablocks(int delta);
|
||||
|
||||
int sweep_inode_datablocks(INode_Data *inode_data,
|
||||
u_int64_t start_block_index, bool allocate,
|
||||
|
@ -15,6 +15,10 @@ class SuperBlock_Data {
|
||||
public:
|
||||
u_int64_t free_list_head;
|
||||
u_int64_t inode_list_head;
|
||||
u_int64_t num_inode_blocks;
|
||||
u_int64_t num_used_inodes;
|
||||
u_int64_t num_data_blocks;
|
||||
u_int64_t num_used_data_blocks;
|
||||
SuperBlock_Data();
|
||||
void serialize(char buf[]);
|
||||
void deserialize(char buf[]);
|
||||
|
@ -501,6 +501,25 @@ int FilesOperation::fischl_readdir(const char *path, void *buf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FilesOperation::dir_empty(u_int64_t inode_number) {
|
||||
INode_Data inode;
|
||||
inode.inode_num = inode_number;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
for (u_int64_t idx = 0; idx < inode.metadata.size / IO_BLOCK_SIZE; idx++) {
|
||||
fs->read(&inode, buffer, IO_BLOCK_SIZE, idx * IO_BLOCK_SIZE);
|
||||
DirectoryEntry ent;
|
||||
for (int i = 0; i <= IO_BLOCK_SIZE - 264; i += 264) {
|
||||
ent.deserialize(buffer + i);
|
||||
if (ent.inode_number && strcmp(ent.file_name, ".") &&
|
||||
strcmp(ent.file_name, "..")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int FilesOperation::fischl_releasedir(const char *path,
|
||||
struct fuse_file_info *fi) {
|
||||
if (fischl_load_entry(root_node, path) == NULL)
|
||||
@ -559,6 +578,16 @@ int FilesOperation::fischl_opendir(const char *path,
|
||||
}
|
||||
|
||||
int FilesOperation::fischl_rmdir(const char *path) {
|
||||
u_int64_t fh = namei(path);
|
||||
if (fh == -1) {
|
||||
return -ENOENT;
|
||||
}
|
||||
printf("in rmdir\n");
|
||||
if(!dir_empty(fh)){
|
||||
return -ENOTEMPTY;
|
||||
}
|
||||
printf("rmdir: not empty\n");
|
||||
|
||||
char *pathdup = strdup(path);
|
||||
char *lastSlash = strrchr(pathdup, '/');
|
||||
*lastSlash = '\0';
|
||||
@ -1324,10 +1353,11 @@ int FilesOperation::fischl_utimens(const char *path,
|
||||
|
||||
int FilesOperation::fischl_statfs(const char *path, struct statvfs *stbuf) {
|
||||
stbuf->f_bsize = 4096;
|
||||
stbuf->f_blocks = 0;
|
||||
stbuf->f_bfree = 0;
|
||||
stbuf->f_files = 0;
|
||||
stbuf->f_ffree = 0;
|
||||
stbuf->f_frsize = IO_BLOCK_SIZE;
|
||||
stbuf->f_blocks = fs->superblock.num_data_blocks;
|
||||
stbuf->f_bfree = fs->superblock.num_data_blocks - fs->superblock.num_used_data_blocks;
|
||||
stbuf->f_files = fs->superblock.num_inode_blocks * 8;
|
||||
stbuf->f_ffree = fs->superblock.num_inode_blocks * 8 - fs->superblock.num_used_inodes;
|
||||
stbuf->f_namemax = 256;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -226,8 +226,21 @@ int fischl(int argc, char *argv[])
|
||||
printf("WRONG l/n ARGUMENTS\n");
|
||||
return 0;
|
||||
}
|
||||
options.fs = new Fs(options.H);
|
||||
if(!options.load){
|
||||
if(options.load){
|
||||
options.fs = new Fs(options.H, true);
|
||||
}
|
||||
else{
|
||||
uint64_t total_blocks = options.H->diskSize / IO_BLOCK_SIZE;
|
||||
uint64_t max_inode_blocks = options.H->diskSize / IO_BLOCK_SIZE - 2 - DATABLOCKS_PER_BITMAP_BLOCK;
|
||||
printf("The block device contains %llu blocks\n", total_blocks);
|
||||
printf("Choose the number of blocks to store inodes: 1 ~ %llu\n", max_inode_blocks);
|
||||
uint64_t user_inode_blocks;
|
||||
scanf("%llu", &user_inode_blocks);
|
||||
if (user_inode_blocks < 1 || user_inode_blocks > max_inode_blocks) {
|
||||
printf("Invalid number of blocks to store inodes\n");
|
||||
return -1;
|
||||
}
|
||||
options.fs = new Fs(options.H, false, user_inode_blocks);
|
||||
printf("FORMAT %d\n", options.fs->format());
|
||||
}
|
||||
options.fsop = new FilesOperation(*options.H, options.fs);
|
||||
@ -311,4 +324,4 @@ int fischl(int argc, char *argv[])
|
||||
ret = fuse_main(args.argc, args.argv, &fischl_oper, NULL);
|
||||
fuse_opt_free_args(&args);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) {
|
||||
return err;
|
||||
|
||||
(*block_num) = block_num_;
|
||||
fs->update_num_used_datablocks(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -119,6 +121,7 @@ int DataBlock_Manager_Bitmap::free_datablock(u_int64_t block_num) {
|
||||
if ((err = fs->save_free_list_head(bitmap_block_num)) < 0)
|
||||
return err;
|
||||
|
||||
fs->update_num_used_datablocks(-1);
|
||||
return 0;
|
||||
|
||||
// placing almost full bitmaps back at start of freelist is slow
|
||||
|
@ -1,13 +1,25 @@
|
||||
#include "fs.hpp"
|
||||
#include <assert.h>
|
||||
|
||||
Fs::Fs(RawDisk *disk) : disk(disk) {
|
||||
assert((disk->diskSize / IO_BLOCK_SIZE) >
|
||||
2 + NUM_INODE_BLOCKS + DATABLOCKS_PER_BITMAP_BLOCK);
|
||||
Fs::Fs(RawDisk *disk, bool load, uint64_t user_inode_blocks) : disk(disk) {
|
||||
superblock = SuperBlock_Data();
|
||||
inode_manager = new INode_Manager_Freelist(this, 1, 1 + NUM_INODE_BLOCKS);
|
||||
// Determine the num inode blocks
|
||||
uint64_t num_inode_blocks = 0; // The superblock is not loaded from disk here; it is done in FilesOperation::initialize called by fischl_init
|
||||
if(load) {
|
||||
load_superblock();
|
||||
num_inode_blocks = superblock.num_inode_blocks;
|
||||
} else {
|
||||
num_inode_blocks = user_inode_blocks;
|
||||
superblock.num_inode_blocks = num_inode_blocks;
|
||||
superblock.num_used_inodes = 0;
|
||||
superblock.num_data_blocks = disk->diskSize / IO_BLOCK_SIZE - 1 - num_inode_blocks;
|
||||
superblock.num_used_data_blocks = 0;
|
||||
}
|
||||
assert((disk->diskSize / IO_BLOCK_SIZE) >
|
||||
2 + num_inode_blocks + DATABLOCKS_PER_BITMAP_BLOCK);
|
||||
inode_manager = new INode_Manager_Freelist(this, 1, 1 + num_inode_blocks);
|
||||
datablock_manager = new DataBlock_Manager_Bitmap(
|
||||
this, 1 + NUM_INODE_BLOCKS, disk->diskSize / IO_BLOCK_SIZE);
|
||||
this, 1 + num_inode_blocks, disk->diskSize / IO_BLOCK_SIZE);
|
||||
};
|
||||
|
||||
Fs::~Fs() {
|
||||
@ -68,4 +80,12 @@ int Fs::save_inode_list_head(u_int64_t new_inode_list_head) {
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Fs::update_num_used_inodes(int delta) {
|
||||
superblock.num_used_inodes += delta;
|
||||
}
|
||||
|
||||
void Fs::update_num_used_datablocks(int delta) {
|
||||
superblock.num_used_data_blocks += delta;
|
||||
}
|
@ -36,18 +36,27 @@ size_t read_u32(u_int32_t *num, char buf[]) {
|
||||
SuperBlock_Data::SuperBlock_Data() {
|
||||
free_list_head = 0;
|
||||
inode_list_head = 0;
|
||||
num_inode_blocks = 0;
|
||||
}
|
||||
|
||||
void SuperBlock_Data::serialize(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += write_u64(free_list_head, &buf[i]);
|
||||
i += write_u64(inode_list_head, &buf[i]);
|
||||
i += write_u64(num_inode_blocks, &buf[i]);
|
||||
i += write_u64(num_used_inodes, &buf[i]);
|
||||
i += write_u64(num_data_blocks, &buf[i]);
|
||||
i += write_u64(num_used_data_blocks, &buf[i]);
|
||||
}
|
||||
|
||||
void SuperBlock_Data::deserialize(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += read_u64(&free_list_head, &buf[i]);
|
||||
i += read_u64(&inode_list_head, &buf[i]);
|
||||
i += read_u64(&num_inode_blocks, &buf[i]);
|
||||
i += read_u64(&num_used_inodes, &buf[i]);
|
||||
i += read_u64(&num_data_blocks, &buf[i]);
|
||||
i += read_u64(&num_used_data_blocks, &buf[i]);
|
||||
}
|
||||
|
||||
INode_Data::INode_Data(u_int64_t inode_num) : inode_num(inode_num) {
|
||||
|
@ -88,6 +88,7 @@ int INode_Manager_Freelist::new_inode(u_int64_t uid, u_int64_t gid,
|
||||
inode_data->inode_num = 0xFFFFFFFFFFFFFFFF;
|
||||
return err;
|
||||
}
|
||||
fs->update_num_used_inodes(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -111,6 +112,7 @@ int INode_Manager_Freelist::free_inode(INode_Data *inode_data) {
|
||||
|
||||
if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0)
|
||||
return err;
|
||||
fs->update_num_used_inodes(-1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user