SimpleFS
A Simple File Sytem implementation including Disk and Shell Layers
fs_layer_1.cpp
Go to the documentation of this file.
1 
13 #include "sfs/fs.h"
14 #include "sfs/sha256.h"
15 
16 #include <algorithm>
17 #include <math.h>
18 #include <assert.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <iostream>
22 
23 using namespace std;
24 
25 void FileSystem::debug(Disk *disk) {
30  Block block;
31 
33  disk->read(0, block.Data);
34 
35  printf("SuperBlock:\n");
36 
38  if(block.Super.MagicNumber == MAGIC_NUMBER)
39  printf(" magic number is valid\n");
40  else {
41  printf(" magic number is invalid\n");
42  printf(" exiting...\n");
43  return;
44  }
45 
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);
50 
52  int ii = 0;
53 
54  for(uint32_t i = 1; i <= block.Super.InodeBlocks; i++) {
55  disk->read(i, block.Data);
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:");
62 
64  for(uint32_t k = 0; k < POINTERS_PER_INODE; k++) {
65  if(block.Inodes[j].Direct[k]) printf(" %u", block.Inodes[j].Direct[k]);
66  }
67  printf("\n");
68 
70  if(block.Inodes[j].Indirect){
71  printf(" indirect block: %u\n indirect data blocks:",block.Inodes[j].Indirect);
72  Block IndirectBlock;
73  disk->read(block.Inodes[j].Indirect,IndirectBlock.Data);
74  for(uint32_t k = 0; k < POINTERS_PER_BLOCK; k++) {
75  if(IndirectBlock.Pointers[k]) printf(" %u", IndirectBlock.Pointers[k]);
76  }
77  printf("\n");
78  }
79  }
80 
81  ii++;
82  }
83  }
84 
85  return;
86 }
87 
88 bool FileSystem::format(Disk *disk) {
93  if(disk->mounted()) return false;
94 
96  Block block;
97  memset(&block, 0, sizeof(Block));
98 
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);
102  block.Super.Inodes = block.Super.InodeBlocks * (FileSystem::INODES_PER_BLOCK);
103  block.Super.DirBlocks = (uint32_t)std::ceil((int(block.Super.Blocks) * 1.00)/100);
104 
105  disk->write(0,block.Data);
106 
108  block.Super.Protected = 0;
109  memset(block.Super.PasswordHash,0,257);
110 
112  for(uint32_t i = 1; i <= block.Super.InodeBlocks; i++){
113  Block inodeblock;
114 
116  for(uint32_t j = 0; j < FileSystem::INODES_PER_BLOCK; j++){
117  inodeblock.Inodes[j].Valid = false;
118  inodeblock.Inodes[j].Size = 0;
119 
121  for(uint32_t k = 0; k < FileSystem::POINTERS_PER_INODE; k++)
122  inodeblock.Inodes[j].Direct[k] = 0;
123 
125  inodeblock.Inodes[j].Indirect = 0;
126  }
127 
128  disk->write(i,inodeblock.Data);
129  }
130 
132  for(uint32_t i = (block.Super.InodeBlocks) + 1; i < block.Super.Blocks - block.Super.DirBlocks; i++){
133  Block DataBlock;
134  memset(DataBlock.Data, 0, Disk::BLOCK_SIZE);
135  disk->write(i, DataBlock.Data);
136  }
137 
139  for(uint32_t i = block.Super.Blocks - block.Super.DirBlocks; i < block.Super.Blocks; i++){
140  Block DataBlock;
141  Directory dir;
142  dir.inum = -1;
143  dir.Valid = 0;
144  memset(dir.Table,0,sizeof(Dirent)*ENTRIES_PER_DIR);
145  for(uint32_t j=0; j<FileSystem::DIR_PER_BLOCK; j++){
146  DataBlock.Directories[j] = dir;
147  }
148  disk->write(i, DataBlock.Data);
149  }
150 
152  struct Directory root;
153  strcpy(root.Name,"/");
154  root.inum = 0;
155  root.Valid = 1;
156 
158  struct Dirent temp;
159  memset(&temp, 0, sizeof(temp));
160  temp.inum = 0;
161  temp.type = 0;
162  temp.valid = 1;
163  char tstr1[] = ".";
164  char tstr2[] = "..";
165  strcpy(temp.Name,tstr1);
166  memcpy(&(root.Table[0]),&temp,sizeof(Dirent));
167  strcpy(temp.Name,tstr2);
168  memcpy(&(root.Table[1]),&temp,sizeof(Dirent));
169 
171  Block Dirblock;
172  memcpy(&(Dirblock.Directories[0]),&root,sizeof(root));
173  disk->write(block.Super.Blocks -1, Dirblock.Data);
174 
175  return true;
176 }
177 
178 bool FileSystem::mount(Disk *disk) {
184  if(disk->mounted()) return false;
185 
187  Block block;
188  disk->read(0,block.Data);
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;
193 
195  if(block.Super.Protected){
196  char pass[1000], line[1000];
197  printf("Enter password: ");
198  if (fgets(line, BUFSIZ, stdin) == NULL) {
199  return false;
200  }
201  sscanf(line, "%s", pass);
202  SHA256 hasher;
203  if(hasher(pass) == string(block.Super.PasswordHash)){
204  printf("Disk Unlocked\n");
205  return true;
206  }
207  else{
208  printf("Password Failed. Exiting...\n");
209  return false;
210  }
211  }
212 
213  disk->mount();
214  fs_disk = disk;
215 
217  MetaData = block.Super;
218 
220  free_blocks.resize(MetaData.Blocks, false);
221 
223  inode_counter.resize(MetaData.InodeBlocks, 0);
224 
226  free_blocks[0] = true;
227 
229  for(uint32_t i = 1; i <= MetaData.InodeBlocks; i++) {
230  disk->read(i, block.Data);
231 
232  for(uint32_t j = 0; j < INODES_PER_BLOCK; j++) {
233  if(block.Inodes[j].Valid) {
234  inode_counter[i-1]++;
235 
237  if(block.Inodes[j].Valid) free_blocks[i] = true;
238 
240  for(uint32_t k = 0; k < POINTERS_PER_INODE; k++) {
241  if(block.Inodes[j].Direct[k]){
242  if(block.Inodes[j].Direct[k] < MetaData.Blocks)
243  free_blocks[block.Inodes[j].Direct[k]] = true;
244  else
245  return false;
246  }
247  }
248 
250  if(block.Inodes[j].Indirect){
251  if(block.Inodes[j].Indirect < MetaData.Blocks) {
252  free_blocks[block.Inodes[j].Indirect] = true;
253  Block indirect;
254  fs_disk->read(block.Inodes[j].Indirect, indirect.Data);
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;
258  }
259  else return false;
260  }
261  }
262  else
263  return false;
264  }
265  }
266  }
267  }
268 
270  dir_counter.resize(MetaData.DirBlocks,0);
271 
272  Block dirblock;
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++){
276  if(dirblock.Directories[offset].Valid == 1){
277  dir_counter[dirs]++;
278  }
279  }
280  if(dirs == 0){
281  curr_dir = dirblock.Directories[0];
282  }
283  }
284 
285  mounted = true;
286 
287  return true;
288 }
289 
290 
297  if(!mounted) return false;
298 
300  Block block;
301  fs_disk->read(0, block.Data);
302 
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);
308 
310  for(uint32_t j = 0; j < INODES_PER_BLOCK; j++) {
312  if(!block.Inodes[j].Valid) {
313  block.Inodes[j].Valid = true;
314  block.Inodes[j].Size = 0;
315  block.Inodes[j].Indirect = 0;
316  for(int ii = 0; ii < 5; ii++) {
317  block.Inodes[j].Direct[ii] = 0;
318  }
319  free_blocks[i] = true;
320  inode_counter[i-1]++;
321 
322  fs_disk->write(i, block.Data);
323 
324  return (((i-1) * INODES_PER_BLOCK) + j);
325  }
326  }
327  }
328 
329  return -1;
330 }
331 
332 
333 bool FileSystem::load_inode(size_t inumber, Inode *node) {
339  if(!mounted) return false;
340  if((inumber > MetaData.Inodes) || (inumber < 1)){return false;}
341 
342  Block block;
343 
345  int i = inumber / INODES_PER_BLOCK;
346  int j = inumber % INODES_PER_BLOCK;
347 
349  if(inode_counter[i]) {
350  fs_disk->read(i+1, block.Data);
351  if(block.Inodes[j].Valid) {
352  *node = block.Inodes[j];
353  return true;
354  }
355  }
356 
357  return false;
358 }
359 
360 
361 bool FileSystem::remove(size_t inumber) {
367  if(!mounted) return false;
368 
369  Inode node;
370 
372  if(load_inode(inumber, &node)) {
373  node.Valid = false;
374  node.Size = 0;
375 
378  if(!(--inode_counter[inumber / INODES_PER_BLOCK])) {
379  free_blocks[inumber / INODES_PER_BLOCK + 1] = false;
380  }
381 
383  for(uint32_t i = 0; i < POINTERS_PER_INODE; i++) {
384  free_blocks[node.Direct[i]] = false;
385  node.Direct[i] = 0;
386  }
387 
389  if(node.Indirect) {
390  Block indirect;
391  fs_disk->read(node.Indirect, indirect.Data);
392  free_blocks[node.Indirect] = false;
393  node.Indirect = 0;
394 
395  for(uint32_t i = 0; i < POINTERS_PER_BLOCK; i++) {
396  if(indirect.Pointers[i]) free_blocks[indirect.Pointers[i]] = false;
397  }
398  }
399 
400  Block block;
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);
404 
405  return true;
406  }
407 
408  return false;
409 }
410 
411 
412 ssize_t FileSystem::stat(size_t inumber) {
418  if(!mounted) return -1;
419 
420  Inode node;
421 
423  if(load_inode(inumber, &node)) return node.Size;
424 
425  return -1;
426 }
427 
428 void FileSystem::read_helper(uint32_t blocknum, int offset, int *length, char **data, char **ptr) {
434  fs_disk->read(blocknum, *ptr);
435  *data += offset;
436  *ptr += Disk::BLOCK_SIZE;
437  *length -= (Disk::BLOCK_SIZE - offset);
438 
439  return;
440 }
441 
442 
443 ssize_t FileSystem::read(size_t inumber, char *data, int length, size_t offset) {
449  if(!mounted) return -1;
450 
452  int size_inode = stat(inumber);
453 
457  if((int)offset >= size_inode) return 0;
458  else if(length + (int)offset > size_inode) length = size_inode - offset;
459 
460  Inode node;
461 
463  char *ptr = data;
464  int to_read = length;
465 
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;
473 
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);
480  }
481 
483  if(length <= 0) return to_read;
484  else {
490  if(direct_node == POINTERS_PER_INODE && node.Indirect) {
491  Block indirect;
492  fs_disk->read(node.Indirect, indirect.Data);
493 
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);
498  }
499  else break;
500  }
501 
503  if(length <= 0) return to_read;
504  else {
507  return (to_read - length);
508  }
509  }
510  else {
513  return (to_read - length);
514  }
515  }
516  }
517  else {
519  return 0;
520  }
521  }
522  else {
525  if(node.Indirect) {
527  offset -= (POINTERS_PER_INODE * Disk::BLOCK_SIZE);
528  uint32_t indirect_node = offset / Disk::BLOCK_SIZE;
529  offset %= Disk::BLOCK_SIZE;
530 
531  Block indirect;
532  fs_disk->read(node.Indirect, indirect.Data);
533 
534  if(indirect.Pointers[indirect_node] && length > 0) {
535  read_helper(indirect.Pointers[indirect_node++], offset, &length, &data, &ptr);
536  }
537 
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);
542  }
543  else break;
544  }
545 
547  if(length <= 0) return to_read;
548  else {
551  return (to_read - length);
552  }
553  }
554  else {
556  return 0;
557  }
558  }
559  }
560 
562  return -1;
563 }
564 
565 
572  if(!mounted) return 0;
573 
575  for(uint32_t i = MetaData.InodeBlocks + 1; i < MetaData.Blocks; i++) {
576  if(free_blocks[i] == 0) {
577  free_blocks[i] = true;
578  return (uint32_t)i;
579  }
580  }
581 
583  return 0;
584 }
585 
586 
587 ssize_t FileSystem::write_ret(size_t inumber, Inode* node, int ret) {
593  if(!mounted) return -1;
594 
596  int i = inumber / INODES_PER_BLOCK;
597  int j = inumber % INODES_PER_BLOCK;
598 
600  Block block;
601  fs_disk->read(i+1, block.Data);
602  block.Inodes[j] = *node;
603  fs_disk->write(i+1, block.Data);
604 
606  return (ssize_t)ret;
607 }
608 
609 
610 void FileSystem::read_buffer(int offset, int *read, int length, char *data, uint32_t blocknum) {
616  if(!mounted) return;
617 
619  char* ptr = (char *)calloc(Disk::BLOCK_SIZE, sizeof(char));
620 
622  for(int i = offset; i < (int)Disk::BLOCK_SIZE && *read < length; i++) {
623  ptr[i] = data[*read];
624  *read = *read + 1;
625  }
626  fs_disk->write(blocknum, ptr);
627 
629  free(ptr);
630 
631  return;
632 }
633 
634 
635 bool FileSystem::check_allocation(Inode* node, int read, int orig_offset, uint32_t &blocknum, bool write_indirect, Block indirect) {
641  if(!mounted) return false;
642 
644  if(!blocknum) {
645  blocknum = allocate_block();
647  if(!blocknum) {
648  node->Size = read + orig_offset;
649  if(write_indirect) fs_disk->write(node->Indirect, indirect.Data);
650  return false;
651  }
652  }
653 
654  return true;
655 }
656 
657 
658 ssize_t FileSystem::write(size_t inumber, char *data, int length, size_t offset) {
664  if(!mounted) return -1;
665 
666  Inode node;
667  Block indirect;
668  int read = 0;
669  int orig_offset = offset;
670 
672  if(length + offset > (POINTERS_PER_BLOCK + POINTERS_PER_INODE) * Disk::BLOCK_SIZE) {
673  return -1;
674  }
675 
679  if(!load_inode(inumber, &node)) {
680  node.Valid = true;
681  node.Size = length + offset;
682  for(uint32_t ii = 0; ii < POINTERS_PER_INODE; ii++) {
683  node.Direct[ii] = 0;
684  }
685  node.Indirect = 0;
686  inode_counter[inumber / INODES_PER_BLOCK]++;
687  free_blocks[inumber / INODES_PER_BLOCK + 1] = true;
688  }
689  else {
691  node.Size = max((int)node.Size, length + (int)offset);
692  }
693 
695  if(offset < POINTERS_PER_INODE * Disk::BLOCK_SIZE) {
697  int direct_node = offset / Disk::BLOCK_SIZE;
698  offset %= Disk::BLOCK_SIZE;
699 
701  if(!check_allocation(&node, read, orig_offset, node.Direct[direct_node], false, indirect)) {
702  return write_ret(inumber, &node, read);
703  }
705  read_buffer(offset, &read, length, data, node.Direct[direct_node++]);
706 
708  if(read == length) return write_ret(inumber, &node, length);
713  else {
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);
719  }
720  read_buffer(0, &read, length, data, node.Direct[direct_node++]);
721 
723  if(read == length) return write_ret(inumber, &node, length);
724  }
725 
727  if(node.Indirect) fs_disk->read(node.Indirect, indirect.Data);
728  else {
730  if(!check_allocation(&node, read, orig_offset, node.Indirect, false, indirect)) {
731  return write_ret(inumber, &node, read);
732  }
733  fs_disk->read(node.Indirect, indirect.Data);
734 
736  for(int i = 0; i < (int)POINTERS_PER_BLOCK; i++) {
737  indirect.Pointers[i] = 0;
738  }
739  }
740 
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);
746  }
747  read_buffer(0, &read, length, data, indirect.Pointers[j]);
748 
750  if(read == length) {
751  fs_disk->write(node.Indirect, indirect.Data);
752  return write_ret(inumber, &node, length);
753  }
754  }
755 
757  fs_disk->write(node.Indirect, indirect.Data);
758  return write_ret(inumber, &node, read);
759  }
760  }
762  else {
764  offset -= (Disk::BLOCK_SIZE * POINTERS_PER_INODE);
765  int indirect_node = offset / Disk::BLOCK_SIZE;
766  offset %= Disk::BLOCK_SIZE;
767 
769  if(node.Indirect) fs_disk->read(node.Indirect, indirect.Data);
770  else {
772  if(!check_allocation(&node, read, orig_offset, node.Indirect, false, indirect)) {
773  return write_ret(inumber, &node, read);
774  }
775  fs_disk->read(node.Indirect, indirect.Data);
776 
778  for(int i = 0; i < (int)POINTERS_PER_BLOCK; i++) {
779  indirect.Pointers[i] = 0;
780  }
781  }
782 
784  if(!check_allocation(&node, read, orig_offset, indirect.Pointers[indirect_node], true, indirect)) {
785  return write_ret(inumber, &node, read);
786  }
787  read_buffer(offset, &read, length, data, indirect.Pointers[indirect_node++]);
788 
790  if(read == length) {
791  fs_disk->write(node.Indirect, indirect.Data);
792  return write_ret(inumber, &node, length);
793  }
795  else {
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);
800  }
801  read_buffer(0, &read, length, data, indirect.Pointers[j]);
802 
804  if(read == length) {
805  fs_disk->write(node.Indirect, indirect.Data);
806  return write_ret(inumber, &node, length);
807  }
808  }
809 
811  fs_disk->write(node.Indirect, indirect.Data);
812  return write_ret(inumber, &node, read);
813  }
814  }
815 
817  return -1;
818 }
FileSystem::read_buffer
void read_buffer(int offset, int *read, int length, char *data, uint32_t blocknum)
reads from buffer and writes to a block in the disk
Definition: fs_layer_1.cpp:610
FileSystem::write_ret
ssize_t write_ret(size_t inumber, Inode *node, int ret)
writes the node into the corresponding inode block
Definition: fs_layer_1.cpp:587
FileSystem::remove
bool remove(size_t inumber)
removes the inode
Definition: fs_layer_1.cpp:361
FileSystem::Directory::Table
Dirent Table[ENTRIES_PER_DIR]
Definition: fs.h:181
FileSystem::write
ssize_t write(size_t inumber, char *data, int length, size_t offset)
write to the disk
Definition: fs_layer_1.cpp:658
Disk::mounted
bool mounted() const
check if the disk has been mounted
Definition: disk.h:67
fs.h
Interface for the FileSystem layer.
FileSystem::Block::Pointers
uint32_t Pointers[FileSystem::POINTERS_PER_BLOCK]
Definition: fs.h:205
Disk::mount
void mount()
mount the disk
Definition: disk.h:73
FileSystem::create
ssize_t create()
creates a new inode
Definition: fs_layer_1.cpp:291
Disk::read
void read(int blocknum, char *data)
read from disk
Definition: disk.cpp:86
FileSystem::Directory::inum
uint32_t inum
Definition: fs.h:179
FileSystem::SuperBlock::Inodes
uint32_t Inodes
Definition: fs.h:153
FileSystem::read_helper
void read_helper(uint32_t blocknum, int offset, int *length, char **data, char **ptr)
reads the block from disk and changes the pointers accordingly
Definition: fs_layer_1.cpp:428
FileSystem::Block::Directories
struct Directory Directories[FileSystem::DIR_PER_BLOCK]
Definition: fs.h:207
FileSystem::SuperBlock::Blocks
uint32_t Blocks
Definition: fs.h:150
FileSystem::Dirent::inum
uint32_t inum
Definition: fs.h:166
FileSystem::Dirent::valid
uint8_t valid
Definition: fs.h:165
FileSystem::Inode::Size
uint32_t Size
Definition: fs.h:192
FileSystem::Inode
Inode Structure Corresponds to a file stored on the disk. Contains the list of raw data blocks used t...
Definition: fs.h:190
FileSystem::Dirent::Name
char Name[NAMESIZE]
Definition: fs.h:167
FileSystem::stat
void stat()
Returns the stat of the disk. The stat contains information like number of directories,...
Definition: fs_layer_2.cpp:583
FileSystem::Block
Block Union Corresponds to one block of disk of size Disk::BLOCKSIZE. Can be used as a SuperBlock,...
Definition: fs.h:202
FileSystem::Dirent
Directory Entry. Contains necessary fields to locate the file and directory Consumes 64 KB per object...
Definition: fs.h:163
FileSystem::debug
static void debug(Disk *disk)
prints the basic outline of the disk
Definition: fs_layer_1.cpp:25
FileSystem::SuperBlock::PasswordHash
char PasswordHash[257]
Definition: fs.h:155
FileSystem::Directory::Name
char Name[NAMESIZE]
Definition: fs.h:180
FileSystem::check_allocation
bool check_allocation(Inode *node, int read, int orig_offset, uint32_t &blocknum, bool write_indirect, Block indirect)
allocates a block if required; if no block is available in the disk; returns false
Definition: fs_layer_1.cpp:635
FileSystem::read
ssize_t read(size_t inumber, char *data, int length, size_t offset)
read from disk
Definition: fs_layer_1.cpp:443
Disk::size
size_t size() const
check size of disk
Definition: disk.h:61
FileSystem::Block::Inodes
struct Inode Inodes[FileSystem::INODES_PER_BLOCK]
Definition: fs.h:204
FileSystem::SuperBlock::DirBlocks
uint32_t DirBlocks
Definition: fs.h:152
FileSystem::load_inode
bool load_inode(size_t inumber, Inode *node)
loads inode corresponding to inumber into node
Definition: fs_layer_1.cpp:333
Disk
Disk class Implements Disk abstraction that enables emulation of a disk image. Used by file system to...
Definition: disk.h:18
FileSystem::SuperBlock::InodeBlocks
uint32_t InodeBlocks
Definition: fs.h:151
FileSystem::Directory
Directory Structure. Contains a table of directory entries for storing hierarchy. Also contains field...
Definition: fs.h:177
FileSystem::Inode::Indirect
uint32_t Indirect
Definition: fs.h:194
FileSystem::format
static bool format(Disk *disk)
formats the entire disk
Definition: fs_layer_1.cpp:88
FileSystem::allocate_block
uint32_t allocate_block()
allocates the first free block from free block bitmap
Definition: fs_layer_1.cpp:566
FileSystem::Inode::Direct
uint32_t Direct[FileSystem::POINTERS_PER_INODE]
Definition: fs.h:193
FileSystem::mount
bool mount(Disk *disk)
mounts the file system onto the disk
Definition: fs_layer_1.cpp:178
FileSystem::Block::Data
char Data[Disk::BLOCK_SIZE]
Definition: fs.h:206
FileSystem::SuperBlock::Protected
uint32_t Protected
Definition: fs.h:154
Disk::write
void write(int blocknum, char *data)
write to disk
Definition: disk.cpp:112