[an error occurred while processing this directive] [an error occurred while processing this directive]
This assignment covers:
In the previous assignment (Lab 3), you implemented synchronization of several user programs, however, the synchronization of files and the file system was out of scope. In this assignment, you are supposed to implement the readers-writers synchronization algorithm for performing reading and writing operations on several files by several programs. Each file can be open by several programs and even by the same program several times. Since the user programs can concurrently modify not only files but the file system itself, you need to synchronize the corresponding system calls (remove/create and open/close) to preserve consistency of the file system.
In this assignment, you will need to implement 4 new systems calls:
You will also need to provide synchronization to the following system calls implemented in the previous labs:
All these system calls will allow to perform the majority of file operations. Note that the file size is still considered to be fixed in this lab for the sake of simplicity.
Pintos File System is a Unix-like file system, which is close to one described with the Virtual File System (VFS) interface. So, read Chapter 21.7.1 "The Virtual File System" of the course book. Pintos uses the same concept of inodes, open files, superblocks and dentry objects. The two last ones correspond to disk and directory in Pintos.
The synchronization of concurrent access to files (reading/writing) is one of the basic issues in operating system design. Usually, it is called "readers-writers problem". The problem with the possible solutions is described in Chapter 6.6.2 "The Readers-Writers Problem" of the course book.
The directory is a special file, which contains file names and file locations on the disk. In other words, it associates the file name with the actual file placement on the disk. Since the kernel and multiple user programs can access the directory concurrently (while creating, removing and opening files) it also needs to be synchronized. Moreover, the operating system keeps track of currently free disk sectors. Creation and removal of files change the map of free disk sectors, which also requires synchronization.
Before you begin doing your lab assignment, you have to answer the following set of questions to ensure that you are ready to continue:
You will need to use the functions and the structures provided in filesys/file.[h|c] and filesys/filesys.[h|c]. So, clear understanding of what those functions are doing is essential for completing this lab assignment. You will also need to have a look into filesys/directory.[h|c] in order to get some ideas how the directory is implemented.
Implementation of the Pintos File System is already done in the following set of files:
Before you proceed to the implementation part of this lab assignment, answer on the following control questions:
Reads size bytes from the file with identifier fd into buffer. Returns the number of bytes actually read (0 at end of file), or -1 if the file could not be read (due to a condition other than end of file). Fd 0 reads from the keyboard. Several readers should be able to read from a file at the same time. However, reading should be forbidden if the file content is being changed by the writer.
Writes size bytes from buffer to the open
file fd. Returns the number of bytes actually written
or -1 if the file could not be written. Writing past
end-of-file would normally extend the file, but the file growth will
not be implemented. When fd=1 then the system
call should write to the console. Only one writer can write to a file
at the same time. The writer must not write if at least one reader is
reading from the file.
Opens the file called file. Returns a nonnegative integer handle called a "file descriptor" (fd), or -1 if the file could not be opened.
Within each process, every call to open returns a unique ID (even for the same file) and associates a distinct position for reading/writing.
It should not be possible to open the file, on which remove has been called but the actual deletion has not been done yet (for more details, look into the description of remove system call). This part of functionality is already implemented in Pintos (look into filesys/inode.[h|c]).
Closes file descriptor fd.
Sets the current position in the open file fd to position. If the position exceeds the file size, it should be set to the end of file.
Returns the current position in the open file fd.
Returns the file size of the open file fd.
Removes the file with the name file_name. Returns true if successful, false otherwise.
Note that the open files must not be deleted from the file system before they are closed. All the processes, which have this file opened when remove is called, can work with the file as usual until they close it. The operating system should wait until the file is closed by all processes, which have already opened it, and only then perform the actual deletion of the file content. In case the file has to be deleted but the actual deletion is postponed, no process can open this file. This part of functionality is already implemented in Pintos (look into filesys/inode.[h|c]).
Hint: Make sure that the relevant synchronization primitives for the readers-writers problem will be shared among all current and coming open instances of the particular file.
The following tests should pass if your implementation is correct in addition to the tests from Lab 2 and Lab 3:
tests/filesys/base/lg-create
tests/filesys/base/lg-full
tests/filesys/base/lg-random
tests/filesys/base/lg-seq-block
tests/filesys/base/lg-seq-random
tests/filesys/base/sm-create
tests/filesys/base/sm-full
tests/filesys/base/sm-random
tests/filesys/base/sm-seq-block
tests/filesys/base/sm-seq-random
tests/filesys/base/syn-read
tests/filesys/base/syn-remove
tests/filesys/base/syn-write
tests/userprog/close-twice
tests/userprog/read-normal
tests/userprog/multi-recurse
tests/userprog/multi-child-fd
In order to run the tests you need to do the following:
The expected output is in tests_output.txt file. All 66 tests should pass if the implementation is correct.
For testing your readers-writers algorithm, we provide the following user programs: pfs, pfs_reader, pfs_writer. These programs emulate several readers and writers accessing the same file. In order to run these programs, you should do the following steps:
The result is written into the messages file, which should only contain the word "cool" 500 times.
| Code directory: | src/userprog, src/filesys, src/devices, src/threads, src/lib, src/lib/kernel |
| Textbook chapters: | Chapter 10: File System Chapter 11: Implementing File-Systems Chapter 6.2: The Critical-Section Problem Chapter 6.7: Classic Problems of Synchronization Chapter 16.7.1 The Virtual File System |
| Documentation: | Pintos documentation related to Project 2 (Always remember that the TDDE68 lab instructions always have higher precedence) |
Before you demonstrate your laboratory work, remember the reader/writer problem is not the only synchronization problem you need to solve in this lab. Think about scenarios such as the simultaneous creation of two files of the same name in the same directory, or opening inodes at the same time. Add the necessary synchronizations to make sure the filesystem and the kernel are kept safe. Browse the code and find how these scenarios are handled and new possible tricky scenarios, then fix possible issues. The use of system wide, global locks or semaphores is allowed.
A previously, remember passing all the tests is not necessarily enough. You need to make sure yourself lab assistants won't point out any other issue.
[an error occurred while processing this directive]