[wip] add temporary rm command
This commit is contained in:
parent
685f9fa5cb
commit
be85470929
1
inc/fs.h
1
inc/fs.h
|
@ -49,5 +49,6 @@ int fs_use(void *d);
|
|||
int fs_mkfs(void *d);
|
||||
int fs_ls(void *d);
|
||||
int fs_la(void *d);
|
||||
int fs_rm(void *d);
|
||||
int fs_allow_write(void *d);
|
||||
int fs_prohibit_write(void *d);
|
||||
|
|
|
@ -17,6 +17,7 @@ static const struct CliCommandEntry cmd[] = {
|
|||
{"create", 1, (enum CliArgType[]) {STR}, fs_create},
|
||||
{"ls", 0, NULL, fs_ls},
|
||||
{"ln", 2, (enum CliArgType[]) {STR, STR}, fs_ln},
|
||||
{"rm", 1, (enum CliArgType[]) {STR}, fs_rm},
|
||||
|
||||
// custom commands
|
||||
{"use", 1, (enum CliArgType[]) {STR}, fs_use},
|
||||
|
|
164
src/fs.c
164
src/fs.c
|
@ -36,6 +36,11 @@ static int read_block(unsigned int block_no, void *data)
|
|||
|
||||
static int write_block(unsigned int block_no, void *data)
|
||||
{
|
||||
if (!write_permitted) {
|
||||
pr_err("write operations are prohibited\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lseek(used_file_fd, block_no * FS_BLOCK_SIZE, SEEK_SET) < 0) {
|
||||
pr_err("failed to seek to block %d (bs=%d) on device '%s'\n", block_no, FS_BLOCK_SIZE, used_file_path);
|
||||
return -1;
|
||||
|
@ -332,8 +337,51 @@ static int fs_find_free_directory_record(unsigned int dir_inode_ptr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int *find_filename_in_directory(unsigned int dir_inode_ptr, char *fname)
|
||||
{
|
||||
int dir_inode = read_inode_ptr(fs_cwd_inode_ptr);
|
||||
|
||||
struct fs_inode dir;
|
||||
read_block(dir_inode, (void *) &dir);
|
||||
|
||||
// list entries from base inode
|
||||
for (int i = 0; i < BLOCK_ADDRESSES_PER_INODE; i++) {
|
||||
struct fs_directory_record recs[DIRECTORY_RECORDS_PER_BLOCK];
|
||||
|
||||
if (dir.blocks[i]) {
|
||||
read_block(dir.blocks[i], (void *) &recs);
|
||||
|
||||
for (int k = 0; k < DIRECTORY_RECORDS_PER_BLOCK; k++) {
|
||||
if (!recs[k].inode_no)
|
||||
continue;
|
||||
|
||||
if (strcmp(fname, recs[k].fname))
|
||||
continue;
|
||||
|
||||
// filename found
|
||||
int *r = malloc(sizeof(int) * 2);
|
||||
r[0] = i;
|
||||
r[1] = k;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int fs_add_fname_to_directory(unsigned int dir_inode_ptr, unsigned int target_inode_ptr, char *fname)
|
||||
{
|
||||
{
|
||||
// check if duplicate filename exists in specified directory
|
||||
int *r = find_filename_in_directory(dir_inode_ptr, fname);
|
||||
if (r) {
|
||||
free(r);
|
||||
pr_err("filename '%s' already exists\n", fname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int new_directory_record_index = fs_find_free_directory_record(dir_inode_ptr);
|
||||
if (new_directory_record_index < 0) {
|
||||
pr_err("no free inode pointer found\n");
|
||||
|
@ -356,7 +404,7 @@ static int fs_add_fname_to_directory(unsigned int dir_inode_ptr, unsigned int ta
|
|||
return -1;
|
||||
} else {
|
||||
pr("Allocated new physical block %d for inode_ptr=%d (inode=%d, inner_block_no=%d)\n",
|
||||
new_block, read_inode_ptr(dir_inode_ptr), block_no);
|
||||
new_block, dir_inode_ptr, read_inode_ptr(dir_inode_ptr), block_no);
|
||||
}
|
||||
|
||||
char zero_data[FS_BLOCK_SIZE] = {};
|
||||
|
@ -382,7 +430,7 @@ static int fs_add_fname_to_directory(unsigned int dir_inode_ptr, unsigned int ta
|
|||
|
||||
write_block(dir_inode.blocks[block_no], (void *) &recs);
|
||||
|
||||
pr("Written new directory record #%d for file '%s' (-> %d) in inode_ptr=%d\n",
|
||||
pr("Written new directory record #%d for file '%s' (-> inode_ptr=%d) in inode_ptr=%d\n",
|
||||
new_directory_record_index, fname, target_inode_ptr, dir_inode_ptr);
|
||||
|
||||
return 0;
|
||||
|
@ -390,18 +438,83 @@ static int fs_add_fname_to_directory(unsigned int dir_inode_ptr, unsigned int ta
|
|||
// record is located in inode extension
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// I don't remember what was this, but this function shouldn't need it
|
||||
static int fs_remove_fname_from_directory(unsigned int dir_inode_ptr, char *fname)
|
||||
{
|
||||
// find directory record with this fname
|
||||
int dir_inode = read_inode_ptr(fs_cwd_inode_ptr);
|
||||
|
||||
// write new record
|
||||
//unsigned int inode_block_no = read_inode_ptr(fs_inode_ptr);
|
||||
struct fs_inode dir;
|
||||
read_block(dir_inode, (void *) &dir);
|
||||
|
||||
// list entries from base inode
|
||||
for (int i = 0; i < BLOCK_ADDRESSES_PER_INODE; i++) {
|
||||
struct fs_directory_record recs[DIRECTORY_RECORDS_PER_BLOCK];
|
||||
|
||||
if (dir.blocks[i]) {
|
||||
read_block(dir.blocks[i], (void *) &recs);
|
||||
|
||||
for (int k = 0; k < DIRECTORY_RECORDS_PER_BLOCK; k++) {
|
||||
if (!recs[k].inode_no)
|
||||
continue;
|
||||
|
||||
if (!strcmp(fname, recs[k].fname)) {
|
||||
pr("Directory record for '%s' found in block=%d, record=%d, removing\n", fname, i, k);
|
||||
|
||||
// decrement ref_count
|
||||
struct fs_inode f;
|
||||
read_block(read_inode_ptr(recs[k].inode_no), (void *) &f);
|
||||
f.ref_count--;
|
||||
write_block(read_inode_ptr(recs[k].inode_no), (void *) &f);
|
||||
|
||||
// if it drops to zero, nullify inode_ptr pointing to this inode
|
||||
if (!f.ref_count) {
|
||||
pr("ref_count=0, clearing inode_ptr\n");
|
||||
write_inode_ptr(recs[k].inode_no, 0);
|
||||
}
|
||||
|
||||
// clear directory record inode_ptr
|
||||
recs[k].inode_no = 0;
|
||||
write_block(dir.blocks[i], (void *) &recs);
|
||||
|
||||
goto fs_remove_fname_from_directory_finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// list entries from inode extension
|
||||
// TODO
|
||||
|
||||
pr_err("no such file '%s'\n", fname);
|
||||
return -1;
|
||||
|
||||
fs_remove_fname_from_directory_finish:
|
||||
pr("Removed fname from directory record successfully\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fs_create(void *d)
|
||||
{
|
||||
if (!write_permitted) {
|
||||
pr_err("write operations are prohibited\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *fname = *((char **) d);
|
||||
int fname_len = strlen(fname);
|
||||
|
||||
{
|
||||
// check if duplicate filename exists in current directory
|
||||
int *r = find_filename_in_directory(fs_cwd_inode_ptr, fname);
|
||||
if (r) {
|
||||
free(r);
|
||||
pr_err("filename '%s' already exists\n", fname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (fname_len > 59) {
|
||||
pr_err("filename too long (%d > %d)\n", fname_len, 59);
|
||||
return 0;
|
||||
|
@ -452,7 +565,8 @@ int fs_create(void *d)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fs_ln(void *d) {
|
||||
int fs_ln(void *d)
|
||||
{
|
||||
if (used_file_fd <= 0) {
|
||||
pr_err("no storage device\n");
|
||||
return 0;
|
||||
|
@ -462,6 +576,17 @@ int fs_ln(void *d) {
|
|||
char *new_fname = ((char **)d)[1];
|
||||
int new_fname_len = strlen(new_fname);
|
||||
|
||||
{
|
||||
// check if duplicate filename exists in current directory
|
||||
int *r = find_filename_in_directory(fs_cwd_inode_ptr, new_fname);
|
||||
if (r) {
|
||||
free(r);
|
||||
pr_err("filename '%s' already exists\n", new_fname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (new_fname_len > 59) {
|
||||
pr_err("new filename too long (%d > 59)\n", new_fname_len);
|
||||
return 0;
|
||||
|
@ -496,6 +621,9 @@ int fs_ln(void *d) {
|
|||
}
|
||||
}
|
||||
|
||||
// list entries from inode extensions
|
||||
// TODO
|
||||
|
||||
pr_err("no such file '%d'\n", existing_fname);
|
||||
return 0;
|
||||
|
||||
|
@ -519,7 +647,26 @@ original_inode_ptr_found:
|
|||
pr("Updated inode ref_count (%d -> %d)\n", f.ref_count-1, f.ref_count);
|
||||
}
|
||||
|
||||
int fs_ls(void *d) {
|
||||
int fs_rm(void *d)
|
||||
{
|
||||
if (!write_permitted) {
|
||||
pr_err("device '%s' is write-protected\n", used_file_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *fname = *((char **) d);
|
||||
|
||||
if (fs_remove_fname_from_directory(fs_cwd_inode_ptr, fname) < 0) {
|
||||
pr_err("failed to unlink '%s'\n", fname);
|
||||
} else {
|
||||
pr("Unlinked '%s'\n", fname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fs_ls(void *d)
|
||||
{
|
||||
if (used_file_fd <= 0) {
|
||||
pr_err("no storage device\n");
|
||||
return 0;
|
||||
|
@ -552,7 +699,8 @@ int fs_ls(void *d) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fs_la(void *d) {
|
||||
int fs_la(void *d)
|
||||
{
|
||||
if (used_file_fd <= 0) {
|
||||
pr_err("no storage device\n");
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue