This assignment is due on Tuesday, 1 May, no later than 11:30 p.m. See
the turn-in page (last modified on 2012 March 6) for information about turning in your
assignment.
In this fourth and last assignment, you will be implementing a simple file
system.
A file is a sequence of zero or more words; the size of a file is the
number of words contained in the file. An empty file contains no words
and has size zero. A file has no predefined maximum size; it may grow until
there’s no more disk space.
The words in a file of size n are addressed by the numbers 0 to n -
1. The first (or leftmost) word in the file is word 0; the last (or rightmost)
word in the file is word n - 1. If two words are adjacent in a file and
the first word is word i, then the second word is word i + 1; that
is, word address increase consecutively and sequentially from the first word of
the file.
A file pointer is a reference to a word in the file, or to the location
just past the last word in the file, which is known as the end of file
location.
When a file is opened, the file pointer references the first word in the file,
or end of file if the file is empty. Read and write operations take place
relative to the file pointer, and move the file pointer to reference the word
after the data read or written, or the end of file.
There is one file pointer per opened file. If a file is opened more than once,
it will have more than one file pointer; for example, a file opened three times
will have three file pointers. File pointers are independent of one another;
an operation affecting one of a file’s file pointers doesn’t
affect any of the other file pointers.
The file system is a simple, flat file system. A file is identified by a
32-bit integer called the file tag.
This assignment does not require any new interrupt handlers, although
you’ll probably have to add some code to your system-call interrupt
handler.
This assignment implements two new system calls — the
seek system call and the remove system call —
and extends the interpretation of the device system calls to cover files.
- open system call (
OperatingSystem.SystemCall.open
) - Open a file; register 1 should contain
OperatingSystem.FileIO.file
. Register 3 contains the integer identifying the file to open.
Register 2 contains a set of flags indicating how the file should be opened:
OperatingSystem.FileIO.read
- Open the file for reading.
OperatingSystem.FileIO.write
- Open the file for writing.
OperatingSystem.FileIO.create
- If the file doesn’t exist, create it and
then open it.
OperatingSystem.FileIO.exists
- Open the file if it exists.
OperatingSystem.FileIO.exclusive
- Open the file only if no other process
currently has the file open. Once a file has been opened exclusively, no
other open of any kind can succeed on the file until the opening process
closes the file.
OperatingSystem.FileIO.shared
- Open the file regardless of how many other processes
currently have the file opened. However, if the other process has the file
opened exclusively, the open with sharing will fail. Also, if a file is opened
for sharing, then it can’t also be opened exclusively.
The flag set may contain both reading and writing; if neither are given,
reading is assumed. The flag set may contain both create and exists; if
neither are given, exists is assumed. A file opened with create only must not
exists; if the file exists, the open should fail. A file opened with exists
only must exist; if the file doesn't exist, the open should fail. The flag set
may contain either exclusive or shared, but not both; if neither is given,
shared is assumed. If both shared and exclusive are given, the open should
fail.

After the open system call is completed, CPU register 0 contains the system
call status:
Hardware.Status.ok
- The command completed successfully.
Hardware.Status.deviceBusy
- The open request failed. The failure could be for
any reason, not just because the file was busy (for example, if a file that
doesn’t exist is opened without create, then the open request should
fail with status device-busy).
Hardware.Status.badDevice
- The value in CPU register 1 is not
Hardware.disk.device
,
Hardware.terminal.device
, or OperatingSystem.FileIO.file
.
If the open system call completed successfully, CPU register 1 contains a file
identifier, which must be included as an argument to other system calls related
to this file. If the open system call didn’t complete successfully,
the contents of CPU register 1 is undefined.
- close system call (
OperatingSystem.SystemCall.close
) - The currently executing process is closing its
connection to the file associated with the file id passed in CPU register 1.
The status code for the close system call is passed back to the user process in
CPU register 0.

After the close system call is completed, CPU register 0 contains the system
call status:
OperatingSystem.SystemCall.ok
- The command completed successfully.
OperatingSystem.SystemCall.badId
- The file id in CPU register 1 is not
associated with any file.
If the close system command completes successfully, the file id held by the
user process becomes invalid and may not usefully be used in any other
file-oriented system call.
- read system call (
OperatingSystem.SystemCall.read
) - Read data from the file associated with file id
given in CPU register 1. The data are read from the file starting at the word
referenced by the file pointer; the data are written starting at the address
given in CPU register 2. After the read, the file pointer references the word
immediately following the last word read to the file, or to the end of file.
The contents of CPU register 3 is the number of words to read from the file.

