A hard drive is a stack of magnetic platters (show-and-tell).
Each platter is organized into concentric circles called tracks.
Each track is broken into sectors, each with some fixed number of bytes.
The time it takes for the magnetic head to find a track is usually called the access time.
The faster the platter spins, the faster data can be read/written.
We can treat the set of sectors as an array of blocks.
A logical block may actually consist of multiple disk sectors.
Hard drive organization
We can divide the blocks into one or more partitions. Each partition is treated like a separate disk (from the OS perspective).
On each partition (or more simply, each disk), we divide the blocks into three groups
The superblock -- contains info about how the file system is
organized, such as the number of inodes
The inode table -- struct containing size, owner, last mod time of a file (one inode per file)
The data area -- actual file contents are stored here, possibly across many blocks
Might want to draw array
Hard drive organization
Creating a file
What happens when we create a file?
E.g., when we type who > userlist
Creating a file
The kernel stores the file contents in the data area, in one or more blocks
Some properties of the file are stored in the inode for the file
Others (such as the name) are stored in the directory in which the file is placed
Creating a file
Creating a file
In more detail:
The kernel finds a free inode in which to record file properties
(e.g., inode 47)
Data blocks are allocated from a list of free blocks (e.g., 627, 200, and 992) and file contents are stored in them
The kernel records those block IDs (in that order) into the inode
The kernel records the entry (47, userlist) to the directory file.
Show inode numbers (using ls -ia) for root directory
Reading a file
In more detail:
The directory is searched for the filename of interest, which has a particular inode entry
The inode is read, telling the list of data blocks
Read the data blocks in order
What happens with large files?
Large files
We know that large files require many disk blocks, that the inode stores the list of disk blocks used, and that the inode is a fixed-size structure.
With large files, we use most, but not all of the block entries to refer to file blocks.
When we run out of regular data block entries, we use an indirect entry --
a pointer to a block that contains entries for more data blocks
When this indirect block fills, we use the next entry to store a double indirect block entry (points to a block with entries that point to blocks with entries pointing to data)
When the double indirect block fills, a triple indirect block is used
When the triple indirect block fills, the filesystem has been exhausted
Access to large files can be expensive (multiple levels of indirection)
Large files
Files in Directories
Thought Questions:
So, is a file really in a directory?
What happens when you rename a file? (e.g., with mv)
A single inode (refering to a particular file) can be listed in multiple directories (and even multiple times in the same directory). What does this mean? Does a file really have a name?
Relevant system calls
mkdir() - creates inode for directory file, writes . and .. entries in block allocated to file, and adds an antry in the parent node with the name
rmdir() - does reverse, and if directory is not in use, inode and data blocks are freed
unlink() - used by rm(1); removes an entry from a directory and decrements the link count
link() - used by ln(1); makes a new link with a specified name to an inode (but not to directories)
rename() - used by mv; typically uses link() and unlink()
chdir() - used by cd; changes the current directory of a process (i.e., the inode number)
pwd
How would you write pwd?
Full implementation is beyond the class; answer in Molay chapter 4
Multiple File Systems
UNIX file systems are made up of multiple disks (and often multiple partitions per disk).
Yet all appear within a single, unified, logical tree.
Each partition has its own file and directory tree (and thus its own inodes, etc.)
We can attach one partition to another by 'mounting' one to another
A mount takes the place of an existing directory
link() and rename() will fail when attempting to link across filesystems
Modern versions of mv will resort to copying and unlinking
Symbolic links (generated by ln -s can span filesystems and can point to anything (including directories)