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_read(void *d);
|
||||||
int fs_write(void *d);
|
int fs_write(void *d);
|
||||||
int fs_close(void *d);
|
int fs_close(void *d);
|
||||||
|
int fs_truncate(void *d);
|
||||||
int fs_allow_write(void *d);
|
int fs_allow_write(void *d);
|
||||||
int fs_prohibit_write(void *d);
|
int fs_prohibit_write(void *d);
|
||||||
|
|
|
@ -19,7 +19,7 @@ static const struct CliCommandEntry cmd[] = {
|
||||||
{"ls", 0, NULL, fs_ls},
|
{"ls", 0, NULL, fs_ls},
|
||||||
{"ln", 2, (enum CliArgType[]) {STR, STR}, fs_ln},
|
{"ln", 2, (enum CliArgType[]) {STR, STR}, fs_ln},
|
||||||
{"rm", 1, (enum CliArgType[]) {STR}, fs_rm},
|
{"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},
|
{"open", 1, (enum CliArgType[]) {STR}, fs_open},
|
||||||
{"seek", 2, (enum CliArgType[]) {INT, INT}, fs_seek},
|
{"seek", 2, (enum CliArgType[]) {INT, INT}, fs_seek},
|
||||||
{"read", 2, (enum CliArgType[]) {INT, INT}, fs_read},
|
{"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;
|
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 fs_close(void *d)
|
||||||
{
|
{
|
||||||
int fd = *((int *) d);
|
int fd = *((int *) d);
|
||||||
|
|
Loading…
Reference in New Issue