This task requires us to modify the inode structure to extend the maximum file size. The original inode data consists of 12 direct links and 1 single-level indirect links:
The new structure will change one direct link to a double-indirect link:
The NDIRECT
and MAXFILE
macros will be changed.
#define NDIRECT 11
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT + NINDIRECT * NINDIRECT)
// On-disk inode structure
struct dinode {
short type; // File type
short major; // Major device number (T_DEVICE only)
short minor; // Minor device number (T_DEVICE only)
short nlink; // Number of links to inode in file system
uint size; // Size of file (bytes)
uint addrs[NDIRECT+2]; // Data block addresses
};
Now if we allocate a new data block for an inode, we have to consider the case of double-indirect link when we call bmap
:
log_write
will be finished elsewhere)The link()
system call creates a new directory entry pointing to the underlying inode. It only creates a pathname and increments the link count of the inode.
Instead of referencing an inode, a symbolic link reference another pathname. The target pathname can be invalid (not exists), point to a normal file/inode or be another symbolic link. To save the target path string, I create an inode for each symbolic link and write it to data blocks when calling symlink()
. What differs from link()
is that every symbolic link contains a real inode, not just a mapping between directory entry and inode.
The whole task can be split into link file creating and opening.
Symbol link is identified as T_SYMLINK
for inode.type
. System call symlink()
will do two things: