Introduction
A disk is an array of fixed-size blocks, and a file is a sequence of logical blocks 0, 1, 2 and so on. The allocation method decides which disk blocks hold a file and how the file system finds logical block . The choice fixes three quantities: how many disk accesses a read of block costs, how large a file can be, and how much space is wasted.
There are three classical methods: contiguous, linked (with its table form, the FAT) and indexed (with the UNIX inode as its multilevel form). The file system must also remember which blocks are free, using a bit vector, a free list, grouping or counting. Each method is given with the arithmetic that goes with it.
Prerequisites
- File System Interface and Directory Structure: files, directories, inodes and the open-file tables.
Core concepts
Conventions. Logical blocks are numbered from 0. "Accesses" counts disk-block reads needed to fetch one data block, with the directory entry or inode already in memory unless stated otherwise. Block numbers (disk addresses) are 4 bytes.
| Method | Directory or inode holds | Read logical block | External fragmentation | Growth |
|---|---|---|---|---|
| Contiguous | Start block, length | 1 access: block start | Yes | Hard: the next blocks may be in use |
| Linked | First (and last) block; each block holds a pointer to the next | accesses (follow the chain) | No | Easy |
| FAT | First block; a table in memory holds the next-block pointers | 1 disk access once the FAT is cached | No | Easy |
| Indexed | Address of an index block listing all data blocks | 2 accesses (index block, data) | No | Easy, up to the index size |
How each method works

Contiguous allocation
The file occupies blocks start, start , ..., start length . File a in Figure 1 has start 14 and length 6: blocks 14 to 19, and logical block 4 is disk block 18. Both sequential and direct access are fast, and sequential reads need almost no seeking. The costs are those of Contiguous Memory Allocation and Fragmentation: choosing a hole by first fit or best fit, external fragmentation, and the need to know the final size in advance. Some systems allocate a contiguous extent and link further extents when the file grows.
Linked allocation
Each block stores the address of the next block of the file; the directory holds the first block (and often the last, for appending). File b has the chain 7, 21, 3, 12, 28, and the last block holds a null pointer. To read logical block 3, the system reads blocks 7, 21 and 3 for their pointers and then block 12: 4 accesses, and in general for logical block .
- No external fragmentation, and a file can grow while free blocks exist.
- Only sequential access is efficient.
- Each block loses space to the pointer: with 512-byte blocks and 4-byte pointers, 508 bytes hold data, a loss of 0.78%. Grouping blocks into clusters reduces the loss and the number of seeks, at the price of internal fragmentation.
- One damaged pointer loses the rest of the file.
File-allocation table (FAT)
The FAT moves all the next-block pointers into one table with an entry per disk block, kept at the start of the volume and cached in memory. Entry holds the number of the block that follows block in its file, an end-of-file mark, or 0 for a free block. For file b:
| Block | 3 | 7 | 12 | 21 | 28 |
|---|---|---|---|---|---|
| FAT entry | 12 | 21 | 28 | 3 | EOF |
The directory entry holds 7. Finding logical block means following entries in memory, then one disk access. The table is large, though: a 2 GB volume with 4 KB blocks has blocks, and with 4-byte entries the FAT occupies 2 MB. The FAT width limits the volume: FAT-16 addresses at most blocks, so with 32 KB blocks the largest volume is 2 GB (Tanenbaum 4.5.1).
Indexed allocation
Each file has an index block: an array of disk-block addresses, entry giving logical block . File c's index block is block 9 and holds 7, 21, 3, 12, 28 and then null entries. Reading any block takes 2 accesses (index block, then data); with the index block cached, 1. Direct access is fast and there is no external fragmentation, but every file, however small, costs a whole index block.
When one index block is not enough:
- Linked scheme: the last entry of an index block points to the next index block.
- Multilevel index: a first-level block points to second-level index blocks, which point to data. With 4 KB blocks and 4-byte addresses, an index block holds 1,024 addresses, and two levels address blocks, a 4 GB file.
- Combined scheme (UNIX inode): a few direct pointers for small files plus single, double and triple indirect pointers.
The UNIX inode and maximum file size

