remove filesystem caching

This commit is contained in:
ІО-23 Шмуляр Олег 2025-04-26 10:37:48 +03:00
parent be85470929
commit 447a1448ad
1 changed files with 47 additions and 78 deletions

125
src/fs.c
View File

@ -19,8 +19,6 @@ 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;
@ -51,8 +49,11 @@ 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)
{ {
if (block_no > fsh_cache.block_count) { struct fs_header fsh;
pr_err("block %d is out of filesystem block range (%d)\n", block_no, fsh_cache.block_count); read_block(0, (void *) &fsh);
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;
} }
@ -60,10 +61,13 @@ 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;
fs_bitmap_cache[bitmap_block_index * FS_BLOCK_SIZE + bitmap_block_offset] |= bitmap_bit; unsigned char bitmap_block[FS_BLOCK_SIZE];
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 *) &(fs_bitmap_cache[bitmap_block_index*FS_BLOCK_SIZE])); write_block(bitmap_block_index+1, (void *) &bitmap_block);
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);
@ -71,8 +75,11 @@ static void mark_used(unsigned int block_no)
static void mark_free(unsigned int block_no) static void mark_free(unsigned int block_no)
{ {
if (block_no > fsh_cache.block_count) { struct fs_header fsh;
pr_err("block %d is out of fimesystem block range (%d)\n", block_no, fsh_cache.block_count); read_block(0, (void *) &fsh);
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;
} }
@ -80,10 +87,13 @@ 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;
fs_bitmap_cache[bitmap_block_index * FS_BLOCK_SIZE + bitmap_block_offset] &= ~bitmap_bit; unsigned char bitmap_block[FS_BLOCK_SIZE];
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 *) &(fs_bitmap_cache[bitmap_block_index*FS_BLOCK_SIZE])); write_block(bitmap_block_index+1, (void *) bitmap_block);
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);
@ -123,17 +133,23 @@ static unsigned int find_free_block(void)
{ {
unsigned int b = 0; unsigned int b = 0;
int blocks_used_for_bitmap = fsh_cache.block_count / (FS_BLOCK_SIZE * 8); struct fs_header fsh;
if (fsh_cache.block_count % (FS_BLOCK_SIZE * 8)) read_block(0, (void *) &fsh);
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 (!(~(fs_bitmap_cache[i*FS_BLOCK_SIZE + j]))) { if (!(~(bitmap_block[j]))) {
b += 8; b += 8;
} else { } else {
for (int k = 0; k < 8; k++, b++) { for (int k = 0; k < 8; k++, b++) {
if (!((fs_bitmap_cache[i*FS_BLOCK_SIZE + j]) & (1 << k))) { if (!((bitmap_block[j]) & (1 << k))) {
return b; return b;
} }
} }
@ -148,10 +164,13 @@ 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_cache.inode_ptrs[i] == 0) { if (fsh.inode_ptrs[i] == 0) {
if (i < fsh_cache.max_inode_count) { if (i < fsh.max_inode_count) {
return i; return i;
} else { } else {
return 0; return 0;
@ -161,7 +180,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_cache.next_extension; unsigned int next_extension = fsh.next_extension;
while (next_extension) { while (next_extension) {
read_block(next_extension, (void *) &ext); read_block(next_extension, (void *) &ext);
@ -169,7 +188,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_cache.max_inode_count) { if (i < fsh.max_inode_count) {
return i; return i;
} else { } else {
return 0; return 0;
@ -178,7 +197,7 @@ static unsigned int find_free_inode_ptr(void)
} }
} }
if (i < fsh_cache.max_inode_count) { if (i < fsh.max_inode_count) {
return i; return i;
} else { } else {
return 0; return 0;
@ -303,8 +322,11 @@ static struct fs_directory_record *fs_read_dir(unsigned int fs_inode_ptr)
return NULL; return NULL;
} }
struct fs_directory_record *recs = malloc(fsh_cache.max_inode_count * sizeof(struct fs_directory_record)); struct fs_header fsh;
memset(recs, 0, fsh_cache.max_inode_count * sizeof(struct fs_directory_record)); read_block(0, (void *) &fsh);
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++) {
@ -326,7 +348,10 @@ static int fs_find_free_directory_record(unsigned int dir_inode_ptr)
return 0; return 0;
} }
for (unsigned int i = 0; i < fsh_cache.max_inode_count; i++) { struct fs_header fsh;
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;
@ -784,50 +809,6 @@ 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);
@ -892,12 +873,6 @@ 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];
@ -929,9 +904,6 @@ 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);
} }
} }
@ -967,9 +939,6 @@ 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);