File Systems and Mass Storage Structure
Prerequisite Knowledge
This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.
Previously Covered in This Subject
- File System Concepts: From Raw Disks to Volumes — file attributes, file operations, access methods, partitions, and volumes were covered in Lecture 14 (File Systems).
- Directory Structures — single-level, two-level, tree, and graph directories, including path naming, were covered in Lecture 14 (File Systems).
- File System Mounting and Virtual File Systems — mounting file systems at mount points and the layered VFS structure were covered in Lecture 14 (File Systems).
- Allocation Methods — contiguous, linked (FAT), and indexed allocation with the UNIX inode scheme were covered in Lecture 14 (File Systems).
This session wraps up the file-system implementation topics — directory structures, allocation methods, free space management, and the network file system — and then opens the mass storage structure: magnetic disks, their performance, and the three ways a disk attaches to a system. Disk scheduling and disk management are left for the next contact session.
Where we are in the course: Earlier modules covered the user's view of files — attributes, operations, access methods, and locking (the file-system interface). This session goes one level deeper: how the operating system actually organizes directories, places file contents on disk, tracks free space, and extends the file system across a network. The second half of the session moves down to the physical layer — the magnetic disk itself — because most of the remaining material (disk scheduling, disk management) is about it. The professor's running theme for the whole session: every abstraction we saw earlier sits on top of a disk, and the disk's mechanical behaviour decides what the file system can get away with.
The main path through the session runs as follows:
- File system structure — from a raw disk, to partitions, to volumes, to directories (15.1–15.3).
- Allocation methods — contiguous, linked (with FAT), and indexed (with UNIX's combined scheme), and when each is the right tool (15.4).
- Free space management — bitmap, linked list, grouping, counting, and ZFS space maps (15.5).
- The network file system (NFS) — mounting remote directories, stateless servers, RPC and XDR, path resolution, and caching (15.6).
- Mass storage hardware — magnetic disk anatomy, the performance formulas, the worked example, SSDs and tape (15.7–15.9).
- Disk structure and attachment — logical blocks, CAV vs CLV, host-attached storage, SANs, and NAS (15.10).
The session closes with the professor's answer to the standard question: the comprehensive exam carries both theory and problems, with the problem-style material (disk performance, disk scheduling, paging, segmentation, deadlocks, CPU scheduling) weighted more heavily than theory detail.
15.1 File System Concepts: From Raw Disks to Volumes
15.1.1 General File System Concepts
The general file system ideas were covered in the previous module, so most of them are already familiar from everyday use — every programming language and every operating system touches them. This subsection is a fast recap; the session spends its real time on what comes after.
A file is the named unit of stored information on secondary storage, and it carries a set of file attributes:
- Name — the symbolic string we type (for example,
report.txt). - Identifier — a unique tag, usually a number, by which the file system knows the file internally; it is the non-human-readable name.
- Type — needed on systems that support several kinds of files (source, binary, directory).
- Location — a pointer to the device and to the position of the file on that device.
- Size — the current size in bytes, words, or blocks.
- Protection — access-control information deciding who may read, write, or execute.
- Owner and timestamps — who created it, and when it was created, last modified, and last used; these are useful for protection, backup decisions, and usage monitoring.
File operations are the actions performed on files: create (find space and make a directory entry), open (search the directory and copy the entry into the open-file table), read (using a current-file-position pointer), write, reposition (seek — moving the pointer without I/O), delete (release the space and erase the entry), and truncate (erase contents but keep the attributes). Most operating systems expect open() before active use so that repeated searches of the directory are avoided; the open call returns a handle (called a file descriptor in UNIX, a file handle in Windows) used for all later operations.
Files also come in different file structures and file types:
- None — a stream of bytes with no imposed structure (the UNIX view).
- Simple record structure — a sequence of fixed-length records.
- Complex formatted structure — for example, a document or a database with internal structure managed by the application.
Access methods describe how we reach the data. Sequential access reads from the beginning onward, one record after another — the natural method for tapes and for logs. Direct (random) access jumps straight to any record using its relative position; disks support this directly because any block can be reached by moving the head and waiting for rotation. The professor's framing: sequential access is like reading a book page by page from page 1; direct access is like opening the book at chapter 7 without turning the earlier pages.
Locking types. When several processes share one file, the operating system may offer file locks. A shared lock behaves like a reader lock: several processes may hold it at the same time, so everyone can read together. An exclusive lock behaves like a writer lock: only one process at a time may hold it, so concurrent writers are serialized. Think of a shared lock as a shared textbook on a library table — many students may look at it together — and an exclusive lock as the same textbook borrowed out to one student alone. The professor notes this matters in any system where multiple processes touch the same file, for example a shared system log. Two refinements worth knowing: locks may be mandatory (the operating system refuses access to a locked file, as in Windows) or advisory (the OS does nothing; cooperating programs must check the lock themselves, as is common in UNIX), and careless locking can produce the same deadlock hazards as any other synchronization.
15.1.2 Raw Disks, Partitions, and Volumes
Disk structure is the starting point for understanding any file system. Without a file system, a disk is raw: just a bare device that can only be read and written in blocks. Raw disk is still used in special places — UNIX swap space uses a raw partition because it has its own format, and some databases format raw disk to suit their needs.
When the disk is raw, we can partition it into several parts, each of which can be treated as a mini disk. When a file system is placed on a partition, we call that partition a volume — the professor's picture is a vault: a volume is like a vault that contains folders, and each folder holds information or files.
The vault analogy. Picture a bank vault (the volume) with labelled folders inside (the directories), and documents inside each folder (the files). The vault is the unit you can own and lock; the folders are how you find things; the documents are the actual content. The analogy maps the whole chain: raw disk → partition → volume with a file system → directories → files. Where the analogy breaks: a directory can contain other directories (folders inside folders), and a vault can sit on a network somewhere rather than in the machine beside you.
On a typical machine with a C: drive and a D: drive, we first make partitions and then store information on them; each partition (volume) gets its own file system. Alongside this, the device holds some information directly — a device directory — which acts as the table of contents for the whole partition or vault: it records how many blocks the partition has, the block size, and the free-block information for that volume. In UNIX terms this volume-level information is called the superblock; in Windows NTFS it lives in the master file table. That is how the typical file organization looks: raw disk → partitions → volumes with file systems → directories → files.
15.1.3 Directories: Purpose and Operations
A directory is itself a file with respect to the UNIX operating system — a file whose "type" field marks it as a directory, and whose contents are the names and identifiers of the files it contains. Directories support a fixed set of operations:
- Search for a file — find the entry for a given name (and, often, match patterns).
- Create a file — add a new entry.
- Delete a file — remove the entry and free its space.
- List a directory — list the files and their entries.
- Rename a file — change the name, possibly moving the file's position in the structure.
- Traverse — walk from one file system to another, which is how backup and recovery tools visit every file.
Why organize the disk into directories at all? The professor gives three reasons, in order:
- Efficiency — with directories we can locate a particular file quickly. A flat pile of files would force a linear search of every name on the disk; the directory narrows the search to one small table.
- Convenience — if we keep folders named after a course or a project, the person using the machine finds things easily without remembering exact paths.
- Grouping — project-based information lives in a particular folder or directory, so files are grouped logically. That grouping is the main aim of the directory.
Takeaway: everything in this lecture hangs on one chain: a raw disk is partitioned into mini disks; a partition with a file system becomes a volume; a volume holds a device directory plus directories; directories organize files. When you see a drive letter or a mount point in an operating system, you are looking at the top of this chain.
15.2 Directory Structures
15.2.1 Single-Level and Two-Level Directories
The simplest arrangements are the single-level directory structure and the two-level directory structure.
In a single-level structure, one directory holds every file on the system; any two files need distinct names. It is easy to support and understand, but it fails as soon as the system has more than one user or many files. If two users both call their file test, the unique-name rule is violated. The professor's warning: the failure is not a theoretical curiosity — even a single user with a few hundred files quickly loses track of what is stored where.
The one-room dormitory picture. A single-level directory is like one room where every student's belongings share a single shelf: two people cannot both have an item called "notes" without collision. The natural fix is to give each person their own room — the two-level structure.
The two-level structure gives each user a directory of their own. The textbook machinery: a master file directory (MFD) is indexed by user name or account number, and each entry points to that user's user file directory (UFD), which lists only that user's files. When a user logs in, the system looks up their UFD; every reference searches only that UFD, so two users may each have a file named test without conflict. The trade-off: users are now isolated from each other. That is an advantage when users are independent, but a disadvantage when a team must cooperate — the two-level scheme gives no clean way to share a file between two users.
Both designs share a structural limitation: they offer no way to organize a single user's files into projects. Those disadvantages are the reason the next design, the tree structure, exists.
15.2.2 Tree-Structured Directories
The tree-structured directory is the hierarchy we all know from UNIX and Windows. The professor asks us to picture an inverted tree: the root sits at the top, the subdirectories are the internal nodes, and what we call the leaf of a sub-tree is at the bottom — the leaf marks the end of that branch of the hierarchy, whether it is the left tree, the center one, or the right tree.
(root)
/ | \
bin usr tmp
/ \
home shared
/ \ \
alice bob projects
/ \
docs os-lab
The tree has a root directory, and every file in the system has a unique path name from the root to it. A directory is simply another file — in UNIX one bit in each directory entry marks the entry as a file or a subdirectory — and each process keeps a current directory so that short relative path names work. The advantages of the tree structure are concrete:
- No naming conflicts. The same file name can appear in two different directories, and the same subdirectory name can appear inside two different subdirectories. There is no conflict because the full path disambiguates them —
/home/alice/docs/report.txtand/home/bob/report.txtname different files. - Per-user space. When a group of users is present, each user can be assigned a particular directory (a folder) and keep their files there; inside it they can build whatever sub-tree they like.
The slides cover how to create entries and how to delete them, and all the operations present in the tree level — the same behaviour we have seen in UNIX and Windows, so no command-by-command detail is repeated here. One policy point worth remembering: when deleting a non-empty directory, some systems refuse unless the directory is empty first (MS-DOS), while others offer a recursive delete of the whole sub-tree in one command (rm -r in UNIX) — more convenient, but dangerous because one mistake removes an entire branch.
15.2.3 Cyclic Graph and General Graph Directories
A cyclic graph directory is built from nodes that are connected to each other, like a general graph. The key rule for a cyclic graph structure is that a cycle must not form within the graph — forming a cycle is the problem the design must avoid — which is why it is called an acyclic graph: sharing is allowed, cycles are not.
The advantage of a cyclic graph is sharing. Suppose an organization has two groups — two different teams or domains — that must communicate through a particular file. A cyclic graph directory lets that one file be shared by the two groups: the same file (or subdirectory) appears in two places at once, but it is still one file, not two copies. If one group changes the file, the other group sees the change immediately; a new file created inside a shared subdirectory appears automatically in both views.
One file, two doors. The professor's mental model: a shared file is a single room with two doors. Both teams enter through their own door, but it is the same room — what one team moves inside is seen by the other. This is different from making two copies, which is the same room twice with no connection between them. Where the picture breaks: unlike a real room, deleting the shared item through one door also removes it for the other team — which is exactly the danger below.
The disadvantages follow directly from sharing:
- A mistake made by one group affects the other group too.
- If one team unknowingly deletes the shared file, the other team is left pointing at a file that no longer exists. This is called a dangling pointer — a directory entry that points to a file that is not there. That is one of the problems that must be resolved.
Pitfalls of the acyclic graph design:
- Dangling pointers. After a shared file is deleted, any remaining link references nothing. The textbook warns the situation is worse if the freed space is later reused: a dangling pointer containing a real disk address can end up pointing into the middle of an unrelated file.
- Aliasing. A file may have several absolute path names, so "distinct" names refer to the same data — the same problem as variable aliasing in programming. Tools that traverse the whole file system (backup, statistics, search) can count a shared file more than once unless they skip repeated visits.
- Cycle danger. The structure is called cyclic because the risk is that sharing, taken too far, produces a cycle; traversal algorithms must be written to detect and avoid cycles, which is why the general-graph step below needs special care.
So to build a proper acyclic graph directory, we have to overcome these difficulties. The general graph directory structure is mentioned next; most of the graph rules apply there as well, and the slides walk through it. In a general graph, cycles are permitted, and with them comes the harder problem of garbage collection — deciding when a file that can be reached through several paths is truly no longer needed.
15.2.4 Path Naming Across Operating Systems
Different operating systems represent the path to a file differently, and the session compares them:
- DOS: the path name is built from a drive letter and backslash-separated components — for example,
C:\userb\testnames volumeC, directoryuserb, filetest. - VMS (virtual management system): the volume is identified by a letter — C, for example — followed by a colon. The colon separates the volume from the directory, so the volume name reads like "C:". The directory is written inside square brackets, followed by the name of the file. The arrangement is: volume letter + colon, directory in square brackets, then the file name — for example,
C:[users.jdeck]login.com, withusersandjdeckbeing nested directories andlogin.comthe file. - UNIX: the volume name itself is treated as part of the directory name. The forward slash
/is the root from which the file system starts. Under the root we have, say,home, and insidehomea folder is created in the name of each user — that folder is also a file — and inside it we can create many subdirectories. This is how the arrangement works in UNIX: the path/home/alice/report.txtnames the file without ever mentioning a drive letter.
Scope note — where these conventions live. These naming schemes describe logical path syntax, not the physical placement of files on the disk. The same logical path can point to a file that is stored anywhere on a disk, a volume, or even a remote machine — the mapping from path name to physical block is the job of the allocation and mounting machinery in the next sections. Also note the path separators are not interchangeable: DOS uses \, UNIX uses /, and mixing them is a classic cross-platform bug.
The session does not go into the commands in depth, but notes that to search for a file we navigate to it and use the ls command to list; other commands give information about a particular file.
Takeaway: directory design evolves in steps — single-level (no naming freedom), two-level (per-user, but no sharing), tree (full hierarchy, but no sharing), acyclic graph (sharing via links, with dangling-pointer risk), and general graph (cycles allowed, but garbage collection gets hard). Each step buys a capability and pays for it with a new failure mode; the path-naming conventions of DOS, VMS, and UNIX are simply different syntaxes for the same tree idea.
15.3 File System Mounting and Virtual File Systems
15.3.1 Mounting and Mount Points
A partition often starts with no information in it. To make it usable we place a file system inside the partition, and for that the file system has to be mounted. Mounting means attaching a file system to an existing volume — that is the whole meaning of the term.
The room-within-a-house picture. Think of the existing directory tree as a house. A newly formatted disk is an empty shipping container delivered to the front door: its contents are not part of the house yet. Mounting is the act of welding a doorway between the container and a wall of the house — after that, you walk from the house into the container exactly as if it had always been a room. The wall where the doorway is cut is the mount point.
Mounting is a privileged operation: not everyone can do it, only super users can, and the file system has to be checked for correctness before it is attached. The operating system verifies that the device actually contains a valid file system (typically by reading its volume control block / device directory and checking the expected format) before it records the mount in its in-memory mount table. The mount point is the place where the file system gets attached; wherever we attach the file system, that location is called the mount point.
The textbook fills in the mechanics with two examples:
- Windows-style: each volume gets its own name space denoted by a letter and a colon (
F:); the system places a pointer to the file system in the device structure for that letter, and any path starting withF:traverses that file system. Newer Windows versions can also mount a file system at any point inside the existing directory structure. - UNIX-style: a file system can be mounted at any directory. The kernel marks the in-memory inode of that directory with a mount-point flag and points it to an entry in the mount table; the mount table entry holds a pointer to the superblock of the mounted file system. Because the flag lives in the inode, the operating system can traverse the whole directory tree and switch seamlessly among file systems of varying types without the user noticing.
Scope — what mounting does and does not give you. A mount attaches one whole file system at one directory; it does not merge two disks into a single pool of blocks, and it does not make the mounted file system share the mount point's original contents — the mounted file system covers the subtree rooted at that directory. And because the mount table lives in memory, mounting decisions are per-boot unless a configuration file (for example, /etc/vfstab in Solaris) restates them.
15.3.2 File System Types and the Virtual File System
File systems come in different types. The lecture distinguishes a file-layered file system from a virtual file system (VFS). The example is Linux, which uses a virtual file system.
Why do we need a layer between the user and the file system at all? A modern operating system must support several concrete file systems at once — on a Linux machine, ext4, FAT, NTFS, ISO 9660 for CDs, procfs for process information, and NFS for remote files can all be mounted at the same time. Writing separate directory and file routines for each type would be a maintenance nightmare. The VFS is the object-oriented answer: it defines one uniform interface, and each concrete file system supplies its own implementation behind it.
The Linux VFS works with only four objects, and each object represents a particular entity:
- an inode object — an individual file,
- a file object — an open file,
- a superblock object — an entire file system,
- a dentry object — an individual directory entry.
Every file in the file system falls into one of these four categories, and the VFS layer lets Linux support many concrete file systems behind one uniform interface.
How the four objects do the work. Each object carries a pointer to a function table — the addresses of the functions that implement that object's operations for the concrete file system behind it. When the VFS calls read() on an open file, it does not need to know whether that file lives on ext4, on FAT, or on a remote NFS server: it simply looks up read in that file object's function table and calls the implementation it finds. In textbook terms, the VFS also distinguishes local from remote files: local requests are dispatched to the file-system-specific code, while remote requests are handed to the NFS protocol procedures.
This is also the layer where a network file system plugs in: NFS rides on top of the VFS, so a remote file looks like just another file type. The three-layer NFS architecture in section 15.6.4 is the same idea made concrete.
Takeaway: mounting is a privileged operation that attaches a checked file system to a mount point inside an existing tree (marked by a flag in the inode in UNIX, a drive letter in Windows). The VFS is the uniform interface layer — four object types (inode, file, superblock, dentry) — that lets one operating system host many file systems, local and remote, behind a single set of system calls.
15.4 Allocation Methods
15.4.1 Contiguous Allocation and Fragmentation
Once the file system exists, we have to place each file somewhere. If memory is available the file can live there; otherwise we go to the secondary storage device.
The first method is continuous (contiguous) allocation: starting from one block, we allocate blocks continuously — two or three blocks, depending on the size of the file. The file's blocks sit side by side on the disk: if the file is blocks long and starts at block , it occupies blocks . The directory entry records the starting block and the length. This is the fastest way to read a file — sequential access rarely moves the head — and direct access to block is trivial: just read block .
Two ways space is wasted. The professor flags the fragmentation pair, and the exam-friendly distinction is:
- Internal fragmentation — wasted space inside an allocated block. One thing to note: we cannot allocate exactly the file's size. The file size rarely divides evenly into blocks, so the last allocated block is only partially used; every file leaves a little unused space at the end of its last block. That wasted space inside a block is called internal fragmentation.
- External fragmentation — wasted space between allocations. Across the whole disk, free spaces that are scattered here and there are called external fragmentation. If we collected all those scattered pieces, they could form a larger hole big enough for a useful file. External fragmentation bites when files are created and deleted repeatedly: the free space ends up broken into small chunks, and eventually no single chunk is large enough for a new file even though the total free space is ample.
Gathering the scattered free pieces means compaction: shuffling all the allocated blocks to one side of the disk and all the free spaces to the other side. Compaction is time-consuming and expensive, so it is not done every time; that is why we look at other allocation methods. The classic textbook picture of the whole problem: contiguous allocation is just the dynamic storage-allocation problem in another disguise, and the familiar first-fit and best-fit strategies for choosing a hole apply — both beat worst-fit, and first-fit is generally the fastest.
Scope — when contiguous allocation is acceptable. It fits files whose maximum size is known in advance and that rarely grow: IBM VM/CMS uses it for its performance, and some systems use extents — contiguous chunks that can be chained, so a file is a list of (location, count) extents rather than one run (the Veritas file system does this). The moment files must grow unpredictably — and the third block beside them is already owned by another file — contiguous allocation starts paying the extension price described in the Q&A below.
15.4.2 Linked Allocation and the File Allocation Table
Linked allocation is easy to picture. For a particular file, the directory entry mentions the starting block and the ending block — only the location (the address) of the first block and the address of the last block are stored. To read the file we follow the link from the first block to the second block, then to the third, until we reach the end. The blocks may be scattered anywhere on the disk: nothing forces them to be neighbors. Linked allocation is somewhat better than contiguous allocation because we are not going to waste any space — no internal fragmentation from partially filled neighbors, no need for compaction.
The costs are real, though:
- Pointer overhead. Every block must reserve space for the pointer (the address) that points to the next block. That space is overhead. The textbook gives the arithmetic: if a block is 512 bytes and a disk address takes 4 bytes, the user sees only 508 bytes of usable space per block — about 0.78% of the disk goes to pointers. The usual remedy is to group blocks into clusters (say, four blocks) and link clusters instead of blocks, so the pointer overhead is spread over more data — at the price of some internal fragmentation inside the last, partially filled cluster.
- Broken links. If one of the pointers gets cut — corrupted for any reason — we cannot find the path to the next block and the rest of the file is lost. There is no way to rebuild the chain from the surviving blocks.
- No efficient direct access. To reach block we must walk the chain from the start; each hop is a disk read. So linked allocation suits sequential access only.
Real-world: the FAT (file allocation table) is this idea made into a table. Instead of storing a pointer inside every block, a separate table — one entry per block, indexed by block number — holds the chain. The starting block number is given, and by following the table we reach the other blocks till we come to the end: the table entry for block 217 says "next is 618", the entry for 618 says "next is 339", and the entry for 339 holds the end-of-file value. An unused block is marked with a 0 in the table, so allocating a block is a matter of finding the first 0 entry. MS-DOS and OS/2 use FAT. The price: the disk head must travel to the table at the start of the volume to read a chain step, then to the data block — a lot of movement unless the FAT is cached in memory.
There is also a variation of linked allocation: the first block, the one pointed to by the file, holds the indexes of the other blocks where the information is present. We start from the first entry and, following the sequence, we reach and find the information. The drawback of that variation is that one block has to be reserved for the index — a block that could otherwise be useful for any other file. That is the problem with this linked variation.
15.4.3 Indexed Allocation and Multi-Level Indexing
Indexed allocation is familiar from database management: to map from the logical entity to the physical place where the file is present, we allocate some bytes specifically for an index table. One block is allocated for the index table. The index holds the displacements — the addresses of the data blocks — and to read data we first go to the index, then travel from the index entry to the block itself.
How to read an indexed file. Each file owns one index block, an array of disk-block addresses. Entry of the index points to block of the file, and the directory entry stores the address of the index block. To read the -th block, read the index block once, take entry , then read the data block it points to. The professor's DBMS connection is exact: an index table maps a logical position to a physical location, exactly as a database index maps keys to row locations. Direct access works without walking chains, and any free block on the disk can serve a growing file — so there is no external fragmentation.
The next level is multi-level indexing: two (or more) levels of indexing. The problem of indexed allocation is that the overhead of maintaining the index table itself is larger than the data blocks it describes — the index can cost more space than the file contents. The textbook's example: a file of only one or two blocks still needs a whole index block, and if an index block holds four-byte pointers, two levels of indexes address data blocks — files of up to 4 GB with 4 KB blocks. The professor's point stands: the index is a permanent per-file tax, whether the file is tiny or huge.
15.4.4 UNIX Multi-Level Indexing
UNIX combines the levels instead of picking one. The scheme has:
- Direct blocks: direct addresses to data blocks are stored in the file's metadata (the inode), but only a limited number of them — 12 in the classic layout, which covers small files of up to 48 KB with 4 KB blocks without any extra index.
- Single indirect block: after the direct entries, one single indirect block points to an index table, and inside that table are the addresses of the data blocks.
- Double indirect: two levels of indexing — the first level of indexing takes you to the second level, which then points at the data blocks.
- Triple indirect: three levels — we travel through three levels of index tables before reaching the data.
The idea: small files pay almost nothing (direct pointers only), while huge files can still be addressed through the indirect levels. Each level of indirection multiplies the addressable size by the number of pointers per block, so the scheme covers files far beyond what a single index block could address.
Inside a data block the record we want may not sit in the first position; we may have to search through the block to reach a particular record or a group of records. Indexing is key-based: entries are sorted on a key, and the index takes us to the particular data block. Even so, we may still have to travel inside the block — that travel is itself an overhead. The payoff is that we can locate data properly: with indexing the data is kept sorted and in sequence, and that is the advantage of this type of indexed allocation.
Student Q&A: which allocation method is better — continuous, index, or link?
Q: During memory allocation and de-allocation — de-allocation meaning the freeing of space — which is the more good way: continuous allocation, the index, or the link?
A: Each and every allocation method has its own advantages and disadvantages. Take continuous allocation: suppose the file size increases and the file needs to be extended. The first two blocks were allocated to it, but the third and fourth blocks may already be allocated to some other file. Some space may be there, but it may not be enough for the growing file. In that case we have to find the free space, transfer the contents of the second file to some other place, make the third block free, and place the growing file there. That is a time-consuming process. With the link method, the address itself takes some space, and following the pointers is another overhead — but the link method is somewhat better. Index-based allocation is also better, but the time taken to access the data block is more in that case. So we cannot say this one is best and that one is not; it depends on the requirement. If the number of records is large and they are already sorted, we can go for the indexing type. If the records are few and not sorted, then either the link method or continuous allocation. Again, it depends on the file size.
Q: With continuous allocation, when I delete some data, that freed memory will be of no use. So in that way the index method looks better.
A: Yes — that space cannot be used efficiently by some other file, because sometimes only one or two blocks are freed. Suppose four or five blocks are freed together; then they can be used for one particular file. So it depends on the number of records and the way they are stored. And remember: everything is stored on the disk, not in memory. Only when it is needed is it brought into memory.
Pitfalls worth keeping in mind:
- Extension cost (contiguous). Growing a contiguous file can force a move: copy the file to a larger hole and free the old blocks — expensive, and it can happen repeatedly.
- Pointer tax (linked). Every block pays 4 bytes (or so) for its next-pointer, and one bad pointer silently truncates the file — the professor calls this the broken-link failure.
- Index tax (indexed). Every file pays for a whole index block even if the file fits in one data block; access to a large file may require reading several index blocks before the data.
- Sorting assumption. The "indexing wins for large sorted records" rule assumes the data is actually kept sorted; unsorted data must be searched inside the block, and that search is overhead the professor explicitly counts.
Exam note — the decision rule the professor repeated: there is no universal "best" allocation method. Contiguous, linked, and indexed each trade space, time, and simplicity. The right choice depends on the file sizes, the number of records, whether the data is sorted, and how often files grow: large, sorted record sets → indexing; small, unsorted records → linked or contiguous; predictable, known-size files → contiguous. And on the exam, be ready to reason through the extension scenario: why a growing contiguous file forces relocating someone else's blocks.
15.5 Free Space Management
15.5.1 Bit Vector (Bitmap)
Whenever space is allocated, whatever is left over is tracked in a free space list. The list has to be tracked because the free blocks may later be allocated to a file that needs a block. Different file systems use different concepts for the free space list; the first one discussed is the bit vector or bitmap.
With the help of bits, we can find out which blocks are free and which are allocated. For a list of blocks, the bitmap is a string of bits such as 1 1 0 0 ... — here 1 means that particular block is free and 0 means that particular block is allocated.
A tiny worked bitmap. Suppose a disk has 32 blocks (blocks 0–31) and the free blocks are 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 17, 18, 25, 26, and 27 (the classic textbook example). The bitmap, read block by block, is:
Reading left to right, block 2 is free (bit 1), block 3 is free, block 6 is allocated (bit 0), and so on. A 1 at position means block is free.
To find a particular block number, the CPU does a small calculation. The professor describes it as: take the number of bits per word, multiply it by the number of zero-valued words (the words scanned so far), and add the offset of the first set bit — that gives the block number. The textbook confirms the same rule verbatim (number of bits per word × number of 0-value words + offset of first 1 bit), so the formula is:
Why the calculation works. Suppose each word holds 8 bits. The bitmap is scanned word by word; a word of all zeros means every block it covers is allocated, so we skip it, adding 8 to our running block count. The first word that is not all zeros must contain a free block; we find the first 1 bit in it and add that offset. For example, if the first three words scanned are all zeros and the fourth word is 01000000 (first 1 bit at offset 1), then:
which is exactly the 25th block. This is why hardware bit-manipulation instructions matter: the CPU needs the offset of the first set bit inside a word, and most modern instruction sets provide it directly.
The CPU performs this calculation to find the block number and retrieve the information. The problem: the bitmap itself requires space — we have to store all those bits, one per block.
The lecture works a concrete example. Suppose the block size is 4 KB, which is bytes, and the total disk size is bytes (1 TB). The number of blocks is:
Exam note: the computation is exactly the kind of small calculation to expect. Recognize the pattern: the number of blocks is always (disk size) ÷ (block size), and when both are powers of two, the answer is the difference of the exponents.
The professor then states the storage cost of the bitmap: with entries the bitmap takes about 256 MB, and if we combine blocks into clusters of 4 blocks, the bitmap takes about 64 MB. Making the blocks into clusters reduces the space needed for the bitmap to some extent — dividing entries by 4 gives entries, and MB.
Units — the professor's numbers versus the standard treatment. The 256 MB / 64 MB figures treat each bitmap entry as one byte. The standard treatment (and the textbook's) uses one bit per block: with blocks the bitmap is bits bytes MB, and with 4-block clusters it is bits bytes MB. The textbook states the same rule of thumb: a 1-TB disk with 4-KB blocks needs a 32 MB bitmap, and clustering by four cuts it to about 8 MB. On the exam, follow whichever unit the problem states — but if a problem says "bitmap," count one bit per block.
The only problem: we must first find the bitmap, then reach the file — but after reaching the block, the file content is there. The deeper limitation the textbook flags: a bitmap is efficient only if the whole vector fits in main memory (with periodic writes to disk for recovery); on very large disks, a full bitmap can itself be huge (a 1-PB file system would need a 32-GB bitmap), which is exactly the problem ZFS's space maps (§15.5.4) were designed to solve.
15.5.2 Linked List Free List
Another type of free space management is the linked list. The linked list gives us the list of free files and the list of allocated ones. Here, as we said for allocation, there is no wastage of space — but we cannot allocate blocks one after another easily, because we have to travel the whole list to find out how many free blocks there are and which ones have been allocated.
The free list head is stored, and from the head we walk the list: block 2 is free, next 3 is free, next 4, next 5, and again 8 is free — like this. In the textbook's picture, each free block holds a pointer to the next free block, and the head pointer (cached in memory) points to the first one; the pointer inside the last free block ends the chain. The entire list must be traveled every time, and that is the only problem in the linked-list type of free space management.
Cost of the linked free list. To count the free blocks or find how much contiguous space exists, the system must read every block on the chain — each hop is a disk read, so traversing a long chain is slow. The saving grace: allocating one block is cheap (take the head, follow one pointer, update the cached head), and traversal is infrequent. The FAT approach goes one step further: the free-block accounting lives inside the FAT itself, so no separate free-space structure is needed.
15.5.3 Grouping and Counting
Grouping improves on the plain linked list. We take a particular block — the first free block, say — and store in it the addresses of the next free blocks. If the first block is free, we take it, and we store how many free blocks there are: counting the first one, the remaining free blocks are recorded, and we also store the pointer to the first free block. Example: if 4 free blocks are there, , so the addresses of the remaining 3 free blocks are recorded. Like this we can group.
Why grouping is faster. With the plain linked list, finding many free blocks means many disk reads — one per block on the chain. With grouping, one read of the first free block yields the addresses of further free blocks at once. The textbook form is slightly different in detail: the first free block stores the addresses of free blocks, the first of which are really free while the last address points to the next group block — so each block read jumps a whole group ahead instead of one block.
Counting is a second approach: we keep the count of how many free blocks are there and the address of the first free block, and then we can allocate continuously. It exploits the fact that free blocks often come in runs: rather than storing every free address, store an entry of the form (address of first free block, number of contiguous free blocks following it). The professor highlights the difference between the two: in grouping we take the first free block and store the count of the remaining free blocks plus a pointer; in counting we store the address of the first free block and the count of how many free blocks are there, along with addresses. Any of these can be used by the operating system.
Grouping with real numbers. Suppose blocks 10, 11, 12, and 13 are the free blocks we are tracking. With grouping (professor's form): block 10 is taken as the group block; it stores addresses — 11, 12, 13 — plus a pointer onward. The next time the file system needs blocks, it reads block 10 and immediately knows about 11, 12, and 13. With counting: one entry "(start = 10, count = 4)" records the whole run; if later block 14 is also freed, the entry can grow to count 5 without any new addresses being listed.
15.5.4 Space Maps
The third type, the space map, is mainly used in the ZFS system (Sun's ZFS file system — the "Zeta 5" heard in the recording is the phonetic rendering of ZFS). First we have to consider metadata: everything except the data itself — all information with respect to the input/output — is stored in the file system. Metadata includes the directory structure, the free-space records, and all bookkeeping; the actual file contents are the data. The whole space is divided into many units called metaslabs. Many metaslabs are managed by a particular volume — a volume will have hundreds of metaslabs — and each metaslab has a space map.
The space map uses the counting algorithm we just saw: it records how many free blocks there are and their addresses. Everything related to block activity is recorded in the space map — it is, in the textbook's words, a log of all block activity (allocating and freeing), in time order, in counting format. When we need to know how many free spaces there are and what their addresses are, the space map is loaded into memory and indexed with the help of an offset; then it is checked, and the space is allocated to a particular set of bytes. In ZFS the in-memory structure is a balanced tree indexed by offset, and the log is replayed into that tree; contiguous free blocks are condensed into single entries. That is how the space map works.
Why ZFS bothers. A plain bitmap becomes a liability at ZFS scale: freeing 1 GB of scattered data on a 1-TB disk can force updates to thousands of bitmap blocks. Splitting the device into metaslabs (hundreds per volume) localizes the damage — only the affected metaslab's space map changes — and the counting format keeps each map compact. The professor's summary: the space map trades a little management overhead for a scheme that stays fast on enormous, heavily used file systems.
The problem: the space map itself occupies some space in memory, and first it is on the disk and later it is taken into memory. Everything has to be managed — even the metaslabs have to be maintained. That is the ZFS trade-off, but it is the scheme used in the ZFS system.
Pitfall — free-space bookkeeping is metadata, and metadata costs. Every free-space scheme spends some storage and some I/O to track free blocks: the bitmap's storage cost (one bit per block), the linked list's traversal cost (one read per hop), grouping's group blocks, counting's address+count entries, and ZFS's in-memory space maps. The recurring exam trap is mixing these costs: a bitmap's cost is space (bits), a linked list's cost is time (reads), and ZFS's cost is the memory and maintenance of the maps themselves.
Takeaway: the free-space list comes in four flavours — bitmap (1 = free, 0 = allocated; block number = bits per word × zero words scanned + offset of first set bit; blocks for the lecture's example), linked list (head pointer, slow traversal), grouping (one block holds further free addresses), and counting (first address + count of the contiguous run), with ZFS space maps applying counting inside metaslabs at file-system scale. All four exist because the disk is the slowest component: the free-space structure you choose directly decides how fast allocation can be.
15.6 Network File System (NFS)
15.6.1 The NFS Model: Remote Directories and Mounting
The network file system (NFS) is a type of file system where many workstations are connected: each workstation is an independent machine with an independent file system, and some information is shared among the file systems. When information is shared between the file systems of different machines, a remote directory has to exist, and every machine has its own local file system. The remote directory must be mounted over the local file system — only then can a particular user or machine access the file system that exists elsewhere, on an interconnected workstation.
Two properties follow. First, the information about the remote directory is not transparent: it is not available to every machine by itself. Only a super user can mount it into the local file system; after that, any user at the workstation can use it. Ordinary users cannot mount — mounting is a privileged operation. Second, the remote file system has to be mounted on top of the local directory; the professor stresses that this point is very important.
Why design it this way? Because it works on any type of machine, any type of operating system, any type of architecture — irrespective of all that, NFS can be used. The textbook makes the same point: one of NFS's design goals was to operate in a heterogeneous environment of different machines, operating systems, and network architectures, and that independence is achieved by building everything on RPC primitives over XDR (both described below).
The lecture's three-machine example. We have three independent file systems: U, S1, and S2. U is the local file system; S1 and S2 are two remote file systems existing on other workstations, and we must bring them to our local file system by mounting them. When we mount, the remote file system is attached into this view: on top of the local file system, the "shared" directory of S1 is mounted. After mounting (done by the super user), the "shared" directory cannot be seen as remote anymore — it now appears as a local file system under which there is a directory; that is what the picture shows. Similarly, "directory two" from S2 can be shared the same way, again mounted on top of the local file system; and S2 can be mounted on top of S1 — then, working under S1, the path looks like "user" under directory two. The textbook's canonical version of the same picture: mounting S1:/usr/shared over U:/usr/local means users on U reach everything inside with the prefix /usr/local/..., and the original U:/usr/local subtree is hidden underneath. A mount on top of an already-remote mount is called a cascading mount.
15.6.2 Mount Protocol and File Handles
How does communication take place between one workstation and another? With the help of XDR — external data representation — and the remote procedure call (RPC). The RPC is applied to transfer information between the file systems. In NFS, one side is a client — the local machine that wants the information — and the other is the server — the machine where the information is stored. The only things that have to be mentioned during the operation are the name of the remote directory and the name of the server machine where it is stored.
When a mount is requested, the client first sends a request; the server confirms it and returns a file handle. Only when the file handle is returned can the client proceed. The file handle consists of:
- a file system identifier, and
- an inode.
The inode identifies the mounted directory within the exported one — because the file system comes from the server, an identifier is needed to say where it is exported from and where it is going, and that is what is mentioned in the file handle. The textbook's framing: the file handle contains all the information the server needs to distinguish an individual file it stores — in UNIX terms, a file-system identifier plus an inode number. The server keeps an export list stating which file systems it exports and which machines may mount them (edited only by a super user). We use the NFS protocol for this mounting, together with a set of remote procedure calls. Once the RPC is confirmed between client and server, everything else can happen: searching for a file, reading a set of directories, manipulating or accessing file attributes, reading, and writing.
15.6.3 Stateless Servers and Concurrency Control
The servers in this design are stateless. Stateless means: once the request and response are over, the server keeps no information about the request or about the client. Every time, we must give the full set of arguments again — the file identifier, the position inside the file, the data — with every request. There are some versions that are stateful — they remember the client, so the full information need not be given again — but the stateless model is the core one.
Why stateless is a feature, not a bug. A stateless server needs nothing to recover after a crash: it has no open-file tables, no per-client session to rebuild — the next request just re-supplies everything. The textbook adds the fine print: because each request carries a sequence number, a duplicated or lost request can be detected, and operations are made idempotent so re-sending them is safe. The price of statelessness is paid in argument bytes: every request must repeat its full context, and (as we will see) path resolution must be repeated rather than remembered.
One thing to note: NFS does not provide any concurrency control mechanism. Concurrency means more than one user trying to operate on a particular file. If the users are only reading the file, it is okay. But if two or three workstations have two different users trying to access a particular file on some other workstation and trying to manipulate it, there is no concurrency control in NFS to coordinate them.
Scope — what NFS guarantees and what it does not. NFS guarantees that a single write procedure call is atomic, and that a server crash is invisible to the client (the server must commit modified data to disk before answering). It does not guarantee that two users' writes to the same remote file stay unmixed — a write() from one user may be split into several RPCs, and the server can interleave another user's RPCs between them. The textbook's advice matches the professor's: users who need coordinated access to a shared file must use locking mechanisms outside NFS (for example, the lock service of the local operating system).
15.6.4 NFS Architecture: Three Layers, XDR, and RPC
Based on the architecture, NFS has three layers:
- the VFS interface — the top layer,
- the file system interface layer — the middle layer,
- the service layer — the bottom layer.
The file system interface carries out the system calls — open, read, write — and works out which calls are local and which are remote. The client sits on one side, the server on the other, and the network lies between them. When a system call such as open is made, the VFS first tries to find out whether the target is in the local file system. If it is local, the data is taken from the disk and given back. If it is not in the local file system but represents some other type of file system that exists on the same system, the information is taken from that same system. Otherwise the file is treated as NFS: the VFS acts as a network file system client and makes an RPC.
The data being sent as a request is not understandable by the server, so it has to be converted into a common representation — that is what XDR, the external data representation, is for. Through XDR and the RPC, the information is sent to the server, and when it arrives it is unpacked so that the particular server can understand it. The NFS on the other side acts as a server: it takes the information, finds it in its local file system, and gives it back. The response comes back through the same path — it is packed on the server side and unpacked on the client side. That is how NFS works end to end.
The professor connects this to Java: in Java we used to call the two sides of an RPC the stub and the skeleton — the stub is the client side and the skeleton is the server side.
The language problem and XDR. Two machines can exchange RPCs only if they agree on how data is represented: integers (big-endian or little-endian?), strings (length-prefixed or terminated?), floating point (which format?). XDR is the neutral, machine-independent representation both sides convert to: the client packs its request into XDR before sending; the server unpacks it on arrival, and packs its reply the same way on the way back. This is precisely why NFS can run across different machine architectures — the same trick the professor's Java stub/skeleton pair performs for remote method calls.
15.6.5 Path Name Resolution in NFS
We should know how to resolve a path name — this is with respect to the UNIX file system, where the path starts with a slash /, the root. First we have to find whether it is the root directory; if it is the root, we find the next name that is present; the directory entries are separated with the help of the front slash. This is how we break up and translate the path name when we perform a lookup operation in the network file system.
We first have to reach the mount point: after the root we go to "user", and there the mount point sits. From that place we have to find where "local" is present. For each component, we take the component out, check the name, and find out where it is present. Because this is a network file system, each of these lookups requires an RPC: as many RPCs as the number of directories or subdirectories used in the path. That makes path translation a very expensive scheme. If, once we find one thing, we can find all the other subdirectories easily, the scheme becomes somewhat efficient. And if the server keeps no state, it is another burden: all these translations have to be repeated every time a request comes from any client to the server.
Counting the RPCs. Consider the path /usr/local/dir1/file.txt. The path splits into components: usr, local, dir1, file.txt. To resolve it, the client performs one NFS lookup RPC per component after crossing the mount point — usr by one RPC, local by a second, dir1 by a third, file.txt by a fourth. Four path components, four network round trips. The textbook's numbers: a path like this needs a separate lookup call for every pair of component name and directory vnode, and the cost cannot be avoided because each client's name space is shaped by its own mounts — a server cannot resolve the whole path itself since it does not know the client's mount layout.
NFS follows the paradigm of the remote service. There is no direct correspondence between the remote operation and the RPC — every time, with the help of the RPC, we have to find out that file block and the file attributes. One practical remedy: if we are going to use the same file again, we can keep it locally — if it is kept locally, there is no need to go for the remote operation every time and no need to make an RPC every time. The client-side directory-name-lookup cache does exactly this: it remembers the vnodes for recently resolved remote directory names, so a repeated reference to the same initial path portion hits the cache instead of the network. The cache is discarded when the server's attributes no longer match the cached entry.
15.6.6 Caching: Attribute Cache, Read-Ahead, and Delayed Write
To cache information, we can use either a file attribute type of cache or a file block cache. When we try to open a particular file, we check with the remote server — where the file is present — whether the attributes are proper. Only after checking the attributes can the file blocks be used. That means the file attribute has to be up to date, so it has to be updated regularly: after every 60 seconds, whatever has been cached is rechecked, and the new attribute is updated if we try to use the file. This 60-second timeout is the standard NFS attribute-cache behaviour: cached attributes are, by default, discarded after 60 seconds, and the cached file blocks are trusted only while the cached attributes are current.
For the actual transfer we can use read-ahead and delayed write techniques. Delayed write means the update is not performed as soon as every change happens: after making a set of changes, after a period of time, the system checks whether the data is up to date; if it is not, whatever has been updated so far on the disk is reflected in the file attribute cache. This is how remote file operations can be performed easily with the help of these caches.
The consistency price of caching. Every cache weakens consistency: a new file created on one machine may not be visible on another for up to 30 seconds, and a write at one site may not be visible at another site that has the file open for reading. New opens only see changes that have already been flushed to the server. The professor's practical summary — and the industry rule of thumb: if we are going to use the same file again, keep it locally and avoid repeated remote operations; the caches exist to make the common case fast, and their staleness is the accepted trade-off. NFS provides neither strict UNIX semantics nor session semantics; it buys utility and performance.
Beyond NFS, the textbook works through two example file systems in detail: the virtual file system (VFS), which we already saw in section 15.3, and one more whose name came through the source unclearly — it is the WAFL (write-anywhere file layout) file system from Network Appliance, a file system optimized for network file servers, best known for its snapshots. (The name heard in the recording resolves to WAFL; the same design family also includes log-structured ideas, but the textbook's second worked example is WAFL.)
15.6.7 Student Q&A: RPC in Industry Practice
Q: We use RPC at work — it is used to call HTTP endpoints. We did not study RPC in any course; I use it for working purposes. I work on cloud development, and mainly in Golang we use RPC. It is more secure than HTTP.
A: Which course did you study it in? ... Which platform are you working on? ... So you work on cloud development and you use RPC there, mainly in Golang, and you find it more secure than HTTP. These are general concepts — they are not related to any one particular language. Others — is there any doubt?
The professor's answer makes the course-agnostic point: RPC is a general mechanism, not a language feature. The student's example is exactly how RPC is used today — cloud development platforms use RPC (for example in Golang services) as a communication mechanism that practitioners often find more secure than plain HTTP — but the underlying idea (call a function that executes on a remote machine, with the stub on your side and the skeleton on the other) is the same one NFS uses and the same one Java's RMI illustrates.
Takeaway: NFS shares directories across independent workstations by mounting a remote directory on top of a local one (super-user operation), identifying remote files with file handles (file-system identifier + inode), serving requests from stateless servers that repeat full arguments and offer no concurrency control, and paying one RPC per path component — mitigated by attribute, block, and directory-name caches with a 60-second attribute revalidation and read-ahead/delayed-write transfer.
15.7 Mass Storage: Magnetic Disk Fundamentals
15.7.1 Magnetic Disk Anatomy and Terminology
Magnetic disk is a form of secondary storage — we already know the difference between primary and secondary storage (primary = main memory, fast and volatile; secondary = persistent storage, slow and cheap). The lecture focuses on the magnetic disk because most of the remaining material is about it; magnetic tape gets an overview only.
The anatomy of a disk drive: we have an arm assembly with many disks combined together with the help of a spindle — the center piece. The spindle rotates, and the rotation makes the tracks move and lets the arm find the desired sector within the tracks. Each arm is attached to each disk, on both ends, because both surfaces of every disk are readable — a drive with platters carries read-write heads, one per surface. On each surface we have many concentric circles, and the concentric circles are called tracks. Interconnecting each circle with the corresponding circle on every other disk forms a cylinder.
The cylinder is imaginary. The professor's point (and the textbook's): a cylinder is the set of all tracks at the same radius across all the platters — the track on surface 0 at radius , the track on surface 1 at radius , and so on. Nothing physical connects them; the concept is useful because the arm moves all heads together, so when the head on surface 0 sits over its track at radius , every other head is simultaneously positioned over its own track at the same radius. Addressing by cylinder (rather than by individual track) lets the drive read all those tracks with one arm movement.
____ side view: | platter 1 (surfaces 0,1) |
| platter 2 (surfaces 2,3) | <- spindle through the center
| platter 3 (surfaces 4,5) |
arm moves all heads together; heads at the same
radius on every surface -> one imaginary cylinder
Moving from the inner track to the outer track, the number of sectors increases — each track is divided into sectors, and outer tracks hold more sectors than inner tracks. The bit density moves the other way: the density of bits per track is higher in the inner zone and lower in the outer zone. That is the difference. (The mechanism behind it is the topic of §15.10.2 — CAV vs CLV.)
Head crash = whole disk replaced. The head flies over the surface on an extremely thin cushion of air. If the arm crashes, or the surface of the disk is corrupted because of the arm, the damage cannot be repaired in place: a head crash normally cannot be repaired — the entire disk must be replaced. The professor's practical warning: this is why disks are sealed units and why reliable backups exist — the failure is catastrophic and sudden, not gradual. (This is a hardware warning, not a beginner mistake — it belongs to the disk's scope and limits.)
15.7.2 Seek Time, Rotational Latency, and Access Time
Two times dominate disk performance. Seek time is the time taken to move the disk arm to the desired cylinder (track). Because the disk is rotating, the desired block — inside a sector, inside a track — may not be under the head yet; rotational latency is the time taken for the disk to rotate until the head is placed on the desired sector. These two together give the random access time — the time taken to find the block.
The record-player picture. Think of a vinyl record on a turntable: the arm (tonearm) must first swing over to the right groove — that swing is the seek. But the music starts only when the needle lands at the beginning of the song, and the record is spinning — if the song's start just passed under the needle, you wait almost a full rotation for it to come around again. That waiting is the rotational latency. Both together — swing plus wait — are the access time. Where the analogy breaks: a disk drive's arm can stop anywhere and the "songs" (sectors) are all the same short length, but the two-phase picture is exactly right.
Apart from these, some other overheads exist (transfer time and controller overhead — both measured in the worked example of §15.8). The drives attach to the system through different I/O buses — Fibre Channel, SCSI, and the like. Every system has a host controller, which communicates with the disk controller present in each and every disk: through the host controller, the communication happens with the system; through the disk controller, the communication happens with the disk. (The three attachment schemes of §15.10 are built on these buses.)
15.7.3 Disk Performance Metrics
Common performance metrics apply to any type of disk:
- Transfer rate — the rate of flow of data between the system and the drive. Theoretically this is about 6 GB per second as stated in the source; in this lecture's convention "GB" in that phrase means gigabits per second (the same convention used in the §15.8 worked example, where 1 Gbps is given). Read as 6 Gbps — roughly the interface speed of a modern SATA link — while real sustained data rates are lower because the head must actually read the bits. (Interface speeds such as 6 Gbps are bus limits; effective transfer rates are media-limited and smaller.)
- Positioning time / random access time — the time taken to find the block, made of seek time plus rotational latency.
Several formulas go with these metrics. The average seek time can be measured with the help of one third of the number of tracks:
The reasoning: if a request can be anywhere and the head starts anywhere, the expected distance is about one third of the full travel — the maximum seek divided by three. It is a rule-of-thumb estimate, not a physical law; manufacturers quote measured average seek times (typically under 10 ms on modern disks).
The latency — the time for one full rotation — depends on the spindle speed, given in rotations per minute (RPM). Converting minutes to seconds:
Half of that latency gives the average latency (average rotational delay):
Why half? The desired sector can be anywhere around the circle when we arrive; on average it is halfway around, so the average wait is half a revolution.
The random access time (the lecture warns it should not be called "average access time" when a specific transfer is meant) is:
For the fastest disks the seek can be at most about 5 milliseconds; slower disks take longer. If the problem gives you some information and asks for the random access time, combine these pieces.
Throughput is the number of input/output operations per second multiplied by the transfer size:
If the throughput is given, fine; if it is not required, leave it. To find the average I/O time:
The controller overhead is the host controller overhead or the disk controller overhead — in a disk-transfer problem it would be given. Note the structure: the I/O time is the positioning time (seek + latency) plus the data movement time (transfer) plus the electronics time (controller overhead). The textbook's equivalent formulation is , where is rotations per second and is bytes per track — the same three ingredients.
If the data transfer rate is not given, it can be computed. The professor's formula: the transfer rate is the number of heads times the capacity of one track times the number of rotations per second:
Notation check — the professor's transfer-rate form. The professor includes the number of heads in the formula, which suits a drive reading a whole cylinder across all its surfaces at once (all heads transfer in parallel). The standard form for a single surface, as in the textbook, is simply
The two agree when the question is about one head; multiply by the number of heads when the problem says a full cylinder is read. On the exam, use the form that matches how the problem counts surfaces.
If values are in minutes, convert to seconds — whatever is required, we do that. And the capacity of one track comes from the number of sectors per track and the number of bytes per sector:
So: with the number of sectors per track and bytes per sector, find the track capacity; with track capacity, the number of heads, and the rotations per second, find the transfer rate. These are all small pieces that a question can ask for.
Exam note — the formula chain. The professor explicitly says this disk-performance material is expected to carry one problem question — "based on this, you can expect one question." The chain to memorize: rotation time → average latency is half of it → random access time = average seek + average latency → average I/O time = access + transfer + controller overhead; and track capacity = sectors × bytes → transfer rate = heads × track capacity × rotations per second → throughput = I/O per second × transfer size.
15.7.4 Hard Disk Specifications
Hard disks come in known specifications. The platter diameter (the diameter of one full circle of the disk) can vary from 0.85 inches to 14 inches; the commonly used ones are 3.5, 2.5, and 1.8 inches. The space per drive starts from 30 GB and goes to 3 TB, and now it is more (the "3 dB" heard in the recording reads as 3 TB). The spindle speeds — the rotations per minute — have some typical values, which are mentioned in a table: 4,200 RPM, 5,400 RPM, and so on. Depending on the speed, the vendor mentions the RPM of the spindle and sometimes the transfer rate, and we have to find the seek time or the latency ourselves.
For the common RPM values, remember the small table — the lecture gives one value as an example: for 7200 RPM, the average latency is 4.17 ms. Check it with the formula: ms per rotation, half of that is 4.17 ms — the formula and the table agree. The table has only about five values, and it makes problems faster. If the rotation time is given directly, apply the half formula; otherwise assume the values from the table. That is all there is to it.
The five common RPM values, computed from the formula.
| Spindle speed (RPM) | Rotation time | Average latency (half) |
|---|---|---|
| 3,600 | 16.67 ms | 8.33 ms |
| 4,200 | 14.29 ms | 7.14 ms |
| 5,400 | 11.11 ms | 5.56 ms |
| 7,200 | 8.33 ms | 4.17 ms |
| 10,000 | 6.00 ms | 3.00 ms |
Sense-check: faster rotation means shorter rotation time and shorter average latency — 7,200 RPM is a common desktop drive, and its 4.17 ms is the value the professor quotes; the textbook's 7,500 RPM example gives an average rotational delay of 4 ms, in the same neighbourhood.
The source also mentions historical information about the first commercial disk drive: when it was invented and by whom, how many characters it can store, what the diameter of the platter was, and what the access time was. These facts are on the slides and are worth knowing as background — the key takeaway is how far the technology has come from that first drive to today's multi-terabyte drives.
15.8 Hard Disk Performance: Worked Example
15.8.1 Problem Setup and Given Values
The lecture works a complete problem: transferring a 4 KB block. The given values are:
- block to transfer: 4 KB,
- spindle speed: 7200 RPM,
- average seek time: 5 ms (given),
- transfer rate: 1 Gbps (given — the professor explicitly notes that GB here is gigabits per second, and the block size is in kilobytes, so we multiply by 8),
- controller overhead: 0.1 ms (given).
We have to find the average access time.
The professor sets up the formula: the average access time is the average seek time plus the average latency. Written elaborately, it is the average seek time plus the average rotational delay — the lecture notes both names mean the same thing — plus the other factors, namely the transfer time and the controller overhead. So:
The structure is the same one from §15.7: positioning time (seek + latency) plus data movement (transfer) plus electronics (controller overhead).
15.8.2 Transfer Time Computation
First we need the transfer time. The transfer time is the size of the block divided by the transfer rate:
The units need care — and the professor calls this step very important. The block size is in kilobytes (bytes), while the transfer rate is in gigabits per second (bits), so:
- Multiply the block size by 8 to convert bytes to bits: .
- Convert the rate to the same unit: from giga we go to mega, and from mega to kilo, multiplying by 1024 each time — .
Putting it together:
Every digit of the transfer-time computation.
Step 1 — bytes to bits. of data carries Kbit of bits (each byte = 8 bits).
Step 2 — align the units. The denominator must be expressed in Kbit per second:
Step 3 — divide:
Step 4 — evaluate. seconds, i.e. s — the professor walks the class through the decimal: "you get four zeros, then 3, 0, 5" — which converts to about 0.031 milliseconds:
Sense-check: 1 Gbps transfers bits per second, so 32 Kbit is a tiny fraction of a second — one millisecond of data at 1 Gbps is bits, and 32 Kbit bits is about 3% of that, giving roughly 0.03 ms. The answer is in the right ballpark.
Exam note — the units trap. The byte-to-bit conversion (multiply by 8) and the giga → mega → kilo conversion (1024 twice) are exactly the traps a problem question can check. Remember to multiply by 8 first. The common failure mode: dividing 4 by 1 and reporting 4 seconds, or dividing 4 KB by 1 Gbps without converting — both are off by orders of magnitude.
15.8.3 Average Rotational Latency
The average latency, or average rotational delay, is half of the latency, and the latency is the time taken to make one full rotation:
For 7200 RPM:
which is the table value for 7200 RPM from §15.7.4. If the time for one full rotation is given in the problem, apply the formula directly; if not, take the value from the table for the five common RPM values.
15.8.4 Final Average Access Time
Now put every piece into the formula:
The average access time for transferring the 4 KB block is 9.301 ms.
The full worked problem, end to end.
Given: block = 4 KB, spindle = 7200 RPM, average seek = 5 ms, transfer rate = 1 Gbps, controller overhead = 0.1 ms. Find the average access time.
- Transfer time: Kbit; Kbit/s; .
- Rotational latency: one rotation ; average latency .
- Add everything:
Answer: 9.301 ms.
Sense-check: the seek (5 ms) and the rotational wait (4.17 ms) dominate — together 9.17 ms — while the actual data movement (0.031 ms) is nearly free and the controller adds 0.1 ms. This matches the textbook's recurring observation that seek time and rotational latency dwarf transfer time for small transfers. A different transfer size would barely change the answer; a different RPM or seek time would move it substantially.
The class is asked whether there is any doubt about the computation; there is none, and the professor repeats the useful summary: average rotational delay is half of the latency, latency is the time for one full rotation, and if the data is not given, assume the values from the table.
Exam note — expect a problem like this. The professor says the comprehensive exam can carry a problem of exactly this shape: given block size, RPM, average seek time, transfer rate, and controller overhead, compute the average access time. The recipe never changes: convert bytes to bits (×8), align units (1024 twice), halve the rotation time, then add seek + transfer + latency + overhead. The lecture's own answer: 9.301 ms.
15.9 Solid-State Drives and Magnetic Tape
15.9.1 Solid-State Drives (SSDs)
After the first commercial disk drives came solid-state drives (SSDs). Their advantages: they are reliable, and they are non-volatile — even if the power is switched off, the information is still there. The problem: even for a small SSD you have to pay more; the capacity is smaller for the price, but it is faster. In some systems the operating system itself is loaded from an SSD.
Why an SSD feels so much faster. A hard disk drive spends its time moving: the arm seeks, the platter rotates. An SSD has neither — no seek time and no rotation delay — those delays do not exist, so it operates directly and is faster compared to hard disk drives. Every formula of §15.7 and §15.8 simplifies drastically: the seek term and the latency term vanish, and what remains is effectively the transfer itself. That is why the professor notes that some systems load the operating system from an SSD: boot time is dominated by thousands of small reads, exactly the workload where removing seek and latency helps most.
Real-world: SSD boot drives are standard in modern systems precisely because the OS loads faster without seek time and rotational latency. The trade-off the professor states is the enduring one — price per gigabyte is higher and capacity per drive is smaller for the same money — which is why big storage pools still mix media: an SSD for the hot, frequently-read data (the OS, active files) and magnetic disks for bulk storage.
15.9.2 Magnetic Tape
Magnetic tape is very old — it was the first secondary storage medium. It evolved from open reels to cartridges, and it is capable of holding a large quantity of data; it is also permanent. The problem is the time taken to access the information: the professor states it is about a thousand times slower than the disk — "thousand times less" — so imagine how slow that is. In order to speed up operations, the industry went for magnetic disks and solid-state types instead.
Scope — when tape is the right medium. If we are not going to use the data frequently, or if we have to make a backup, magnetic tape is the choice: it is cheap. The transfer takes more time, so it cannot be used for commercial purposes — just for storage. The textbook agrees on both counts: random access to tape is about a thousand times slower than random access to disk, so tapes are not useful as working secondary storage, but they are used mainly for backup, for infrequently used information, and for moving data between systems — and once positioned, a modern tape drive (for example LTO) writes at speeds comparable to disk.
Real-world: tape remains the standard medium for long-term backup archives, where cost per terabyte matters more than access speed. The professor's cost ladder runs the other way from the performance ladder: RAM is fastest and most expensive, SSDs next, hard disks after, and tape cheapest per byte — so the industry allocates data by how often it is touched, exactly the principle behind backup tiers that spill cold data onto tape.
15.10 Disk Structure and Disk Attachment
15.10.1 Logical Disk Structure: Blocks, Sectors, Cylinders
Think of a disk drive as a one-dimensional array. In that array, each element is a logical block — the smallest unit of data transfer (usually 512 bytes, sometimes 1,024). Whenever a disk is formatted, these blocks are created. The blocks are mapped to sectors sequentially: this block after that block, each belonging to one particular sector. Sector zero is the first sector of the first track of the outermost cylinder. From there the mapping proceeds: we can move through the other tracks of that cylinder, then from cylinder to cylinder, from the outermost cylinder to the innermost cylinder — that is how the logical blocks are traversed.
Why the one-dimensional view matters. The file system never talks about cylinders, tracks, and sectors directly: it asks for "block 1234", and the disk hardware translates that to a physical location. The mapping exists so that the operating system can treat the whole drive as a flat array, while the drive hides the physics. The textbook adds the honest caveat: in practice the translation is not a clean formula, because disks hide defective sectors by substituting spare sectors, and because some drives do not have a constant number of sectors per track (the CAV/CLV distinction below).
15.10.2 Constant Angular Velocity and Constant Linear Velocity
The number of sectors per track is tied to the disk's rotation scheme. Constant angular velocity (CAV) means the number of sectors per track is uniform — every track holds the same number of sectors. Constant linear velocity (CLV) describes the bits: if the number of bits per track is uniform, we call that constant linear velocity. So: uniform sectors per track → constant angular velocity; uniform bits per track → constant linear velocity.
The two speeds, one sentence each. Under CAV the disk spins at a constant speed (constant angle per second), so to keep the same data rate on every track, the bit density must drop on the long outer tracks — so outer tracks hold more sectors, inner tracks hold fewer (the professor's observation in §15.7.1), and the storage capacity is limited by what the innermost track can hold. Hard disks use CAV. Under CLV the linear speed of the surface under the head stays constant (constant length per second), so the bit density is uniform and the disk must change its rotation speed — spinning slower over the long outer tracks and faster over the short inner ones — which is why CD-ROM and DVD-ROM drives use it. The professor's summary line: CAV is about uniform sector counts, CLV is about uniform bit counts.
15.10.3 Host Attached Storage
Disk attachment comes in three types. The first is host attached storage — storage that is like local storage, present in each and every system, connected through the I/O buses. We can have up to 16 devices on one cable. Each target SCSI device performs up to eight logical units — the blocks it serves. The architecture for sending and receiving information is done with the help of Fibre Channel; one variant is the arbitrated Fibre Channel. The address space that can be fabricated is a 24-bit address space, and this is the basis for the other storage area networks. When the host sends an I/O, the request is directed to the bus ID, the device ID, and the logical unit — everything has to be mentioned.
The SCSI address book. The professor's numbers map exactly onto the textbook's: a SCSI bus supports a maximum of 16 devices — one host controller card (the initiator) plus up to 15 storage devices (the targets) — and each SCSI target can address up to 8 logical units (for example, the separate drives inside a RAID array or a CD jukebox's changer mechanism and drives). So an I/O request needs three coordinates: bus ID, device (SCSI) ID, and target logical unit. Fibre Channel adds its own scheme: the large switched-fabric variant uses a 24-bit address space (which is what makes SANs possible — see below), while the arbitrated-loop variant (FC-AL) addresses up to 126 devices. Typical desktop machines use the simpler IDE/ATA or SATA buses (one or two drives), while high-end workstations and servers use SCSI or Fibre Channel.
15.10.4 Storage Area Networks (SAN)
The second type is the storage area network (SAN). Picture a storage array — an array of disks, thousands of disks. Each array has a controller, which helps to attach the array to a particular host or to the disks, and the ports are connected to the host with the help of the arrays; there is memory as well. When very large information has to be stored, we go for a storage area network. In the local system these storage areas are just storage present in the same system, but when connected to the network, the storage area can serve the other systems that are connected through a LAN or a WAN. A client that needs space makes a request, gets some space, and uses it.
SAN versus NAS — one sentence each. A SAN is a private network of storage devices speaking storage protocols (Fibre Channel, iSCSI): the hosts and the storage arrays are on their own dedicated fabric, so storage I/O does not compete with ordinary network traffic, and a SAN switch can allocate or block storage per host. NAS (next subsection) is a file server on the ordinary data network speaking file protocols (NFS, CIFS) over RPC: easy to set up, but the storage traffic shares bandwidth with everything else on the LAN. The textbook's rule of thumb: SAN when performance and flexibility at scale matter (clusters of servers sharing the same storage), NAS when convenience on a LAN matters more.
Real-world: Google Drive can be taken as a storage area network — we, as clients, make a request to have some space and use it; the service acts as a storage array storing information. In such a setup, separate data processing centers or web content providers are also attached into the network, and multiple hosts can attach to the storage array with the help of the storage area network.
15.10.5 Network Attached Storage (NAS)
The third type is network attached storage (NAS). It is another type of storage system, but it is not a local connection — it is a network. We remotely attach our system to another file system, and we can use either the network file system (NFS) or the CIFS file system — the common protocols file system, as the source phrases it. The standard expansion of the acronym: CIFS = Common Internet File System, the file-sharing protocol used by Windows machines (the professor's "common protocols file system" is the same thing in plain words). The implementation again takes place with the help of RPC, and the protocol that is followed can be either TCP or UDP.
Different products exist today — Synology and many more are examples of network attached storage. If we compare Synology with Google Drive: Synology is mainly used for smaller systems, or medium- or larger-sized systems to be stored; Google is capable of any type of system. The NAS is connected to the client either through the LAN or in the way we attach it. Remember: using RPC only, we have to implement this network attached storage — the client makes a request, then it takes the available space in the network for its purpose.
These are the three different types of attachment with respect to the disk. Disk scheduling and disk management come in the next session.
15.10.6 Student Q&A: The Comprehensive Exam
Q: What will be asked in the comprehensive exam — theory or problems?
A: Problems and theory both will be there. Whatever problems we have dealt with in class, similar types of problems may appear: in deadlocks we have seen problems; memory management — paging and segmentation — is problem-based; then the hard disk performance we just covered, then disk scheduling, and also CPU scheduling. Disk scheduling will be somewhat easier compared to CPU scheduling. Theory questions will be there too, but the details asked for theory will always be less compared to problems.
The professor's message is a study plan in one paragraph: rework the solved problems — deadlocks, paging and segmentation, disk performance, disk scheduling, CPU scheduling — because the exam problems will be similar in type, and spend less effort memorizing deep theory detail, because theory questions ask for less. Disk scheduling is called out as easier than CPU scheduling, so it is the safest place to pick up marks.
Takeaway: the disk is a one-dimensional array of logical blocks mapped sector by sector from sector 0 of the outermost cylinder inward; uniform sectors per track = CAV (hard disks), uniform bits per track = CLV (CD/DVD); and disks attach three ways — host attached (local I/O buses, SCSI: 16 devices per bus, 8 logical units per target, 24-bit Fibre Channel address space), SAN (private storage fabric with arrays and switches), and NAS (NFS or CIFS over RPC on TCP/UDP, e.g. Synology). The exam carries both theory and problems, with problems (including this disk material) weighted heavier than theory detail.
Exam Guidance Summary
The session's exam guidance, collected in one place:
- The comprehensive exam contains both problems and theory. Expect problem types similar to those practiced in class — the best preparation is reworking the solved problems.
- Problem topics to practice: deadlocks, memory management (paging and segmentation), hard disk performance, disk scheduling, and CPU scheduling. Disk scheduling is somewhat easier than CPU scheduling.
- Theory questions appear, but the detail level asked for theory is always less than for problems.
- Expect one question on disk performance. Master the formulas:
- average seek time ≈ one third of the number of tracks;
- rotation time = seconds;
- average latency = half of the rotation time;
- random access time = average seek time + average latency;
- throughput = I/O operations per second × transfer size;
- average I/O time = average access time + transfer amount ÷ transfer rate + controller overhead;
- transfer rate = heads × track capacity × rotations per second;
- track capacity = sectors per track × bytes per sector.
- For latency, either use the formula (half of the full rotation time) or read the average latency for the five common RPM values from the table — for 7200 RPM it is 4.17 ms.
- In transfer-time problems, convert bytes to bits by multiplying by 8, and convert between giga, mega, and kilo using 1024 factors. In the worked example the 4 KB block gave a transfer time of 0.031 ms and a final average access time of 9.301 ms.
- For the bitmap, be ready for small computations such as blocks, and know that 1 means free and 0 means allocated in a bitmap.
Exam note: the professor's repeated theme is that this course's exam material is problem-heavy: rework the class problems (deadlocks, paging and segmentation, disk performance, disk scheduling, CPU scheduling), keep the disk formula chain and the unit conversions (×8 for bytes to bits, 1024 for giga→mega→kilo) ready, and treat theory as lighter-weight — the theory detail asked is always less than the problem detail.
Key Industry Applications
- Google Drive as a storage area network: clients request space from a storage array over the network, and the service acts as the array storing the information — the SAN model (§15.10.4) in consumer form.
- Synology and similar appliances as NAS: network attached storage for small to medium and larger systems, implemented over RPC with TCP or UDP, using NFS or CIFS — the SAN/NAS comparison (§15.10.5) in hardware form.
- FAT in real file systems: the file allocation table is the linked-allocation idea made practical (MS-DOS, OS/2): the starting block number is stored and blocks are followed to the end through the table (§15.4.2).
- Linux's virtual file system: four object types (inode, file, superblock, dentry) let many concrete file systems share one interface — the reason a single Linux machine can mount ext4, FAT, NTFS, ISO 9660, and NFS side by side (§15.3.2).
- NFS in practice: workstations with independent file systems share directories; mounting is a super-user operation and the mount is placed on top of the local directory; the stateless server model keeps crash recovery simple (§15.6).
- RPC in modern cloud development: used for example in Golang services, where practitioners often find it more secure than plain HTTP; Java expresses RPC as a client-side stub and a server-side skeleton — the professor's bridge from the lecture to the industry (§15.6.7).
- SSD boot drives: SSDs have no seek time and no rotational latency, which is why operating systems are typically loaded from an SSD for faster boot (§15.9.1).
- Magnetic tape for archives: tape remains the cheap, permanent medium for backups and infrequent data, even though access is about a thousand times slower than disk (§15.9.2).
- ZFS space maps: Sun's ZFS manages enormous file systems by dividing space into metaslabs, each tracked by a space map in counting format — the industry answer to bitmap scalability (§15.5.4).
- Fibre Channel SANs: the 24-bit address space of the switched-fabric Fibre Channel variant is the basis of storage area networks, letting multiple hosts and storage arrays share one flexible fabric (§15.10.3–15.10.4).
OS Lecture 15 notes · File Systems and Mass Storage Structure
Sections Breakdown
File attributes, operations, access methods, and locking; the chain from raw disks to partitions, volumes, and directories.
Single-level, two-level, tree, and acyclic graph directories, plus path naming in DOS, VMS, and UNIX.
Mounting a file system at a mount point and the Linux virtual file system's four object types.
Contiguous, linked (FAT), and indexed allocation, UNIX multi-level indexing, and choosing the right method.
Bitmaps, linked free lists, grouping, counting, and ZFS space maps over metaslabs.
Mounting remote directories, file handles, stateless servers, XDR and RPC, path resolution, and caching.
Disk anatomy, seek time and rotational latency, the performance formula chain, and hard disk specifications.
A complete average-access-time problem for a 4 KB block: transfer time, average latency, and the 9.301 ms total.
SSD advantages, and magnetic tape as the cheap, permanent medium for backups.
Logical blocks, CAV versus CLV, host-attached storage, storage area networks, and network attached storage.
The exam strategy: both theory and problems, the problem topics to practice, and the disk formula chain.
Real-world connections: Google Drive as a SAN, Synology as NAS, FAT, the Linux VFS, NFS, RPC, SSDs, tape, and ZFS.
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
File System Concepts: From Raw Disks to Volumes
Must-know: The hierarchy: raw disk -> partitions (mini disks) -> volumes (partitions with a file system) -> device directory -> directories -> files; file attributes (name, id, type, location, size, protection, owner, timestamps); shared vs exclusive locks; the six directory operations.
⚠️ Top pitfall: Confusing a partition (a raw slice of disk) with a volume (a partition that carries a file system).
Self-check: What does a shared lock allow that an exclusive lock does not?
Connects to: Directory Structures, File System Mounting and Virtual File Systems
Directory Structures
Must-know: The directory evolution: single-level (unique names required) -> two-level (MFD/UFD, per-user isolation) -> tree (root, unique paths, no conflicts) -> acyclic graph (sharing, dangling pointers) -> general graph (cycles, garbage collection). Path syntax: DOS C:\dir\file, VMS C:[dir]file, UNIX /dir/file.
⚠️ Top pitfall: Deleting a shared file leaves dangling pointers that can point into reused space of unrelated files.
Self-check: Why can two files named report.txt coexist in a tree-structured directory?
Connects to: File System Concepts: From Raw Disks to Volumes, File System Mounting and Virtual File Systems
File System Mounting and Virtual File Systems
Must-know: Mounting = attaching a file system to an existing volume at a mount point; only super users may mount; the file system is checked for correctness first. Linux VFS: inode (file), file (open file), superblock (file system), dentry (directory entry); VFS dispatches to the concrete file system's function table.
⚠️ Top pitfall: Thinking mounting merges disks into one pool; it attaches one file system at one directory and covers the subtree below it.
Self-check: Why must mounting be a privileged operation?
Connects to: Directory Structures, Network File System (NFS)
Allocation Methods
Must-know: Contiguous: fastest, needs known size, internal (inside last block) + external (scattered holes) fragmentation, compaction to fix. Linked: directory stores first+last block, pointer overhead ~0.78% at 4/512 bytes, broken link loses rest of file, sequential only; FAT stores the chain in a table. Indexed: one index block per file, no external fragmentation, index overhead can exceed small files; multi-level for large files. UNIX inode: 12 direct + single + double + triple indirect. Decision: large sorted records -> indexing; few unsorted records -> linked or contiguous.
⚠️ Top pitfall: Assuming there is one best allocation method; or assuming freed one-or-two blocks are useful — only four or five freed together can serve another file.
Self-check: Why can a contiguous file not simply grow by one block when its neighbour is allocated?
Connects to: Free Space Management, Directory Structures
Free Space Management
Must-know: n = 2^40 / 2^12 = 2^28 blocks; block number = (bits per word) x (zero-valued words scanned) + (offset of first set bit). Professor's bitmap size: 256 MB (64 MB with 4-block clusters); standard one-bit-per-block count: 32 MB (8 MB clustered). Linked list: traverse whole list. Grouping: first free block stores next n-1 addresses. Counting: first address + count. ZFS: metaslabs + space maps (counting format, log replayed into balanced tree).
⚠️ Top pitfall: Counting the bitmap as one byte per block (256 MB) instead of one bit per block (32 MB); or forgetting that 1 = free and 0 = allocated.
Self-check: A bitmap covers blocks 0..31 and reads 0 0 1 1 0 0 0 0 0 1 ... — which blocks are free?
Connects to: Allocation Methods, Network File System (NFS)
Network File System (NFS)
Must-know: Remote directory mounted ON TOP of local directory; super-user only; file handle = file-system identifier + inode; stateless servers repeat full arguments, no concurrency control (single write RPC atomic, interleaved writes possible); three layers (VFS interface, file system interface, service layer) with XDR pack/unpack and RPC (stub = client, skeleton = server); one lookup RPC per path component; attribute cache revalidated every 60 s; read-ahead + delayed write.
⚠️ Top pitfall: Forgetting that each path component after the mount point costs a separate RPC — path resolution is expensive; and assuming NFS coordinates concurrent writers (it does not).
Self-check: Why does the stateless server need the full set of arguments on every request?
Connects to: File System Mounting and Virtual File Systems, Allocation Methods
Mass Storage: Magnetic Disk Fundamentals
Must-know: Cylinder = imaginary set of same-radius tracks across all platters. Avg seek ~= 1/3 x tracks; T_rotation = 60/RPM seconds; avg latency = half of T_rotation (7200 RPM -> 8.33 ms -> 4.17 ms); random access = avg seek + avg latency; throughput = IOPS x transfer size; avg I/O = access + amount/rate + controller overhead; transfer rate = heads x track capacity x rotations per second (standard: track capacity x rotations/sec); track capacity = sectors per track x bytes per sector. Transfer rate ~6 Gbps interface speed.
⚠️ Top pitfall: Calling t_access the 'average access time' when a specific transfer is meant; forgetting the half in average latency; treating GB as gigabytes when the lecture uses gigabits.
Self-check: Why is the average rotational latency exactly half the rotation time?
Connects to: Hard Disk Performance: Worked Example, Disk Structure and Disk Attachment
Hard Disk Performance: Worked Example
Must-know: t_access = t_avg seek + t_transfer + t_avg latency + t_controller overhead. Transfer time: 4 KB x 8 = 32 Kbit; 1 Gbps = 1024 x 1024 Kbit/s; t = 32/1048576 s ≈ 0.031 ms. Average latency: 60/7200 = 8.33 ms, half = 4.17 ms. Total: 5 + 0.031 + 4.17 + 0.1 = 9.301 ms. Seek and latency dominate; transfer is tiny.
⚠️ Top pitfall: Dividing 4 KB by 1 Gbps without converting units: multiply bytes by 8 to get bits, then convert giga to mega to kilo with 1024 twice.
Self-check: Why is the transfer time (0.031 ms) so much smaller than the seek time (5 ms)?
Connects to: Mass Storage: Magnetic Disk Fundamentals, Disk Structure and Disk Attachment
Solid-State Drives and Magnetic Tape
Must-know: SSD: non-volatile, reliable, no seek time, no rotational latency, faster but costlier per GB — OS boot from SSD is standard. Magnetic tape: first secondary storage, permanent, cheap, huge capacity, ~1000x slower random access than disk — use for backups and infrequently used data, not commercial working storage.
⚠️ Top pitfall: Assuming tape is obsolete; it is still the standard backup archive medium because of cost per terabyte.
Self-check: Why does booting the OS from an SSD speed up startup so much?
Connects to: Mass Storage: Magnetic Disk Fundamentals, Hard Disk Performance: Worked Example
Disk Structure and Disk Attachment
Must-know: Logical block = smallest transfer unit; sector 0 = first sector of first track of outermost cylinder; mapping goes track by track, cylinder by cylinder, outward to inward. Uniform sectors per track -> CAV; uniform bits per track -> CLV. Host attached: SCSI 16 devices/bus, 8 logical units per target, FC 24-bit address space (basis of SANs). SAN: private storage network of arrays; NAS: NFS or CIFS over RPC (TCP or UDP), e.g. Synology. Exam: both theory and problems; problems like class ones — deadlocks, paging/segmentation, disk performance, disk scheduling, CPU scheduling; disk scheduling easier; theory details less than problems.
⚠️ Top pitfall: Confusing CAV and CLV: CAV = uniform sectors per track (constant rotation speed); CLV = uniform bits per track (variable rotation speed).
Self-check: Why do outer tracks hold more sectors on a CAV hard disk?
Connects to: Mass Storage: Magnetic Disk Fundamentals, Network File System (NFS)
Exam Guidance Summary
Must-know: Problems + theory both on the comprehensive exam; problem topics: deadlocks, paging and segmentation, disk performance, disk scheduling (easier than CPU scheduling), CPU scheduling; theory detail asked is less than for problems. Disk formulas: avg seek ~ 1/3 tracks; 60/RPM; half-latency; access = seek + latency; throughput = IOPS x size; avg I/O = access + transfer + overhead; transfer rate = heads x track capacity x rotations/s; track capacity = sectors x bytes. Convert bytes to bits (x8), giga->mega->kilo (1024 twice). Worked example: 9.301 ms.
⚠️ Top pitfall: Leaving unit conversions (bytes x 8, 1024 factors) out of transfer-time problems.
Self-check: Which topics will the comprehensive exam's problem section cover?
Connects to: Free Space Management, Mass Storage: Magnetic Disk Fundamentals, Hard Disk Performance: Worked Example
Key Industry Applications
Must-know: Industry applications of the session's concepts: SAN (Google Drive), NAS (Synology, NFS/CIFS over RPC), FAT linked allocation, Linux VFS four objects, NFS super-user mounting, RPC in Golang/Java, SSD boot drives, tape archives, ZFS metaslabs and space maps, Fibre Channel 24-bit address space.
Self-check: Which protocol pair does NAS use over RPC?
Connects to: Allocation Methods, Free Space Management, Network File System (NFS), Disk Structure and Disk Attachment
Was this lecture useful?
BitsNotes AI Assistant
Subject Notes AssistantConfigure AI Chat
Choose how to access the chatbotSigned in as
Powered by BitsNotes — 20 messages per day. No API key needed. Want unlimited access? Use "Bring Your Own Key" mode.
Sign in to use AI Chat
Get 20 free AI messages per day to ask questions about your lecture notes. Sign in with Google or GitHub — it takes 5 seconds.
Sign In to BitsNotesSwitch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.