After the read system call is completed, CPU register 0 contains system call
status:
OperatingSystem.SystemCall.ok
- The command completed successfully.
OperatingSystem.SystemCall.badId
- The file id in CPU register 1 is not
associated with any file, or the file doesn’t allow reading.
OperatingSystem.SystemCall.badAddress
- The Primary Store address in CPU register
2 is bad.
OperatingSystem.SystemCall.badCount
- The contents of CPU register 3 is bad.
If the read system command completes successfully, CPU register 1 contains the
number of words read. The number of words actually read may be smaller (never
larger) than the number of words requested if the number of words from the file
pointer to the end of the file is less than the requested number of words to
read.
- write system call (
OperatingSystem.SystemCall.write
) - Write data to the file
associated with file id given in CPU register 1. The data are written to the
file starting at the word referenced by the file pointer; the data are read
from Primary Store starting at the address given in CPU register 2. After
the write, the file pointer references the word immediately following the
last word written to the file, or to the end of file. The contents of CPU
register 3 is the number of words to write to the file.

After the write system call is completed, CPU register 0 contains the system
call status:
OperatingSystem.SystemCall.ok
- The command completed successfully.
OperatingSystem.SystemCall.badId
- The file id in CPU register 1 is not
associated with any file, or the file doesn’t allow writing.
OperatingSystem.SystemCall.badAddress
- The Primary Store address in CPU register
2 is bad.
OperatingSystem.SystemCall.badCount
- The contents of CPU register 3 is bad.
If the write system command completes successfully, CPU register 1 contains the
number of words written. The number of words actually written may be smaller
(never larger) than the number of words requested if the disk becomes full.
- seek system call (
OperatingSystem.SystemCall.seek
) - Move the file pointer
associated with file id given in CPU register 1. The file pointer is offset
by the number of words given in register 3; this number may be positive or
negative (or zero). The location from which the offset is determined is
given by the contents of register 2, which contains one of the three
characters
'c'
, 'b'
, or 'e'
:
'c'
: Offset from the current file pointer location. If the
file pointer is pointing at word p in a file, and register 3 contains
i, then the file pointer will be pointing at the word p + i
after the seek call is done.
'b'
: Offset from the beginning of the file. If register 3
contains i, then the file pointer will be pointing at the word i
after the seek call is done.
'e'
: Offset from the end of the file. If the file contains
n words and register 3 contains i, then the file pointer will be
pointing at the word n - i after the seek call is done.
It is not an error to attempt to move the file pointer past either end of a
file; in such cases, the file pointer moves as far as it can and stops.

After the seek system call is completed, CPU register 0 contains the system
call status:
OperatingSystem.SystemCall.ok
- The command completed successfully.
OperatingSystem.SystemCall.badId
- The file id in CPU register 1 is not
associated with a file.
OperatingSystem.SystemCall.badAddress
- The direction given in CPU register
2 is not one of the characters
'c'
, 'b'
, or
'e'
.
Register 1 contains the number of the word being referenced by the file
pointer.
- remove system call (
OperatingSystem.SystemCall.remove
) - Remove (or remove) a file. Register 1
contains an integer file tag identifying the file to remove.

After the remove system call is completed, CPU register 0 contains the system
call status:
OperatingSystem.SystemCall.ok
- The command completed successfully.
OperatingSystem.SystemCall.badId
- The file tag in register 1 does not correspond to a
file on disk.
A file that’s opened can be removed; the remove should be delayed until
all opens on the file are closed. A file that’s undergoing delayed
deletion can be opened by other processes.
- The free space for each disk is located immediately after the paging
area and consists of the rest of the disk. Batch disks have fixed size, and
the amount of free space varies from disk to disk depending on the amount of
space taken up by programs.
- When reading a disk block that’s never been written, the block
returned contains all zeros. You can use this to tell if a batch disk contains
a file system.
pa4-simple-fio.dsk
- Contains a process that forks two other
processes. The first process forked creates a file and writes the filename
into the file. The second process opens the created file, reads its contents,
compares it to the filename, and removes the file. The processes are
self-checking; if there’s no output, everything went o.k.
$ java -ea -cp /export/home/class/cs-os/pa4/pa4-
YYMMDD.jar:.
\
main
os-class /export/home/class/cs-os/pa4/pa4-simple-fio.dsk
The system is halted.
Total execution time: 155 ticks, idle time: 63 ticks (40%).
$
pa4-double-simple-fio.dsk
- Runs the processes in
pa-simple-fio.dsk
twice.
$ java -ea -cp /export/home/class/cs-os/pa4/pa4-
YYMMDD.jar:.
\
main
os-class /export/home/class/cs-os/pa4/pa4-double-simple-fio.dsk
The system is halted.
Total execution time: 341 ticks, idle time: 136 ticks (39%).
$
pa4-bad.dsk
- Contains a process that tries to do bad things with
the file system. It is self-checking; if there’s no output, everything
went o.k.
$ java -ea -cp /export/home/class/cs-os/pa4/pa4-
YYMMDD.jar:.
\
main
os-class /export/home/class/cs-os/pa4/pa4-bad.dsk
The system is halted.
Total execution time: 176 ticks, idle time: 59 ticks (33%).
$
pa4-stats.dsk
- Contains some processes that try to determine
interesting information about the file system by creating and deleting lots of
files. It normally produces output.
pa4-bigfile.dsk
- Contains a processes that tries to fill up the
disk with a single file, deletes the file, and tries again.
This page last modified on 2012 April 12.