14 #include "sfs/sha256.h"
35 printf(
"SuperBlock:\n");
38 if(block.Super.MagicNumber == MAGIC_NUMBER)
39 printf(
" magic number is valid\n");
41 printf(
" magic number is invalid\n");
42 printf(
" exiting...\n");
47 printf(
" %u blocks\n" , block.Super.
Blocks);
48 printf(
" %u inode blocks\n" , block.Super.
InodeBlocks);
49 printf(
" %u inodes\n" , block.Super.
Inodes);
54 for(uint32_t i = 1; i <= block.Super.
InodeBlocks; i++) {
56 for(uint32_t j = 0; j < INODES_PER_BLOCK; j++) {
58 if(block.
Inodes[j].Valid) {
59 printf(
"Inode %u:\n", ii);
60 printf(
" size: %u bytes\n", block.
Inodes[j].
Size);
61 printf(
" direct blocks:");
64 for(uint32_t k = 0; k < POINTERS_PER_INODE; k++) {
71 printf(
" indirect block: %u\n indirect data blocks:",block.
Inodes[j].
Indirect);
74 for(uint32_t k = 0; k < POINTERS_PER_BLOCK; k++) {
93 if(disk->
mounted())
return false;
97 memset(&block, 0,
sizeof(
Block));
99 block.Super.MagicNumber = FileSystem::MAGIC_NUMBER;
100 block.Super.
Blocks = (uint32_t)(disk->
size());
101 block.Super.
InodeBlocks = (uint32_t)std::ceil((
int(block.Super.
Blocks) * 1.00)/10);
103 block.Super.
DirBlocks = (uint32_t)std::ceil((
int(block.Super.
Blocks) * 1.00)/100);
112 for(uint32_t i = 1; i <= block.Super.
InodeBlocks; i++){
116 for(uint32_t j = 0; j < FileSystem::INODES_PER_BLOCK; j++){
117 inodeblock.
Inodes[j].Valid =
false;
121 for(uint32_t k = 0; k < FileSystem::POINTERS_PER_INODE; k++)
134 memset(DataBlock.
Data, 0, Disk::BLOCK_SIZE);
144 memset(dir.
Table,0,
sizeof(
Dirent)*ENTRIES_PER_DIR);
145 for(uint32_t j=0; j<FileSystem::DIR_PER_BLOCK; j++){
153 strcpy(root.
Name,
"/");
159 memset(&temp, 0,
sizeof(temp));
165 strcpy(temp.
Name,tstr1);
167 strcpy(temp.
Name,tstr2);
172 memcpy(&(Dirblock.
Directories[0]),&root,
sizeof(root));
184 if(disk->
mounted())
return false;
189 if(block.Super.MagicNumber != MAGIC_NUMBER)
return false;
190 if(block.Super.
InodeBlocks != std::ceil((block.Super.
Blocks*1.00)/10))
return false;
191 if(block.Super.
Inodes != (block.Super.
InodeBlocks * INODES_PER_BLOCK))
return false;
192 if(block.Super.
DirBlocks != (uint32_t)std::ceil((
int(block.Super.
Blocks) * 1.00)/100))
return false;
196 char pass[1000], line[1000];
197 printf(
"Enter password: ");
198 if (fgets(line, BUFSIZ, stdin) == NULL) {
201 sscanf(line,
"%s", pass);
204 printf(
"Disk Unlocked\n");
208 printf(
"Password Failed. Exiting...\n");
217 MetaData = block.Super;
220 free_blocks.resize(MetaData.Blocks,
false);
223 inode_counter.resize(MetaData.InodeBlocks, 0);
226 free_blocks[0] =
true;
229 for(uint32_t i = 1; i <= MetaData.InodeBlocks; i++) {
232 for(uint32_t j = 0; j < INODES_PER_BLOCK; j++) {
233 if(block.
Inodes[j].Valid) {
234 inode_counter[i-1]++;
237 if(block.
Inodes[j].Valid) free_blocks[i] =
true;
240 for(uint32_t k = 0; k < POINTERS_PER_INODE; k++) {
255 for(uint32_t k = 0; k < POINTERS_PER_BLOCK; k++) {
256 if(indirect.
Pointers[k] < MetaData.Blocks) {
257 free_blocks[indirect.
Pointers[k]] =
true;
270 dir_counter.resize(MetaData.DirBlocks,0);
273 for(uint32_t dirs = 0; dirs < MetaData.DirBlocks; dirs++){
274 disk->
read(MetaData.Blocks-1-dirs, dirblock.
Data);
275 for(uint32_t offset = 0; offset < FileSystem::DIR_PER_BLOCK; offset++){
297 if(!mounted)
return false;
301 fs_disk->read(0, block.
Data);
304 for(uint32_t i = 1; i <= MetaData.InodeBlocks; i++) {
306 if(inode_counter[i-1] == INODES_PER_BLOCK)
continue;
307 else fs_disk->read(i, block.
Data);
310 for(uint32_t j = 0; j < INODES_PER_BLOCK; j++) {
312 if(!block.
Inodes[j].Valid) {
313 block.
Inodes[j].Valid =
true;
316 for(
int ii = 0; ii < 5; ii++) {
319 free_blocks[i] =
true;
320 inode_counter[i-1]++;
322 fs_disk->write(i, block.
Data);
324 return (((i-1) * INODES_PER_BLOCK) + j);
339 if(!mounted)
return false;
340 if((inumber > MetaData.Inodes) || (inumber < 1)){
return false;}
345 int i = inumber / INODES_PER_BLOCK;
346 int j = inumber % INODES_PER_BLOCK;
349 if(inode_counter[i]) {
350 fs_disk->read(i+1, block.
Data);
351 if(block.
Inodes[j].Valid) {
367 if(!mounted)
return false;
372 if(load_inode(inumber, &node)) {
378 if(!(--inode_counter[inumber / INODES_PER_BLOCK])) {
379 free_blocks[inumber / INODES_PER_BLOCK + 1] =
false;
383 for(uint32_t i = 0; i < POINTERS_PER_INODE; i++) {
384 free_blocks[node.
Direct[i]] =
false;
395 for(uint32_t i = 0; i < POINTERS_PER_BLOCK; i++) {
401 fs_disk->read(inumber / INODES_PER_BLOCK + 1, block.
Data);
402 block.
Inodes[inumber % INODES_PER_BLOCK] = node;
403 fs_disk->write(inumber / INODES_PER_BLOCK + 1, block.
Data);
418 if(!mounted)
return -1;
423 if(load_inode(inumber, &node))
return node.
Size;
434 fs_disk->read(blocknum, *ptr);
436 *ptr += Disk::BLOCK_SIZE;
437 *length -= (Disk::BLOCK_SIZE - offset);
449 if(!mounted)
return -1;
452 int size_inode = stat(inumber);
457 if((
int)offset >= size_inode)
return 0;
458 else if(length + (
int)offset > size_inode) length = size_inode - offset;
464 int to_read = length;
467 if(load_inode(inumber, &node)) {
469 if(offset < POINTERS_PER_INODE * Disk::BLOCK_SIZE) {
471 uint32_t direct_node = offset / Disk::BLOCK_SIZE;
472 offset %= Disk::BLOCK_SIZE;
475 if(node.
Direct[direct_node]) {
476 read_helper(node.
Direct[direct_node++], offset, &length, &data, &ptr);
478 while(length > 0 && direct_node < POINTERS_PER_INODE && node.
Direct[direct_node]) {
479 read_helper(node.
Direct[direct_node++], 0, &length, &data, &ptr);
483 if(length <= 0)
return to_read;
490 if(direct_node == POINTERS_PER_INODE && node.
Indirect) {
495 for(uint32_t i = 0; i < POINTERS_PER_BLOCK; i++) {
496 if(indirect.
Pointers[i] && length > 0) {
497 read_helper(indirect.
Pointers[i], 0, &length, &data, &ptr);
503 if(length <= 0)
return to_read;
507 return (to_read - length);
513 return (to_read - length);
527 offset -= (POINTERS_PER_INODE * Disk::BLOCK_SIZE);
528 uint32_t indirect_node = offset / Disk::BLOCK_SIZE;
529 offset %= Disk::BLOCK_SIZE;
534 if(indirect.
Pointers[indirect_node] && length > 0) {
535 read_helper(indirect.
Pointers[indirect_node++], offset, &length, &data, &ptr);
539 for(uint32_t i = indirect_node; i < POINTERS_PER_BLOCK; i++) {
540 if(indirect.
Pointers[i] && length > 0) {
541 read_helper(indirect.
Pointers[i], 0, &length, &data, &ptr);
547 if(length <= 0)
return to_read;
551 return (to_read - length);
572 if(!mounted)
return 0;
575 for(uint32_t i = MetaData.InodeBlocks + 1; i < MetaData.Blocks; i++) {
576 if(free_blocks[i] == 0) {
577 free_blocks[i] =
true;
593 if(!mounted)
return -1;
596 int i = inumber / INODES_PER_BLOCK;
597 int j = inumber % INODES_PER_BLOCK;
601 fs_disk->read(i+1, block.
Data);
603 fs_disk->write(i+1, block.
Data);
619 char* ptr = (
char *)calloc(Disk::BLOCK_SIZE,
sizeof(
char));
622 for(
int i = offset; i < (int)Disk::BLOCK_SIZE && *read < length; i++) {
623 ptr[i] = data[*read];
626 fs_disk->write(blocknum, ptr);
641 if(!mounted)
return false;
645 blocknum = allocate_block();
648 node->
Size = read + orig_offset;
649 if(write_indirect) fs_disk->write(node->
Indirect, indirect.
Data);
664 if(!mounted)
return -1;
669 int orig_offset = offset;
672 if(length + offset > (POINTERS_PER_BLOCK + POINTERS_PER_INODE) * Disk::BLOCK_SIZE) {
679 if(!load_inode(inumber, &node)) {
681 node.
Size = length + offset;
682 for(uint32_t ii = 0; ii < POINTERS_PER_INODE; ii++) {
686 inode_counter[inumber / INODES_PER_BLOCK]++;
687 free_blocks[inumber / INODES_PER_BLOCK + 1] =
true;
691 node.
Size = max((
int)node.
Size, length + (
int)offset);
695 if(offset < POINTERS_PER_INODE * Disk::BLOCK_SIZE) {
697 int direct_node = offset / Disk::BLOCK_SIZE;
698 offset %= Disk::BLOCK_SIZE;
701 if(!check_allocation(&node, read, orig_offset, node.
Direct[direct_node],
false, indirect)) {
702 return write_ret(inumber, &node, read);
705 read_buffer(offset, &read, length, data, node.
Direct[direct_node++]);
708 if(read == length)
return write_ret(inumber, &node, length);
715 for(
int i = direct_node; i < (int)POINTERS_PER_INODE; i++) {
717 if(!check_allocation(&node, read, orig_offset, node.
Direct[direct_node],
false, indirect)) {
718 return write_ret(inumber, &node, read);
720 read_buffer(0, &read, length, data, node.
Direct[direct_node++]);
723 if(read == length)
return write_ret(inumber, &node, length);
730 if(!check_allocation(&node, read, orig_offset, node.
Indirect,
false, indirect)) {
731 return write_ret(inumber, &node, read);
736 for(
int i = 0; i < (int)POINTERS_PER_BLOCK; i++) {
742 for(
int j = 0; j < (int)POINTERS_PER_BLOCK; j++) {
744 if(!check_allocation(&node, read, orig_offset, indirect.
Pointers[j],
true, indirect)) {
745 return write_ret(inumber, &node, read);
747 read_buffer(0, &read, length, data, indirect.
Pointers[j]);
752 return write_ret(inumber, &node, length);
758 return write_ret(inumber, &node, read);
764 offset -= (Disk::BLOCK_SIZE * POINTERS_PER_INODE);
765 int indirect_node = offset / Disk::BLOCK_SIZE;
766 offset %= Disk::BLOCK_SIZE;
772 if(!check_allocation(&node, read, orig_offset, node.
Indirect,
false, indirect)) {
773 return write_ret(inumber, &node, read);
778 for(
int i = 0; i < (int)POINTERS_PER_BLOCK; i++) {
784 if(!check_allocation(&node, read, orig_offset, indirect.
Pointers[indirect_node],
true, indirect)) {
785 return write_ret(inumber, &node, read);
787 read_buffer(offset, &read, length, data, indirect.
Pointers[indirect_node++]);
792 return write_ret(inumber, &node, length);
796 for(
int j = indirect_node; j < (int)POINTERS_PER_BLOCK; j++) {
798 if(!check_allocation(&node, read, orig_offset, indirect.
Pointers[j],
true, indirect)) {
799 return write_ret(inumber, &node, read);
801 read_buffer(0, &read, length, data, indirect.
Pointers[j]);
806 return write_ret(inumber, &node, length);
812 return write_ret(inumber, &node, read);