OPERATING SYSTEMS – ASSIGNMENT 4

FILE SYSTEM

Introduction

In this assignment you will expand the maximal size supported by the , and adding support for symbolic links.

You can download xv6 sources for the current work by executing the following command:

git clone http://www.cs.bgu.ac.il/~osce171/git/Assignment4

Task 1: “Hacking” the xv6 file system XV6, as a variant of , uses the same file system architecture based on i-nodes. In both of these systems the maximal size of files is fixed and predetermined. The i-node structure in xv6 contains 12 direct pointers to data blocks and another single indirect pointer. Each data block is of size 512 bytes, totaling 6KB pointed to by the direct pointers. The indirect pointer points to a block which maps additional 128 blocks. This one level of indirection gives access to 64KB of additional data. Due to this structure we are able to use files of size up to 70KB.

1.1. Expanding the maximal :

In this part you are to extend the i-node structure in order to support files of size up to 8MB. Do this by adding a double indirection layer to the i-nodes. This requires changing the i-node structure, as well as the disk representation of i-nodes (dinode). In order to do so you should update NDIRECT macro (see fs.h) to be 11 (i.e., 11 direct links) which must be followed by single indirect pointer and a to double indirection.

Note that the change in i-node structure (both and dinode) requires changes in both the kernel (see bmap and itrunc at fs.c) and the utility mkfs that create the virtual drive, fs.img. The file mkfs.c is written using standard C libraries and is built and executed by the makefile outside of xv6 to create the virtual drive. One of its tasks is to the superblock, which contains metadata characterizing the file system. You will have to modify the contents of the superblock to be consistent with the changes you make. The virtual disk, fs.img, should contain at least 215 blocks (totaling 16MB).

1.2. Sanity :

Write a simple user application which creates a of size 1MB and writes a notification message to the screen after writing the first 11 direct blocks, after writing the single indirect blocks, and after writing the double indirect blocks. The purpose of this application is to test your implementation, and in case it contains bugs, help you identify where the bugs are. You are free to change the output or add additional printings as you see fit.

The output should look something like:

Finished writing 6KB (direct) Finished writing 70KB (single indirect) Finished writing 1MB

Task 2: Adding support for symbolic links

Xv6 supports hard links via the user space program . Hard links allow different file names to reference the same actual file by using the same i-node number. For example, when a named "b.txt" is created for a file named "a.txt", both "a.txt" and "b.txt" refer to the same file (data) on disk. Changes made to “a.txt” are reflected in “b.txt” and vice versa. Deleting one will not affect the other (it will only decrease the link count).

In this task you will expand the program ln to support symbolic links, also referred to as soft links. When a new symbolic link is created, it doesn't share the same i-node as the pointed file (target). Instead, a new file is created and a new i-node is assigned to it. The contents of the new symbolic link file will contain the to the target.

Notice that symbolic links are a special type of files, and should be assigned a unique enumeration value in the file type enum. Also, symbolic links can point to any type of file: regular file, and even another symbolic link. Furthermore, they can be either absolute or relative. Naturally, moving a relative link to a different location will result in a broken link.

2.1. symlink system call;

In order to be able to create a symbolic link you should implement symlink system call:

int symlink(const char *oldpath, const char *newpath);

This system call should create a symbolic link, whose name is specified by the parameter newpath, and which points to the file whose name is specified by the parameter oldpath. The latter can be of any type or may not even exist. symlink() returns 0 upon success, and -1 upon failure.

2.2. Update namei functionality;

In order to deal with with symbolic links update namei signature (see fs.c) to

struct inode* namei(char *path, int depth);

The default behavior of namei is translation of path to inode. By introduction of symbolic links the resolution process must be changed. If the path points to a symbolic link, namei should recursively process to the path stored as the data of the symbolic link. This resolution process should continue up to depth provided by the argument.

Symbolic links to directories may cause infinite loops. We shall tackle this issue in the same manner as done in UNIX, by limiting the degree of a chain of links to 16. I.e. when retrieving the target of a link, which points to a link, which points to a link, and so on… The max number of jumps we will allow is 16. Longer chains will be considered as loops.

Extend the user applications to handle symbolic links as if it were the target file. I.e. cat some_link should display the contents of the target file, to which the symbolic link some_link points. Notice – we always dereference symbolic links in the path as long as it is not the file name (for example, when Path = “a/b/c.txt”, where a and c.txt are symbolic links, we will always dereference a but c.txt will be dereferenced only if requested). To do so you will need to change the , chdir and exec system calls so they dereferences symbolic links.

 Note that the user space program should list symbolic links as they are, so it must open those files without the dereference mode.

2.3. Change ln user space program;

In order to grant a user an ability to create symbolic links you are required to extend the functionality of the ln user space program so that

ln –s old_path new_path will create symbolic link new_path and it will point to the existing file old_path.

Submission Guidelines

Make sure that your Makefile is properly updated and that your code compiles with no warnings whatsoever. We strongly recommend documenting your code changes with comments – these are often handy when discussing your code with the graders.

Due to our constrained resources, assignments are only allowed in pairs. Please note this important point and try to match up with a partner as soon as possible.

Submissions are only allowed through the submission system. To avoid submitting a large number of xv6 builds you are required to submit a patch (i.e. a file which patches the original xv6 and applies all your changes). You may use the following instructions to guide you through the process:

Back-up your work before proceeding!

Before creating the patch review the change list and make sure it contains all the changes that you applied and noting more. Modified files are automatically detected by git but new files must be added explicitly with the ‘git add’ command:

> git add . –Av; git commit –m “commit message”

At this point you may examine the differences (the patch):

> git diff origin

Once you are ready to create a patch simply make sure the output is redirected to the patch file:

> git diff origin > ID1_ID2.patch

 Tip: Although grades will only apply your latest patch, the submission system supports multiple uploads. Use this feature often and make sure you upload patches of your current work even if you haven’t completed the assignment.

Finally, you should note that the graders are instructed to examine your code on lab computers only!

We advise you to test your code on lab computers prior to submission, and in addition after submission to download your assignment, apply the patch, compile it, and make sure everything runs and works.