add truncate
This commit is contained in:
parent
3b3ce23df0
commit
3ee64e5b5d
1
inc/fs.h
1
inc/fs.h
|
@ -60,5 +60,6 @@ int fs_seek(void *d);
|
|||
int fs_read(void *d);
|
||||
int fs_write(void *d);
|
||||
int fs_close(void *d);
|
||||
int fs_truncate(void *d);
|
||||
int fs_allow_write(void *d);
|
||||
int fs_prohibit_write(void *d);
|
||||
|
|
|
@ -19,7 +19,7 @@ static const struct CliCommandEntry cmd[] = {
|
|||
{"ls", 0, NULL, fs_ls},
|
||||
{"ln", 2, (enum CliArgType[]) {STR, STR}, fs_ln},
|
||||
{"rm", 1, (enum CliArgType[]) {STR}, fs_rm},
|
||||
//{"truncate", 2, (enum CliArgType[]) {STR, INT}, fs_truncate},
|
||||
{"truncate", 2, (enum CliArgType[]) {STR, INT}, fs_truncate},
|
||||
{"open", 1, (enum CliArgType[]) {STR}, fs_open},
|
||||
{"seek", 2, (enum CliArgType[]) {INT, INT}, fs_seek},
|
||||
{"read", 2, (enum CliArgType[]) {INT, INT}, fs_read},
|
||||
|
|
106
src/fs.c
106
src/fs.c
|
@ -902,6 +902,112 @@ int fs_write(void *d)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fs_truncate(void *d)
|
||||
{
|
||||
char *fname = *((char **) d);
|
||||
int size = *((int *) ((char **) d+1));
|
||||
|
||||
if (size < 0) {
|
||||
pr_err("file size can not be negative\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_inode_ptr;
|
||||
{
|
||||
int *r = find_filename_in_directory(fs_cwd_inode_ptr, fname);
|
||||
if (r == NULL) {
|
||||
pr_err("no such file: '%s'\n", fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
file_inode_ptr = r[2];
|
||||
free(r);
|
||||
}
|
||||
|
||||
struct fs_inode f;
|
||||
read_block(read_inode_ptr(file_inode_ptr), (void *) &f);
|
||||
|
||||
if (size > f.size) {
|
||||
pr("Increasing file size of '%s': %d -> %d\n", fname, f.size, size);
|
||||
f.size = size;
|
||||
write_block(read_inode_ptr(file_inode_ptr), (void *) &f);
|
||||
} else {
|
||||
pr("Decreasing file size of '%s': %d -> %d\n", fname, f.size, size);
|
||||
f.size = size;
|
||||
|
||||
// cleanup
|
||||
int new_block_amount = f.size / FS_BLOCK_SIZE;
|
||||
if (f.size % FS_BLOCK_SIZE)
|
||||
new_block_amount++;
|
||||
|
||||
int blocks_seen = 0;
|
||||
|
||||
// look through base inode blocks
|
||||
for (int i = 0; i < BLOCK_ADDRESSES_PER_INODE; i++, blocks_seen++) {
|
||||
if ((blocks_seen > new_block_amount) && (f.blocks[i])) {
|
||||
mark_free(f.blocks[i]);
|
||||
f.blocks[i] = 0;
|
||||
}
|
||||
}
|
||||
write_block(read_inode_ptr(file_inode_ptr), (void *) &f);
|
||||
|
||||
// look through inode extension blocks
|
||||
struct fs_inode_extension ext;
|
||||
unsigned int next_ext = f.next_extension;
|
||||
unsigned int curr_ext;
|
||||
|
||||
while (next_ext) {
|
||||
read_block(next_ext, (void *) &ext);
|
||||
|
||||
for (int i = 0; i < BLOCK_ADDRESSES_PER_INODE_EXTENSION; i++, blocks_seen++) {
|
||||
if ((blocks_seen > new_block_amount) && (ext.blocks[i])) {
|
||||
mark_free(ext.blocks[i]);
|
||||
ext.blocks[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
write_block(next_ext, (void *) &ext);
|
||||
next_ext = ext.next_extension;
|
||||
}
|
||||
|
||||
// look through inode extensions themselves
|
||||
int required_extensions = (f.size - BLOCK_ADDRESSES_PER_INODE) / BLOCK_ADDRESSES_PER_INODE_EXTENSION;
|
||||
if ((f.size - BLOCK_ADDRESSES_PER_INODE) % BLOCK_ADDRESSES_PER_INODE_EXTENSION)
|
||||
required_extensions++;
|
||||
|
||||
next_ext = f.next_extension;
|
||||
|
||||
if (!required_extensions) {
|
||||
// zero base inode next_extension ptr
|
||||
f.next_extension = 0;
|
||||
write_block(read_inode_ptr(file_inode_ptr), (void *) &f);
|
||||
}
|
||||
|
||||
// seek to last required extension
|
||||
for (int i = 0; i < required_extensions; i++) {
|
||||
if (!next_ext)
|
||||
return 0;
|
||||
|
||||
curr_ext = next_ext;
|
||||
read_block(next_ext, (void *) &ext);
|
||||
next_ext = ext.next_extension;
|
||||
}
|
||||
|
||||
// remove next_extension ptr
|
||||
ext.next_extension = 0;
|
||||
write_block(curr_ext, (void *) &ext);
|
||||
|
||||
// erase all extensions after this one
|
||||
while (next_ext) {
|
||||
mark_free(next_ext);
|
||||
read_block(next_ext, (void *) &ext);
|
||||
next_ext = ext.next_extension;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fs_close(void *d)
|
||||
{
|
||||
int fd = *((int *) d);
|
||||
|
|
Loading…
Reference in New Issue