Let the block size be bytes and the address size bytes, so an index block holds addresses. With direct pointers and one each of single, double and triple indirect:
For , KB and bytes, :
| Part | Blocks | Bytes |
|---|---|---|
| Direct | 12 | 48 KB |
| Single indirect | 1,024 | 4 MB |
| Double indirect | 1,048,576 | 4 GB |
| Triple indirect | 1,073,741,824 | 4 TB |
| Total | 1,074,791,436 | 4,402,345,721,856 bytes, a little over 4 TB |
Check the address width too. A 4-byte block address can name blocks, so with 4 KB blocks the whole file system is limited to 16 TB. In this example the pointers, not the address width, limit the file size; with larger blocks or more indirection the address width can become the binding limit.
Second example. An inode with 10 direct pointers, one single and one double indirect pointer, 1 KB blocks and 4-byte addresses: , so the largest file is KB KB.
Which pointer serves block ?
With and : logical blocks 0 to 11 are direct; 12 to 1,035 go through the single indirect block; 1,036 to 1,049,611 through the double indirect block; the rest through the triple indirect block.
- Logical block 5,000: , so it is entry 892 of the second-level block found at entry 3 of the double indirect block. With the inode in memory, reading it costs 3 accesses (double indirect block, second-level block, data).
- Byte offset 20,000,000: with remainder 3,328, so the byte is at offset 3,328 of logical block 4,882, which is also in the double indirect range (entry 3, then entry 774).
The cost of reading block , with the inode cached, is 1 access for a direct block, 2 for single indirect, 3 for double and 4 for triple. If the inode must be read first, add 1.
When the address width binds, and the cost of the index blocks
Address width binding. 8 KB blocks, 4-byte block addresses, 12 direct pointers and one each of single, double and triple indirect. An index block holds addresses, so the pointers reach
But a 4-byte address names only blocks, KB bytes TB. A file cannot use more blocks than the volume can number, so the largest file is limited to 32 TB by the address width, not by the pointers.
Wider addresses. With 8-byte addresses and the same 8 KB blocks, and the pointers reach blocks, a little over KB TB. A 64-bit address no longer limits anything, so now the pointers bind. Doubling the address size halves and cuts the triple-indirect reach by a factor of 8.
Index blocks used by one file. With and (4 KB blocks, 4-byte addresses), a file of 5,000 blocks uses the 12 direct pointers, the single indirect block for blocks 12 to 1,035, and the double indirect block for the remaining blocks. Those need second-level blocks. Index blocks in all: , so the file occupies 5,006 blocks on disk.
Free-space management
Bit vector (bitmap)
One bit per block. Convention: as in Silberschatz 14.5, bit 1 means the block is free and 0 that it is allocated; some texts use the opposite, so check the question. To find the first free block, skip words that are all 0, then find the first 1 bit:
Example. With 8-bit words, bitmap 00000000 00000000 00101100 ... (bits numbered from the left within a word): two all-zero words, then the first 1 is at offset 2, so the first free block is . The free blocks in the third word are 18, 20 and 21.
Size. The bitmap for a 2 GB volume with 4 KB blocks has bits = 64 KB. For 1 TB with 4 KB blocks: bits = 32 MB. A bitmap is fast only if it is cached in memory, so its size matters.
Free list, grouping and counting
- Linked free list: each free block points to the next free one; allocating one block is , but traversing the list needs a read per block (rarely needed).
- Grouping: the first free block holds the addresses of free blocks; the last of these holds the next , so many free addresses come from one read.
- Counting: store (first block, count) pairs for runs of consecutive free blocks. The free blocks 2, 3, 4, 5, 8, 9, 10, 17, 18, 25, 26 and 27 become (2, 4), (8, 3), (17, 2), (25, 3).
Bitmap or free list? A disk of blocks of 1 KB needs a 128 KB bitmap (128 blocks) whatever its state. A free list stored as blocks of free addresses (255 four-byte addresses per 1 KB block, plus a pointer to the next such block) needs 40 blocks when 10,000 blocks are free, but 4,113 blocks when all are free. The list is smaller on a nearly full disk; the bitmap is smaller on an empty one (Tanenbaum 4.4.1).
Important properties and observations
- Only contiguous allocation has external fragmentation; it also gives the fastest sequential and direct access.
- Linked allocation supports only sequential access efficiently; the FAT removes the per-block disk reads by caching the pointers.
- Indexed allocation supports direct access; small files waste most of their index block, which the inode's direct pointers avoid.
- Maximum file size grows with block size twice: bigger blocks hold more data and more addresses per index block.
- A bitmap's size depends only on the disk size; a free list's size depends on how much is free.
Common misconceptions.
- "Linked allocation has no overhead." Each block loses the pointer space, and a lost pointer loses the rest of the file.
- "Indexed allocation needs one access per block." It needs the index block too, unless that is cached.
- "The triple indirect pointer adds three levels of blocks." It adds three levels of index blocks above the data, so a triple-indirect block costs 4 reads with the inode cached.
GATE examination perspective
- Maximum file size. Compute , add the direct, single, double and triple contributions, and check the address-width limit.
- Which pointer, how many accesses. Subtract the direct and single ranges, then divide by for the indices; count accesses and say whether the inode is cached.
- Linked versus indexed access counts. Linked: reads; indexed: 2 (1 with the index cached); contiguous: 1.
- FAT and bitmap sizes. Number of blocks times the entry width; one bit per block for the bitmap.
- Bitmap search. Know the convention (1 free or 0 free) and the bit order within a word.
- Counting and grouping. Turn a free-block list into runs, or follow a grouping chain.
Summary
Sources
- A. Silberschatz, P. B. Galvin, G. Gagne, Operating System Concepts, 10th ed., Wiley: Chapter 14 (14.4 Allocation Methods, 14.5 Free-Space Management).
- A. S. Tanenbaum, H. Bos, Modern Operating Systems, 4th ed., Pearson: Chapter 4 (4.3.2 Implementing Files, 4.4.1 Disk-Space Management, 4.5.1 The MS-DOS File System, 4.5.2 The UNIX V7 File System).