Compare commits
No commits in common. "447a1448adce8fd6be49b2579530b4fc20aac075" and "685f9fa5cbbe2c8846e077d88f40dd0d53dc28cb" have entirely different histories.
447a1448ad
...
685f9fa5cb
1
inc/fs.h
1
inc/fs.h
@ -49,6 +49,5 @@ int fs_use(void *d);
|
|||||||
int fs_mkfs(void *d);
|
int fs_mkfs(void *d);
|
||||||
int fs_ls(void *d);
|
int fs_ls(void *d);
|
||||||
int fs_la(void *d);
|
int fs_la(void *d);
|
||||||
int fs_rm(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);
|
||||||
|
@ -17,7 +17,6 @@ static const struct CliCommandEntry cmd[] = {
|
|||||||
{"create", 1, (enum CliArgType[]) {STR}, fs_create},
|
{"create", 1, (enum CliArgType[]) {STR}, fs_create},
|
||||||
{"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},
|
|
||||||
|
|
||||||
// custom commands
|
// custom commands
|
||||||
{"use", 1, (enum CliArgType[]) {STR}, fs_use},
|
{"use", 1, (enum CliArgType[]) {STR}, fs_use},
|
||||||
|
289
src/fs.c
289
src/fs.c
@ -19,6 +19,8 @@ static int used_file_fd;
|
|||||||
static int write_permitted;
|
static int write_permitted;
|
||||||
|
|
||||||
static char fs_cwd[FS_MAX_PATH_LEN+1];
|
static char fs_cwd[FS_MAX_PATH_LEN+1];
|
||||||
|
static struct fs_header fsh_cache;
|
||||||
|
static char fs_bitmap_cache[FS_BLOCK_SIZE * FS_MAX_BITMAP_SIZE];
|
||||||
static unsigned int fs_cwd_inode_ptr;
|
static unsigned int fs_cwd_inode_ptr;
|
||||||
|
|
||||||
|
|
||||||
@ -34,11 +36,6 @@ static int read_block(unsigned int block_no, void *data)
|
|||||||
|
|
||||||
static int write_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) {
|
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);
|
pr_err("failed to seek to block %d (bs=%d) on device '%s'\n", block_no, FS_BLOCK_SIZE, used_file_path);
|
||||||
return -1;
|
return -1;
|
||||||
@ -49,11 +46,8 @@ static int write_block(unsigned int block_no, void *data)
|
|||||||
|
|
||||||
static void mark_used(unsigned int block_no)
|
static void mark_used(unsigned int block_no)
|
||||||
{
|
{
|
||||||
struct fs_header fsh;
|
if (block_no > fsh_cache.block_count) {
|
||||||
read_block(0, (void *) &fsh);
|
pr_err("block %d is out of filesystem block range (%d)\n", block_no, fsh_cache.block_count);
|
||||||
|
|
||||||
if (block_no > fsh.block_count) {
|
|
||||||
pr_err("block %d is out of filesystem block range (%d)\n", block_no, fsh.block_count);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,13 +55,10 @@ static void mark_used(unsigned int block_no)
|
|||||||
unsigned int bitmap_block_offset = (block_no >> 3) % FS_BLOCK_SIZE;
|
unsigned int bitmap_block_offset = (block_no >> 3) % FS_BLOCK_SIZE;
|
||||||
unsigned int bitmap_block_index = (block_no >> 3) / FS_BLOCK_SIZE;
|
unsigned int bitmap_block_index = (block_no >> 3) / FS_BLOCK_SIZE;
|
||||||
|
|
||||||
unsigned char bitmap_block[FS_BLOCK_SIZE];
|
fs_bitmap_cache[bitmap_block_index * FS_BLOCK_SIZE + bitmap_block_offset] |= bitmap_bit;
|
||||||
read_block(bitmap_block_index+1, (void *) bitmap_block);
|
|
||||||
|
|
||||||
bitmap_block[bitmap_block_offset] |= bitmap_bit;
|
|
||||||
|
|
||||||
// write changes to device
|
// write changes to device
|
||||||
write_block(bitmap_block_index+1, (void *) &bitmap_block);
|
write_block(bitmap_block_index+1, (void *) &(fs_bitmap_cache[bitmap_block_index*FS_BLOCK_SIZE]));
|
||||||
|
|
||||||
pr("Marked block_no=%d (block=%d, offset=%d, bit=%d) as used\n",
|
pr("Marked block_no=%d (block=%d, offset=%d, bit=%d) as used\n",
|
||||||
block_no, bitmap_block_index, bitmap_block_offset, block_no & 0x7);
|
block_no, bitmap_block_index, bitmap_block_offset, block_no & 0x7);
|
||||||
@ -75,11 +66,8 @@ static void mark_used(unsigned int block_no)
|
|||||||
|
|
||||||
static void mark_free(unsigned int block_no)
|
static void mark_free(unsigned int block_no)
|
||||||
{
|
{
|
||||||
struct fs_header fsh;
|
if (block_no > fsh_cache.block_count) {
|
||||||
read_block(0, (void *) &fsh);
|
pr_err("block %d is out of fimesystem block range (%d)\n", block_no, fsh_cache.block_count);
|
||||||
|
|
||||||
if (block_no > fsh.block_count) {
|
|
||||||
pr_err("block %d is out of fimesystem block range (%d)\n", block_no, fsh.block_count);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,13 +75,10 @@ static void mark_free(unsigned int block_no)
|
|||||||
unsigned int bitmap_block_offset = (block_no >> 3) % FS_BLOCK_SIZE;
|
unsigned int bitmap_block_offset = (block_no >> 3) % FS_BLOCK_SIZE;
|
||||||
unsigned int bitmap_block_index = (block_no >> 3) / FS_BLOCK_SIZE;
|
unsigned int bitmap_block_index = (block_no >> 3) / FS_BLOCK_SIZE;
|
||||||
|
|
||||||
unsigned char bitmap_block[FS_BLOCK_SIZE];
|
fs_bitmap_cache[bitmap_block_index * FS_BLOCK_SIZE + bitmap_block_offset] &= ~bitmap_bit;
|
||||||
read_block(bitmap_block_index+1, (void *) bitmap_block);
|
|
||||||
|
|
||||||
bitmap_block[bitmap_block_offset] &= ~bitmap_bit;
|
|
||||||
|
|
||||||
// write changes to device
|
// write changes to device
|
||||||
write_block(bitmap_block_index+1, (void *) bitmap_block);
|
write_block(bitmap_block_index+1, (void *) &(fs_bitmap_cache[bitmap_block_index*FS_BLOCK_SIZE]));
|
||||||
|
|
||||||
pr("Marked block_no=%d (block=%d, offset=%d, bit=%d) as free\n",
|
pr("Marked block_no=%d (block=%d, offset=%d, bit=%d) as free\n",
|
||||||
block_no, bitmap_block_index, bitmap_block_offset, bitmap_bit);
|
block_no, bitmap_block_index, bitmap_block_offset, bitmap_bit);
|
||||||
@ -133,23 +118,17 @@ static unsigned int find_free_block(void)
|
|||||||
{
|
{
|
||||||
unsigned int b = 0;
|
unsigned int b = 0;
|
||||||
|
|
||||||
struct fs_header fsh;
|
int blocks_used_for_bitmap = fsh_cache.block_count / (FS_BLOCK_SIZE * 8);
|
||||||
read_block(0, (void *) &fsh);
|
if (fsh_cache.block_count % (FS_BLOCK_SIZE * 8))
|
||||||
|
|
||||||
int blocks_used_for_bitmap = fsh.block_count / (FS_BLOCK_SIZE * 8);
|
|
||||||
if (fsh.block_count % (FS_BLOCK_SIZE * 8))
|
|
||||||
blocks_used_for_bitmap++;
|
blocks_used_for_bitmap++;
|
||||||
|
|
||||||
for (int i = 0; i < blocks_used_for_bitmap; i++) {
|
for (int i = 0; i < blocks_used_for_bitmap; i++) {
|
||||||
unsigned char bitmap_block[FS_BLOCK_SIZE];
|
|
||||||
read_block(i+1, (void *) bitmap_block);
|
|
||||||
|
|
||||||
for (int j = 0; j < FS_BLOCK_SIZE; j++) {
|
for (int j = 0; j < FS_BLOCK_SIZE; j++) {
|
||||||
if (!(~(bitmap_block[j]))) {
|
if (!(~(fs_bitmap_cache[i*FS_BLOCK_SIZE + j]))) {
|
||||||
b += 8;
|
b += 8;
|
||||||
} else {
|
} else {
|
||||||
for (int k = 0; k < 8; k++, b++) {
|
for (int k = 0; k < 8; k++, b++) {
|
||||||
if (!((bitmap_block[j]) & (1 << k))) {
|
if (!((fs_bitmap_cache[i*FS_BLOCK_SIZE + j]) & (1 << k))) {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,13 +143,10 @@ static unsigned int find_free_inode_ptr(void)
|
|||||||
{
|
{
|
||||||
unsigned int i = 1; // inode0 always points to root dir, so can't be free
|
unsigned int i = 1; // inode0 always points to root dir, so can't be free
|
||||||
|
|
||||||
struct fs_header fsh;
|
|
||||||
read_block(0, (void *) &fsh);
|
|
||||||
|
|
||||||
// search fs_header
|
// search fs_header
|
||||||
for ( ; i < BLOCK_ADDRESSES_PER_INODE; i++) {
|
for ( ; i < BLOCK_ADDRESSES_PER_INODE; i++) {
|
||||||
if (fsh.inode_ptrs[i] == 0) {
|
if (fsh_cache.inode_ptrs[i] == 0) {
|
||||||
if (i < fsh.max_inode_count) {
|
if (i < fsh_cache.max_inode_count) {
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -180,7 +156,7 @@ static unsigned int find_free_inode_ptr(void)
|
|||||||
|
|
||||||
// search fs_header_extensions
|
// search fs_header_extensions
|
||||||
struct fs_header_extension ext;
|
struct fs_header_extension ext;
|
||||||
unsigned int next_extension = fsh.next_extension;
|
unsigned int next_extension = fsh_cache.next_extension;
|
||||||
|
|
||||||
while (next_extension) {
|
while (next_extension) {
|
||||||
read_block(next_extension, (void *) &ext);
|
read_block(next_extension, (void *) &ext);
|
||||||
@ -188,7 +164,7 @@ static unsigned int find_free_inode_ptr(void)
|
|||||||
|
|
||||||
for (int j = 0; j < BLOCK_ADDRESSES_PER_INODE_EXTENSION; j++, i++) {
|
for (int j = 0; j < BLOCK_ADDRESSES_PER_INODE_EXTENSION; j++, i++) {
|
||||||
if (ext.inode_ptrs[j] == 0) {
|
if (ext.inode_ptrs[j] == 0) {
|
||||||
if (i < fsh.max_inode_count) {
|
if (i < fsh_cache.max_inode_count) {
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -197,7 +173,7 @@ static unsigned int find_free_inode_ptr(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < fsh.max_inode_count) {
|
if (i < fsh_cache.max_inode_count) {
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -322,11 +298,8 @@ static struct fs_directory_record *fs_read_dir(unsigned int fs_inode_ptr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fs_header fsh;
|
struct fs_directory_record *recs = malloc(fsh_cache.max_inode_count * sizeof(struct fs_directory_record));
|
||||||
read_block(0, (void *) &fsh);
|
memset(recs, 0, fsh_cache.max_inode_count * sizeof(struct fs_directory_record));
|
||||||
|
|
||||||
struct fs_directory_record *recs = malloc(fsh.max_inode_count * sizeof(struct fs_directory_record));
|
|
||||||
memset(recs, 0, fsh.max_inode_count * sizeof(struct fs_directory_record));
|
|
||||||
|
|
||||||
// read block portion from dir_inode
|
// read block portion from dir_inode
|
||||||
for (int i = 0; (i*DIRECTORY_RECORDS_PER_BLOCK < dir_inode.size) && (i < BLOCK_ADDRESSES_PER_INODE); i++) {
|
for (int i = 0; (i*DIRECTORY_RECORDS_PER_BLOCK < dir_inode.size) && (i < BLOCK_ADDRESSES_PER_INODE); i++) {
|
||||||
@ -348,10 +321,7 @@ static int fs_find_free_directory_record(unsigned int dir_inode_ptr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fs_header fsh;
|
for (unsigned int i = 0; i < fsh_cache.max_inode_count; i++) {
|
||||||
read_block(0, (void *) &fsh);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < fsh.max_inode_count; i++) {
|
|
||||||
if (!recs[i].inode_no) {
|
if (!recs[i].inode_no) {
|
||||||
free(recs);
|
free(recs);
|
||||||
return i;
|
return i;
|
||||||
@ -362,51 +332,8 @@ static int fs_find_free_directory_record(unsigned int dir_inode_ptr)
|
|||||||
return -1;
|
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)
|
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);
|
int new_directory_record_index = fs_find_free_directory_record(dir_inode_ptr);
|
||||||
if (new_directory_record_index < 0) {
|
if (new_directory_record_index < 0) {
|
||||||
pr_err("no free inode pointer found\n");
|
pr_err("no free inode pointer found\n");
|
||||||
@ -429,7 +356,7 @@ static int fs_add_fname_to_directory(unsigned int dir_inode_ptr, unsigned int ta
|
|||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
pr("Allocated new physical block %d for inode_ptr=%d (inode=%d, inner_block_no=%d)\n",
|
pr("Allocated new physical block %d for inode_ptr=%d (inode=%d, inner_block_no=%d)\n",
|
||||||
new_block, dir_inode_ptr, read_inode_ptr(dir_inode_ptr), block_no);
|
new_block, read_inode_ptr(dir_inode_ptr), block_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
char zero_data[FS_BLOCK_SIZE] = {};
|
char zero_data[FS_BLOCK_SIZE] = {};
|
||||||
@ -455,7 +382,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);
|
write_block(dir_inode.blocks[block_no], (void *) &recs);
|
||||||
|
|
||||||
pr("Written new directory record #%d for file '%s' (-> inode_ptr=%d) in inode_ptr=%d\n",
|
pr("Written new directory record #%d for file '%s' (-> %d) in inode_ptr=%d\n",
|
||||||
new_directory_record_index, fname, target_inode_ptr, dir_inode_ptr);
|
new_directory_record_index, fname, target_inode_ptr, dir_inode_ptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -463,83 +390,18 @@ static int fs_add_fname_to_directory(unsigned int dir_inode_ptr, unsigned int ta
|
|||||||
// record is located in inode extension
|
// record is located in inode extension
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static int fs_remove_fname_from_directory(unsigned int dir_inode_ptr, char *fname)
|
// I don't remember what was this, but this function shouldn't need it
|
||||||
{
|
|
||||||
// find directory record with this fname
|
|
||||||
int dir_inode = read_inode_ptr(fs_cwd_inode_ptr);
|
|
||||||
|
|
||||||
struct fs_inode dir;
|
// write new record
|
||||||
read_block(dir_inode, (void *) &dir);
|
//unsigned int inode_block_no = read_inode_ptr(fs_inode_ptr);
|
||||||
|
|
||||||
// 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)
|
int fs_create(void *d)
|
||||||
{
|
{
|
||||||
if (!write_permitted) {
|
|
||||||
pr_err("write operations are prohibited\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *fname = *((char **) d);
|
char *fname = *((char **) d);
|
||||||
int fname_len = strlen(fname);
|
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) {
|
if (fname_len > 59) {
|
||||||
pr_err("filename too long (%d > %d)\n", fname_len, 59);
|
pr_err("filename too long (%d > %d)\n", fname_len, 59);
|
||||||
return 0;
|
return 0;
|
||||||
@ -590,8 +452,7 @@ int fs_create(void *d)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_ln(void *d)
|
int fs_ln(void *d) {
|
||||||
{
|
|
||||||
if (used_file_fd <= 0) {
|
if (used_file_fd <= 0) {
|
||||||
pr_err("no storage device\n");
|
pr_err("no storage device\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -601,17 +462,6 @@ int fs_ln(void *d)
|
|||||||
char *new_fname = ((char **)d)[1];
|
char *new_fname = ((char **)d)[1];
|
||||||
int new_fname_len = strlen(new_fname);
|
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) {
|
if (new_fname_len > 59) {
|
||||||
pr_err("new filename too long (%d > 59)\n", new_fname_len);
|
pr_err("new filename too long (%d > 59)\n", new_fname_len);
|
||||||
return 0;
|
return 0;
|
||||||
@ -646,9 +496,6 @@ int fs_ln(void *d)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// list entries from inode extensions
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
pr_err("no such file '%d'\n", existing_fname);
|
pr_err("no such file '%d'\n", existing_fname);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -672,26 +519,7 @@ original_inode_ptr_found:
|
|||||||
pr("Updated inode ref_count (%d -> %d)\n", f.ref_count-1, f.ref_count);
|
pr("Updated inode ref_count (%d -> %d)\n", f.ref_count-1, f.ref_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_rm(void *d)
|
int fs_ls(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) {
|
if (used_file_fd <= 0) {
|
||||||
pr_err("no storage device\n");
|
pr_err("no storage device\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -724,8 +552,7 @@ int fs_ls(void *d)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_la(void *d)
|
int fs_la(void *d) {
|
||||||
{
|
|
||||||
if (used_file_fd <= 0) {
|
if (used_file_fd <= 0) {
|
||||||
pr_err("no storage device\n");
|
pr_err("no storage device\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -809,6 +636,50 @@ int fs_use(void *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (write_permitted) {
|
if (write_permitted) {
|
||||||
|
{
|
||||||
|
int bytes_read = read_block(0, (void *) &fsh_cache);
|
||||||
|
if (bytes_read < 0) {
|
||||||
|
pr_err("failed to cache filesystem header\n");
|
||||||
|
write_permitted = 0;
|
||||||
|
return 0;
|
||||||
|
} else if (bytes_read < FS_BLOCK_SIZE) {
|
||||||
|
pr_err("failed to read full filesystem header (read %d/%d bytes)\n", bytes_read, FS_BLOCK_SIZE);
|
||||||
|
write_permitted = 0;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
pr("Cached filesystem header\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int blocks_used_for_bitmap = fsh_cache.block_count / (FS_BLOCK_SIZE * 8);
|
||||||
|
if (fsh_cache.block_count % (FS_BLOCK_SIZE * 8))
|
||||||
|
blocks_used_for_bitmap++;
|
||||||
|
|
||||||
|
if (blocks_used_for_bitmap > FS_MAX_BITMAP_SIZE) {
|
||||||
|
pr_err("filesystem bitmap too large (%d blocks > %d)\n", blocks_used_for_bitmap, FS_MAX_BITMAP_SIZE);
|
||||||
|
write_permitted = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
for (int i = 0; i < blocks_used_for_bitmap; i++) {
|
||||||
|
int bytes_read = read_block(i+1, &(fs_bitmap_cache[FS_BLOCK_SIZE*i]));
|
||||||
|
|
||||||
|
if (bytes_read < 0) {
|
||||||
|
pr_err("failed to cache filesystem bitmap block %d/%d\n", i+1, blocks_used_for_bitmap);
|
||||||
|
write_permitted = 0;
|
||||||
|
return 0;
|
||||||
|
} else if (bytes_read < FS_BLOCK_SIZE) {
|
||||||
|
pr_err("failed to read full filesystem bitmap block %d/%d (read %d/%d bytes)\n",
|
||||||
|
i+1, blocks_used_for_bitmap, bytes_read, FS_BLOCK_SIZE);
|
||||||
|
write_permitted = 0;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
pr("Cached filesystem bitmap block %d/%d\n", i+1, blocks_used_for_bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *root_dir_path = "/";
|
char *root_dir_path = "/";
|
||||||
fs_chdir((void *) &root_dir_path);
|
fs_chdir((void *) &root_dir_path);
|
||||||
|
|
||||||
@ -873,6 +744,12 @@ int fs_mkfs(void *d)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update fsh cache
|
||||||
|
memcpy(&fsh_cache, &fsh, FS_BLOCK_SIZE);
|
||||||
|
|
||||||
|
// clear fs_bitmap_cache
|
||||||
|
memset(&fs_bitmap_cache, 0, sizeof(fs_bitmap_cache));
|
||||||
|
|
||||||
int blocks_used = 1 + blocks_used_for_bitmap;
|
int blocks_used = 1 + blocks_used_for_bitmap;
|
||||||
|
|
||||||
unsigned char bitmap_block[FS_BLOCK_SIZE];
|
unsigned char bitmap_block[FS_BLOCK_SIZE];
|
||||||
@ -904,6 +781,9 @@ finish_current_block:
|
|||||||
} else {
|
} else {
|
||||||
pr("Written bitmap block %d/%d on device '%s'\n", i+1, blocks_used_for_bitmap, used_file_path);
|
pr("Written bitmap block %d/%d on device '%s'\n", i+1, blocks_used_for_bitmap, used_file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update fs_bitmap_cache
|
||||||
|
memcpy(&(fs_bitmap_cache[FS_BLOCK_SIZE*i]), &bitmap_block, FS_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -939,6 +819,9 @@ finish_current_block:
|
|||||||
// inode0 -> root_dir_block
|
// inode0 -> root_dir_block
|
||||||
write_inode_ptr(0, free_block_index);
|
write_inode_ptr(0, free_block_index);
|
||||||
|
|
||||||
|
// update fsh cache
|
||||||
|
memcpy(&fsh_cache, &fsh, FS_BLOCK_SIZE);
|
||||||
|
|
||||||
char *root_dir_path = "/";
|
char *root_dir_path = "/";
|
||||||
fs_chdir((void *) &root_dir_path);
|
fs_chdir((void *) &root_dir_path);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user