diff --git a/src/fs.c b/src/fs.c index 894653f..bb1e615 100644 --- a/src/fs.c +++ b/src/fs.c @@ -19,8 +19,6 @@ static int used_file_fd; static int write_permitted; 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; @@ -51,8 +49,11 @@ static int write_block(unsigned int block_no, void *data) static void mark_used(unsigned int block_no) { - if (block_no > fsh_cache.block_count) { - pr_err("block %d is out of filesystem block range (%d)\n", block_no, fsh_cache.block_count); + struct fs_header fsh; + 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; } @@ -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_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_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", 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) { - if (block_no > fsh_cache.block_count) { - pr_err("block %d is out of fimesystem block range (%d)\n", block_no, fsh_cache.block_count); + struct fs_header fsh; + 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; } @@ -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_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_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", 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; - int blocks_used_for_bitmap = fsh_cache.block_count / (FS_BLOCK_SIZE * 8); - if (fsh_cache.block_count % (FS_BLOCK_SIZE * 8)) + struct fs_header fsh; + 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++; 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++) { - if (!(~(fs_bitmap_cache[i*FS_BLOCK_SIZE + j]))) { + if (!(~(bitmap_block[j]))) { b += 8; } else { 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; } } @@ -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 + struct fs_header fsh; + read_block(0, (void *) &fsh); + // search fs_header for ( ; i < BLOCK_ADDRESSES_PER_INODE; i++) { - if (fsh_cache.inode_ptrs[i] == 0) { - if (i < fsh_cache.max_inode_count) { + if (fsh.inode_ptrs[i] == 0) { + if (i < fsh.max_inode_count) { return i; } else { return 0; @@ -161,7 +180,7 @@ static unsigned int find_free_inode_ptr(void) // search fs_header_extensions struct fs_header_extension ext; - unsigned int next_extension = fsh_cache.next_extension; + unsigned int next_extension = fsh.next_extension; while (next_extension) { 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++) { if (ext.inode_ptrs[j] == 0) { - if (i < fsh_cache.max_inode_count) { + if (i < fsh.max_inode_count) { return i; } else { 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; } else { return 0; @@ -303,8 +322,11 @@ static struct fs_directory_record *fs_read_dir(unsigned int fs_inode_ptr) return NULL; } - struct fs_directory_record *recs = malloc(fsh_cache.max_inode_count * sizeof(struct fs_directory_record)); - memset(recs, 0, fsh_cache.max_inode_count * sizeof(struct fs_directory_record)); + struct fs_header fsh; + 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 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; } - 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) { free(recs); return i; @@ -784,50 +809,6 @@ int fs_use(void *d) } 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 = "/"; fs_chdir((void *) &root_dir_path); @@ -892,12 +873,6 @@ int fs_mkfs(void *d) 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; unsigned char bitmap_block[FS_BLOCK_SIZE]; @@ -929,9 +904,6 @@ finish_current_block: } else { 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 write_inode_ptr(0, free_block_index); - // update fsh cache - memcpy(&fsh_cache, &fsh, FS_BLOCK_SIZE); - char *root_dir_path = "/"; fs_chdir((void *) &root_dir_path);