Programming Assignment 4 - File Management

Operating Systems, Summer 2002


Table of Contents

Due Date

This assignment is due on Sunday, 25 August, no later than 2:00 p.m..

Introduction

In this fourth and last assignment, you will be implementing a simple file system.

Files

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.

File Operations

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

The file system is a simple, flat file system. A file is identified by a 32-bit integer called the file tag.

Interrupt Handlers

This assignment does not require any new interrupt handlers, although you'll probably have to add some code to your system-call interrupt handler.

System Calls

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 (system_call::open)
Open a file; register 1 should contain device::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:

file_io::read
Open the file for reading.

file_io::write
Open the file for writing.

file_io::create
If the file doesn't exist, create it and then open it. If the file does exist, the open fails.

file_io::exists
Open the file only if it exists. If the file doesn't exist, the open fails.

file_io::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.

file_io::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. The flag set may contain either exclusive or shared, but not both; if neither is given, shared is assumed.

After the open system call is completed, CPU register 0 contains the system call status:

status::ok
The command completed successfully.

device::device_busy
The open request failed. The failure could be for any reason, not just because the file was busy.

device::bad_device
The value in CPU register 1 is not device::disk device::terminal, or device::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 (system_call::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:

status::ok
The command completed successfully.

status::bad_device
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 (system_call::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 to Primary Store 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:

status::ok
The command completed successfully.

status::bad_device
The file id in CPU register 1 is not associated with any file, or the file doesn't allow reading.

status::bad_address
The Primary Store address in CPU register 2 is bad.

status::bad_count
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 (system_call::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:

status::ok
The command completed successfully.

status::bad_device
The file id in CPU register 1 is not associated with any file, or the file doesn't allow writing.

status::bad_address
The Primary Store address in CPU register 2 is bad.

status::bad_count
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 (system_call::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 write system call is completed, CPU register 0 contains the system call status:

status::ok
The command completed successfully.

status::bad_device
The file id in CPU register 1 is not associated with a file.

status::bad_address
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 (system_call::remove)
Remove (or remove) a file. Register 1 contains an integer file tag identifying the file to remove.

After the write system call is completed, CPU register 0 contains the system call status:

status::ok
The command completed successfully.

status::bad_device
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.

Notes

Test Files

  1. 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.
    $ /e*/h*/c*/*5/S*/bin/os4 -Dins-cnts -d /e*/h*/c*/*5/d*/pa4-simple-fio.dsk
    
    The system is halted.
    Total execution time:  155 ticks, idle time:  63 ticks (40%).
    Op-code: count
      add:    65
     move:    38
     sysc:    14
     cmpr:    14
      beq:    14
    
    $ 
    

  2. pa4-double-simple-fio.dsk - Runs the processes in pa-simple-fio.dsk twice.
    $ /e*/h*/c*/*5/S*/bin/os4 -Dins-cnts -d /e*/h*/c*/*5/d*/pa4-double-simple-fio.dsk
    
    The system is halted.
    Total execution time:  341 ticks, idle time:  136 ticks (39%).
    Op-code: count
      add:   140
     move:    83
     sysc:    33
     cmpr:    32
      beq:    32
    
    $
    

  3. 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.
    $ /e*/h*/c*/*5/S*/bin/os4 -Dins-cnts -d /e*/h*/c*/*5/d*/pa4-bad.dsk
    
    The system is halted.
    Total execution time:  176 ticks, idle time:  59 ticks (33%).
    Op-code: count
      add:    60
      bne:    10
     move:    56
     sysc:    17
     cmpr:    16
      beq:     6
    
    $
    


This page last modified on 19 August 2002.