280 likes | 555 Views
COS 318 - Operating System. Project 6 (Last!) File System Fall 2000. Overview. Why do we need a file system High-level abstraction of disk device Protected disk access Security measures Simple UNIX-like file system I-node Directory tree Multiple links to one i-node. Features.
E N D
COS 318 - Operating System Project 6 (Last!) File System Fall 2000
Overview • Why do we need a file system • High-level abstraction of disk device • Protected disk access • Security measures • Simple UNIX-like file system • I-node • Directory tree • Multiple links to one i-node
Features • We’ll be implementing the following: • File system creation/check • mkfs, fsck • Directories • mkdir, rmdir, chdir • Accessing a file • open (create if new), close, read, write, lseek • File link creation/deletion • link, unlink (delete if link count is zero) • Query file status • stat
Super Block i-Nodes Block Alloc Bitmap* Data Blocks Bootblock Kernel Procs File system structure • Structure of our file system • Superblock • Describes layout of i-Nodes, bitmaps, blocks, root directory, etc. • i-Nodes • Describes a file/dir – Link counter, list of blocks, size, etc. (owner, permission, …) • Block Allocation Bitmap • Data blocks *We use a bytemap
Super Block i-Nodes Block Alloc Bitmap Data Blocks Superblock • Describes the layout of the file system • signature – A magic number • size – Total size of fs in blocks • root_inode – The root directory • inode_start – 1st block for i-Nodes • inode_blocks – Total i-Nodes blocks • bitmap_start – 1st block of bitmap • bitmap_blocks – Total bitmap blocks • alloc_start – 1st block for data • num_blocks – Total data blocks • free_blocks – Count of unallocated blocks
Super Block i-Nodes Block Alloc Bitmap Data Blocks Bitmap • Bitmap • Indicates which data blocks are free, and which are used • Maps the data blocks only (not i-Nodes) • We actually use a bytemap (1 byte/block)
i-Node • Describes a file/directory • type – File, directory, or free • opens – Count of open file handles • links – Count of links to this i-Node • size – Total byte count • direct[6] – List of data blocks • indirect[3] – List of indirect blocks • direct[6] • First six data blocks in the file (a 32bit number) • indirect[3] • Successively indirect block lists • indirect[0] is block containing a list of next 128 data blocks • indirect[1] is block containing a list of next 128 block lists, each of which can hold 128 blocks… • …max file size: 6 + 128 + 1282 + 1283 blocks
Super Block i-Nodes Block Alloc Bitmap Data Blocks i-Node Actual Data Total Data Blocks = Actual Data blocks + Block List blocks i-Node Type, Opens, Links, Size direct[0] indirect[0] indirect[1] indirect[2]
i-Node • Files internally represented as i-Nodes • i-Node does not have a name • Directory entry = file name + i-Node # • Supports multiple links to a file naturally • Advantages • Fast access to small files • Supports very large files • Support sparse files
Directory • Directory is just a special kind of file • Use the same i-Node structure • Can read it like any other file • Comprised of a list of Directory Entries • Directory Entry • A character string of length 64 • Filename (32 chars), i-Node number in ASCII (31 chars) and trailing NULL • If the i-Node field is INVALID (“-1”), entry is considered empty • Default entries in a directory • “.” : the current directory’s i-Node • “..” : the parent directory’s i-Node
mkfs • Creates the file system (like ‘format’) • Set up the Superblock • Flag all i-Nodes as type free (f) • Zero out the Alloc Bitmap • Create the root directory • Flag an i-Node as type directory (D) • Store it’s number in Superblock • Alloc one block in the bitmap • Initialize the ‘.’ and ‘..’ directory entries and set the others as being INVALID mkfs D f f 1 0 0 . ..
fsck • Given! (But only for direct blocks) • Checks integrity of file system • Walks through all i-Nodes and records what blocks are referenced (allocated) • Compares the Alloc bitmap to the one derived from the i-Nodes • Walks through directory structure recording all i-Node types and link counts • Compares the strored types and link counts to those derived from the directory structure • …you only need to modify this if you do the Indirect Block extra credit option…
chdir • chdir <dir> • Changes the ‘working’ directory (workingInode) • You’ll have to parse <dir> for multiple directories (e.g. chdir ../dir1/dir2) • Paths are relative to working directory unless preceded by / (e.g. chdir /home)
mkdir • Creates a directory within the current working directory • Make sure the name is unique • Flag a free i-Node as type directory, point it to alloc’ed block • Set up the ‘.’ and ‘..’ entries • Insert directory entry in the working path’s directory entry list by extending its size or filling a hole. • Note: Due to rmdir, there could be gaps in directory entry list. • Note: The directory entry list could exceed the storage space of a single block. mkdir x D D f 1 1 0 . . .. .. x
rmdir • Remove a directory • Only remove if it is empty (i.e. only ‘.’ and ‘..’ exist) • De-alloc its blocks in bitmap • Set its i-Node to type free • Remove the directory entry from its parent • Note: This can create holes in the directory entry list. Set the i-Node # to INVALID to indicate the the slot is empty. • Note: If this creates no hole (i.e. the last entry on the list is removed) then the size should be decreased
File Descriptors • How do we control access to files? • File descriptors • We maintain a table of file descriptors in fs.c (but this should really be in the kernel) • Before we can read, write or seek within a file we must open it to obtain a file descriptor • open takes as argument RDONLY, WRONLY or RDWR and returns a file descriptor • read, write and seek take as argument the file descriptor • close releases the file descriptor • Only one file descriptor can have write access for a given file at any one time
File Descriptors cont’d • fdTable • Array of fileDescriptorEntry structures • fileDescriptorEntry • free – Indicates if the descriptor is in use • inodeNo – The i-Node of the open file • flags – RDONLY, WRONLY, RDWR • loc – The current position in the file
open • Acquires a free file descriptor for a given file • Initial seek location is 0 • If write access is requested, check that no other descriptor already exists with write access • Increment opens in the file’s i-Node • If write access is requested on a non-existent file, create an empty file • Get a free inode and set to type file • Insert a directory entry in the working directory • Do not allocate any blocks until data is actually written to the file
close, seek • close - Releases a file descriptor • Decrement open count in the file’s i-Node • Free up the file descriptor • seek – Modify the current position in file • The loc field in the file descriptor is the location in the file at which reading a writing take place • It is automatically incremented when read and write occur • seek manually adjusts this location • We can seek past the EOF thereby extending the size of the file. However, don’t allocate blocks until data is written. Until data is written, unallocated blocks are implicitly filled with 0 up to the EOF.
write • Writes a string of specified length to the current position in the file • This can either overwrite existing data, or extend the length of the file • All disk accesses occurs in block sized segments (1 block = 1 sector = 512 bytes) • If less than one block is to be written, the block should be read first, partially overwritten in memory, and then saved back to disk • When writing occurs in previously unwritten locations, new blocks must be allocated, and inserted into the i-Node’s block list • Files can be sparse (e.g. if we create a file, seek ahead several blocks, and start writing, the ‘seeked’ over blocks are not allocated)
read • Reads a string of specified length from the current position in the file • Reading cannot extend past the EOF • Reading could span over unallocated blocks since files can be sparse (such blocks are implicitly filled with 0)
link • We support multiple links to I-Nodes (of type file, only) • link <src> <lnk> creates a file called lnk which is attached to src’s i-Node • Subsequent accesses to lnk or src refer to the same file • Simply insert a new directory entry with lnk and src’s i-Node into the approriate directory entry list • Increment the link count in the i-Node link ../src lnk D D F 1 1 1 . . .. .. x lnk src
unlink • Removes a link to an i-Node • Simply remove the directory entry • Decrement the link count in i-Node • If count goes to zero, remove the file by freeing i-Node and its blocks • Note: You cannot unlink if the open count is non-zero…
stat • Returns statistics for given a filename • inodeNo – The file’s i-Node number • Type – File or directory • Opens – The open count • Links – The link count • Size – The byte count to EOF • numBlocks – Number of allocated blocks
Doing the project • Only need to deal with file/dir names immediately within current directory except in two cases (see code) • Only need to handle direct blocks for basic credit • You can do the file system completely on Linux. • To compile: “make 318sh” • To run: “./318sh” • Making the FS work with the OS is extra…
Extra Credit • Implement indirect blocks (3 levels). • fsck – You’ll have to fix this to work with indirect blocks • Support mount, umount • See text about adding to superblock • You’ll need to create support for multiple file systems… • Develop a disk caching system • Make the FS work with our OS!