We'll periodically update this FAQ to address problems we see many students are experiencing.
There are two kinds of blocks in this filesystem. They both have size 512 bytes. On the one hand, there are disk blocks, also known as sectors. Disk block 42 is something you can get using diskimg_readsector—it's just the 43rd block on the disk (disk blocks are zero-indexed), if we view the disk as an array of blocks.
On the other hand, there are file blocks. Take some file foo, and divide its contents up into 512-byte chunks. If I ask for the 10th block of the file foo, that means I want the 10th chunk of the file's contents.
Some functions which take a "block number" take a disk block number, and others take a sector number. Part of this assignment is figuring out which is which.
This assignment makes use of a C idiom which you might find counter-intuitive at first blush.
As an example, consider the
read function:
int read(int fd, void *buf, size_t count);
To quote from its man page:
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
On success, the number of bytes read is returned. [...] On error, -1 is returned.
In other words, before calling read on a given file descriptor
fd, you first allocate a buffer of size count bytes.
You then pass to read the address of that buffer, and
read writes the data it reads into that buffer.
You might write this as:
// Assume fd is initialized for us, perhaps through a call to open().
char buf[1024];
int bytes_read = read(fd, &buf, 1024);
if (bytes_read == -1) {
// error!
}
else {
// The first bytes_read bytes of buf now contain data read from the file
// pointed to by fd.
}
Other functions in this assignment use a similar convention. For
instance, consider the function inode_iget:
/*
* Fetch the specified inode from the filesystem.
* Return 0 on success, -1 on error.
*/
int inode_iget(struct unixfilesystem *fs, int inumber, struct inode *inp)
{
// left for you to implement
}
You might call this function as follows:
struct inode ino;
int rv = inode_iget(fs, 42, &ino);
if (rv == 0) {
// ino now contains the contents of inode 42.
}
else {
// error!
}