/usr/lib/foo.c
This means the parameter passed to the file open function would be something like the following:
char path[50] = {"/usr/lib/foo.c"}
;
...
File_Open(path);
Of course, the actual declaration of path will be different but this should give you an idea of what to do.
char buf[SECTOR_SIZE];
for(i=0; i<(SECTOR_SIZE / INODE_SIZE); i++)
memcpy(buf, inode, sizeof(inode));
Disk_Write(inode_sector, buf);
The same goes for modifying an inode (or a data block for that matter). You must first read the entire block into memory, modify the correct portion of it, and then write it back out. Remember, you must always access the disk in elements of SECTOR_SIZE. Here is one more example of modifying a portion of a data sector:
char buf[SECTOR_SIZE];
Disk_Read(sector_num, buf);
// Assume the user has passed in a usrBuf that contains 10 bytes
// that need to be copied out.
memcpy(buf + offset, usrBuf, 10);
Disk_Write(sector_num, buf)
Of course, the offset is which bytes in that sector you want to modify.
/usr/test.c
The following is a rough sketch of how the important data structures are arranged on disk:
root inode (block 0) usr inode (block 24) test.c inode (block 12) --------------------- --------------------- --------------------- | type | D | | type | D | | type | F | | size | 80 | | size | 40 | | size | 700 | |-------------------| |-------------------| |-------------------| | block 0 | 25 | | block 0 | 53 | | block 0 | 21 | | block 1 | 0 | | block 1 | 0 | | block 1 | 28 | | ... | ... | | ... | ... | | block 2 | 0 | | block 29 | 0 | | block 29 | 0 | | ... | ... | --------------------- --------------------- | ... | ... | --------------------- root directory (block 25) usr directory (block 53) ---------------------- ---------------------- | usr | 24 | | local | 90 | | bin | 5 | | test.c | 12 | | foo | 16 | | | | | bar | 48 | | | | | | | | | | | | | | | | ---------------------- ---------------------- test.c data (block 21) test.c data (block 28) ---------------------- ---------------------- | | | | | | | DATA | | DATA | | | | | |--- end of data --- | <-- byte 700 | | | | | | | | ---------------------- ----------------------
To find the file test.c you would start by going to inode 0 and finding out which data blocks contain the directory entries for the root directory. You will then load data block 25 into memory and start searching thought it. When you find the entry usr you will then load inode 24 into memory. The inode will show that the usr directory only contains one data block and it is located at data block 53 - load data block 53 into memory. Search this data block until you come across the test.c entry. Now load inode 12 into memory. You can now find any of the data that is currently held in test.c (it is all located in blocks 21 and 28).
Here is what I suggest you do. First, write functions that allow you access bits. These function might be (but don't have to be) things like:
void getBit(char* bitMap, int bit);
void setBit(char* bitMap, int bit);
void clearBit(char* bitMap, int bit);
int findFirstFreeBlock(char* bitMap);
There could of course be more of these functions. You can write and test these functions completely independant of the rest of your project. Once you are convinced they work properly, you can plug them directly into your project and never worry about doing any bit manipulation again :)
As for how to do this bit manipulation, you're going to need to become familiar with all the bit operators. Here they are:
& - bitwise and
| - bitwise or
^ - bitwise xor
~ - compliment (switch all 1's to zeroes and zeroes to 1's)
>> - shift right
<< - shift left
As a really quick example of how you could use some of these, let's assume you want to set the 3rd bit in a byte equal to zero:
unsigned char byte = getByte(n);
unsigned char mask = 1 << 3;
byte = ~mask & byte;
storeByte(n, byte);
One thing to note, using unsigned char's is probably a better idea than using regular chars. This can save you some headaches in the future.
The second option is to use a function called access(). It basically checks to see if it would be okay for you to open the file without actually opening it.
To get specific information about a file, you can use the stat() function (this could also be used to check for the existance of a file). To get more information on this or the other two functions, check out the man pages.