Hubbry Logo
search
logo

Extent (file systems)

logo
Community Hub0 Subscribers
Read side by side
from Wikipedia

In computing, an extent is a contiguous area of storage reserved for a file in a file system, represented as a range of block numbers, or tracks on count key data devices. A file can consist of zero or more extents; one file fragment requires one extent. The direct benefit is in storing each range compactly as two numbers, instead of canonically storing every block number in the range.[1] Also, extent allocation results in less file fragmentation.

Extent-based file systems can also eliminate most of the metadata overhead of large files that would traditionally be taken up by the block-allocation tree. But because the savings are small compared to the amount of stored data (for all file sizes in general) but make up a large portion of the metadata (for large files), the overall benefits in storage efficiency and performance are slight.[2]

In order to resist fragmentation, several extent-based file systems do allocate-on-flush. Many modern fault-tolerant file systems also do copy-on-write, although that increases fragmentation. As a similar design, the CP/M file system uses extents as well, but those do not correspond to the definition given above. CP/M's extents appear contiguously as a single block in the combined directory/allocation table, and they do not necessarily correspond to a contiguous data area on disk.

IBM OS/360 and successors allocate files in multiples of disk tracks or cylinders. Files could originally have up to 16 extents, but this restriction has since been lifted. The initial allocation size, and the size of additional extents to be allocated if required, are specified by the user via Job Control Language. The system attempts to allocate the initial size as a contiguous area, although this may be split if contiguous space is not available.

Adoption

[edit]

The systems supporting file system extents include the following:

Adoption outside of file systems include the following:

See also

[edit]

References

[edit]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
In file systems, an extent is a contiguous sequence of disk blocks or clusters allocated to a single file, representing a continuous region of storage that minimizes fragmentation by grouping adjacent data units together.[1][2] This allocation method contrasts with non-contiguous approaches like linked lists of individual blocks, as extents store metadata such as the starting block address and length to describe the entire range efficiently.[3][4] Extent-based allocation operates by dividing the disk into fixed or variable-sized extents, which the file system maintains in a list of available units; when a file requires space, the system selects an appropriate extent using policies like first-fit or best-fit to allocate contiguous blocks.[2] Files can consist of multiple extents if they grow beyond a single contiguous area, with each additional extent appended as needed, though this may lead to external fragmentation if free space becomes scattered.[1][3] In practice, extents map logical file offsets (via virtual cluster numbers) to physical disk locations (logical cluster numbers), enabling efficient sequential and random access without excessive metadata overhead.[1][4] This technique offers key advantages, including compact metadata representation—requiring only a pointer and length per extent rather than one per block—and improved performance for sequential I/O due to reduced seek times on contiguous data.[3][2] However, it is less flexible in highly fragmented disks, where finding large contiguous free spaces becomes challenging, and it may introduce internal fragmentation if extents are oversized for small files.[2][3] Extent-based allocation traces its origins to early systems like IBM OS/360 in the 1960s, which used contiguous extents for mainframe storage management, and has evolved into modern implementations such as NTFS (via cluster extents), ext4 (with delayed allocation for extents), XFS (using allocation groups for extents), JFS2, and Veritas File System (VxFS).[5][6][3] These systems leverage extents to handle large files and high-capacity drives effectively, balancing efficiency with the demands of contemporary storage environments.[4][7]

Fundamentals

Definition

In file systems, storage is divided into fixed-size allocation units, such as blocks or clusters, which represent the smallest addressable portions of disk space used to hold file data.[8] These units enable efficient management of data placement on secondary storage devices like hard disks.[8] An extent is a contiguous sequence of these blocks or sectors allocated to a single file, represented compactly by two integers: the starting logical block address and the length (number of blocks).[8] This structure allows the file system to describe large, continuous portions of a file's data with minimal metadata overhead, as opposed to listing each individual block.[8] For instance, a 1 MB file using 4 KB blocks could be allocated as one extent comprising 256 contiguous blocks, specified by its starting block number and length of 256.[8] In cases of fragmentation, the same file might instead span multiple non-contiguous extents, each described similarly but requiring additional metadata to link them.[8] This approach contrasts with non-contiguous methods like linked or indexed allocation, where blocks are not required to be adjacent.[8]

Comparison to Other Allocation Methods

In linked allocation, disk blocks for a file are organized as a linked list, where each block contains a pointer to the next block in the sequence, with the file's metadata storing only the location of the first block.[9] This method avoids external fragmentation since blocks can be allocated anywhere available, but it incurs high seek times for sequential reads due to the need to traverse the chain block by block, and random access is impossible without reading the entire preceding chain.[9] Additionally, it suffers from reliability issues, as corruption in a single pointer can render the rest of the file inaccessible.[10] Indexed allocation addresses some of linked allocation's drawbacks by using a dedicated index block that holds pointers to all data blocks of the file, enabling direct random access to any block without traversal.[11] The file's metadata points to this index block, and space is allocated as needed up to the index's capacity.[11] While it eliminates external fragmentation and supports efficient growth for small to medium files, the method is limited by the fixed size of the index block, which can only hold a finite number of pointers—typically restricting large files unless extended with multi-level indexing, which adds further overhead and indirection.[9] For very small files, it wastes space since the entire index block must be allocated regardless of usage.[9] Extents improve upon these approaches by grouping multiple contiguous disk blocks into a single logical unit, represented in metadata by just the starting block and length, rather than individual pointers.[9] A file can consist of several such extents, allowing non-contiguous storage while minimizing metadata overhead—for instance, a 1 GB file divided into 100 MB extents might require only a few entries instead of thousands of pointers in an indexed scheme.[9] This reduces the space and access cost for metadata, enhances sequential read performance due to locality, and mitigates the index size limitations of pure indexed allocation, though it still risks external fragmentation if extents cannot be placed adjacently.[10]
MethodProsConsUse Cases
LinkedNo external fragmentation; simple growth without relocation.[9]Poor random access; high sequential seek overhead; reliability risks from pointer corruption.[10]Systems prioritizing simplicity over performance, such as early embedded or sequential-only workloads.[11]
IndexedSupports random access; no external fragmentation; efficient growth for files fitting within index size.[11]High metadata overhead; limited file size without multi-level extensions; space waste for small files.[9]General-purpose file systems needing balanced access patterns, like medium-sized files in multi-user environments.[9]
ExtentsLow metadata overhead (one entry per group); good sequential locality; scales to large files with fewer entries.[9]Potential external fragmentation; growth limited by maximum extents per file.[10]Large-file storage in modern systems, such as databases or media files where sequential access dominates.[9]

History

Origins in Early File Systems

The concept of extents in file systems emerged as a response to the challenges of managing storage on early computing hardware, where contiguous allocation was often handled in systems like the Compatible Time-Sharing System (CTSS) and Multics. In CTSS, introduced in 1961, files were allocated contiguously on disk tracks by the system based on user size requests, with symbolic referencing via names and logical module numbers, which limited flexibility and increased administrative overhead on tape and early drum storage.[12] Multics, developed starting in 1965 as an evolution of CTSS, employed segments—logically contiguous units in its hierarchical file system—with automatic allocation to handle storage efficiently, though early designs faced fragmentation challenges on direct-access devices, highlighting the need for automated mechanisms to handle non-contiguous storage efficiently.[13] Extents were first formalized in the IBM System/360 operating systems, with OS/360 released alongside the System/360 hardware in 1964 to address mainframe storage efficiency. In OS/360, an extent is defined as a contiguous area of direct-access storage allocated to a data set, allowing files to span multiple non-contiguous regions when a single contiguous block was unavailable due to fragmentation.[14] Initially, data sets were limited to up to 16 extents per volume, allocated via the SPACE parameter in job control statements, which helped minimize seek times and optimize access on early disks like the IBM 2311.[15] This limit was later increased in successor systems, but the original design prioritized reducing directory overhead on constrained media by grouping blocks into larger units rather than tracking each individually.[14] The primary motivation was to support growing data sets for business applications, such as payroll processing, on volumes with limited capacity, where full contiguous allocation often failed due to prior usage patterns.[16] A notable variant appeared in CP/M, the Control Program for Microcomputers, introduced in 1974 by Gary Kildall for 8-bit microprocessors. In CP/M's file system, extents consist of 16 KB units composed of 128-byte logical records, with each directory entry (32 bytes) describing one extent's allocation blocks, differing from modern block-based systems by lacking a separate bitmap and instead deriving free space from directory scans.[17] Early versions like CP/M 1.4 supported up to 32 extents per file on floppy disks, expanding to 512 in CP/M 2.2 by 1979, to accommodate larger files while keeping the fixed 64-entry directory compact.[17][18] This approach was driven by the era's small, removable media constraints, aiming to reduce metadata size and enable efficient sequential access without the fragmentation issues of per-block pointers prevalent in even smaller hobbyist systems.[19]

Evolution in Modern File Systems

In the late 20th century, file system extents evolved from the fixed limitations of early implementations, such as the 16 extents per volume in IBM's OS/360, to support for thousands of dynamic extents in modern designs, enabling efficient handling of large, fragmented files without excessive metadata overhead.[20] This shift was driven by increasing storage capacities and the need for scalability, as seen in the Linux ext family, where ext2 (introduced in 1993) relied on block lists limited to 12 direct pointers plus indirect blocks, while ext4 (released in 2008) introduced an extent tree structure allowing files to span up to 16 terabytes with potentially thousands of extents per inode through multi-level indexing.[21] Similarly, database systems like Oracle, which adopted extents in the 1980s for tablespace allocation, transitioned to locally managed extents in version 8i (1999) and beyond, automatically sizing and scaling allocations to minimize administrative overhead in petabyte-scale environments.[22] Post-1990s advancements integrated extents with journaling mechanisms to enhance fault tolerance, particularly in recovery scenarios following crashes or power failures. Journaling file systems like ext3 (2001) and JFS2 logged metadata changes, including extent allocations, to enable rapid replay and reconstruction of file structures, reducing recovery times from hours to seconds.[7] In ext4, extents are journaled alongside data or metadata, ensuring atomic updates and consistency during replays, which proved crucial for enterprise reliability as storage volumes grew.[23] This integration addressed the fragmentation risks in non-journaled systems, allowing extents to be reliably extended or split without data loss in fault scenarios. Adaptations for solid-state drives (SSDs) emerged in the 2000s as flash memory proliferated, with extents facilitating wear-leveling and TRIM operations to optimize endurance and performance. Extents' contiguous block representation simplifies identifying free ranges for TRIM commands, which notify SSD controllers of deallocated space for immediate garbage collection, preventing write amplification since SSDs became mainstream around 2006.[24] File systems like ext4 added discard (TRIM) support in kernel 2.6.33 (2010), leveraging extent metadata to batch free extent notifications, thus aligning allocation strategies with SSD internals like flash translation layers.[25] Key milestones include the ext2-to-ext4 progression, which marked a paradigm shift toward extent-based allocation for Linux, and Oracle's evolution to uniform and auto-allocated extents for database scaling. Post-2010, extents influenced cloud storage abstractions in distributed systems, such as the Container File System (CFS) proposed in 2019, where large files are split into distributed extents across nodes for scalable, fault-tolerant storage in containerized environments.[26]

Technical Implementation

Allocation and Management

In extent-based file systems, the allocation process begins by scanning structures that track free space, such as bitmaps or lists of free extents, to locate the largest available contiguous blocks that meet or exceed the requested size for a new or expanding file.[27] This scan identifies suitable ranges of free blocks, prioritizing contiguity to align with the inherent design of extents as contiguous storage units. Greedy algorithms are commonly employed for efficiency: the first-fit approach allocates the initial contiguous free space encountered that is large enough, while the best-fit strategy selects the smallest such space to reduce internal fragmentation and leftover unusable fragments.[28] Deallocation reverses this by returning freed extents to the free space pool and immediately merging them with any adjacent free extents, consolidating smaller fragments into larger contiguous blocks to combat external fragmentation and improve future allocation performance.[27] Several techniques optimize extent handling during operations. Allocate-on-flush delays extent allocation until data is flushed from cache to disk, enabling the system to batch writes and select larger contiguous blocks, thereby minimizing fragmentation from scattered small allocations.[29] Conversely, copy-on-write protocols, often used for snapshots and versioning, redirect modifications to new extents rather than altering originals, which preserves data integrity but proliferates small, non-contiguous extents over time and exacerbates fragmentation.[30] File growth, such as through appends, is managed by attempting to extend the trailing extent if adjacent free space allows; if not, the system allocates an additional extent, which may require splitting the file's logical structure across multiple extents in the metadata. Preallocation reserves a substantial contiguous extent upfront for anticipated large-file growth, avoiding repeated small allocations and associated fragmentation. The total size of an extent is determined by multiplying the underlying block size by the extent's length in blocks:
\text{total_bytes} = \text{block_size} \times \text{length}

This formula ensures precise mapping of logical file data to physical storage.[31]

Metadata Structures

In file systems that employ extents, metadata structures are designed to efficiently map logical file offsets to physical storage locations while minimizing overhead for large files. These structures typically organize extents in hierarchical trees, such as B-trees or B+-trees, to avoid linear scans and support rapid lookups and updates. For instance, in the ext4 file system, the extent tree is rooted in the inode's i_block array and uses a multi-level structure to represent mappings, enabling efficient handling of fragmented or large files without the limitations of traditional indirect block pointers.[32] The on-disk format of extent metadata generally consists of headers followed by entries that encode essential attributes. A typical extent entry includes the starting logical block number, the length of the contiguous run (in blocks), and flags indicating properties like compression, encryption, or preallocation status. In ext4, the extent tree begins with a 12-byte extent header (struct ext4_extent_header) containing a magic number (0xF30A), the number of valid and maximum entries, tree depth, and generation counter. This header is followed by leaf entries (struct ext4_extent, 12 bytes each) for direct mappings or index entries (struct ext4_extent_idx, 12 bytes each) for interior nodes pointing to child blocks. For example, an extent entry might specify ee_block as the starting file block, ee_len as up to 32,768 blocks (128 MiB maximum with 4 KiB blocks), and ee_start (split into high and low parts) as the physical block address.[32] Multi-level extents extend this format for files exceeding direct inode capacity, using indirect pointers to additional extent blocks. In ext4, the tree supports up to five levels of indirection, where interior nodes reference lower-level extent blocks, allowing mappings for files up to 16 TiB while keeping the root compact within the 60-byte i_block field (12 bytes header plus up to four direct extents). Similarly, in Btrfs, the extent tree (object ID 2) uses a copy-on-write B-tree where EXTENT_ITEM keys encode the extent start (as objectid), and the item describes allocated space for data or metadata with fields for length, reference count, generation, and flags; interior nodes point to child subtrees for hierarchical organization. This structure tracks shared extents via back references, supporting features like snapshots without duplicating mappings.[32][33][34] Metadata overhead arises primarily from the space required per extent entry, scaling with fragmentation. The total metadata space is approximately the number of extents multiplied by the entry size, typically 12-16 bytes per entry across systems like ext4 (12 bytes per extent or index) and XFS (where B+-tree extent records average similar sizes in allocation group trees). In ext4, leaf nodes include a 12-byte header plus entries, with optional 4-byte checksums, leaving minimal unallocated space in 4 KiB blocks; excessive fragmentation can thus inflate inode-linked metadata blocks. Btrfs extent trees add overhead for reference counts and backrefs but optimize via block groups (e.g., 256 MiB chunks) to batch allocations.[32][33][35]
StructureSize (bytes)Key FieldsExample Usage
ext4_extent_header12eh_magic (2), eh_entries (2), eh_max (2), eh_depth (2), eh_generation (4)Root or node header in i_block or extent block
ext4_extent (leaf)12ee_block (4), ee_len (2), ee_start_hi (2), ee_start_lo (4)Maps 1,000 contiguous blocks: ee_block=0, ee_len=1000, ee_start=physical address
btrfs_extent_itemVariable (≥32)size (8), refs (8), generation (8), flags (8), plus backrefsTracks shared extent from byte offset X, size Y bytes, with refcount Z

Adoption

In Unix-like Systems

In Unix-like systems, extents have been integrated into several prominent file systems to enhance performance and scalability for large files and volumes. The fourth extended file system (ext4), introduced in the Linux kernel in 2008 as an evolution of ext3, replaced the traditional block mapping with an extent-based format to reduce metadata overhead and improve sequential I/O efficiency.[36] This implementation uses an extent tree structure, where each extent describes a contiguous range of up to 128 MiB of blocks, allowing files to be mapped efficiently with minimal inode space; for larger files, the tree extends support up to a maximum file size of 16 terabytes on a standard 4 KiB block size.[37] By default, ext4 allocates extents dynamically during writes, aiming for contiguous blocks to minimize fragmentation, though the maximum per-extent size of 128 MiB serves as a practical limit tied to block group boundaries.[38] The XFS file system, originally developed by Silicon Graphics in 1993 for IRIX and later ported to Linux, has employed extent-based allocation from its inception to handle high-performance workloads on large storage arrays.[39] Extents in XFS are defined by a starting block number and length, supporting variable sizes and features like unwritten extents for preallocation; this design scales to filesystems exceeding 8 exabytes. A key optimization is delayed allocation, which defers physical block assignment until data is flushed to disk, enabling the allocator to batch requests and select more contiguous extents, thereby reducing fragmentation and improving write throughput.[39] The Journaled File System 2 (JFS2), originally developed by IBM for AIX and ported to Linux, uses extent-based allocation to manage file data efficiently.[40] Extents in JFS2 are variable-length sequences of contiguous blocks, allocated from allocation groups to support large files and reduce fragmentation; it supports features like inline data for small files and delayed allocation for better performance. JFS2 scales to filesystem sizes up to 32 terabytes with 4 KiB blocks and is designed for reliability in enterprise environments.[41] The Veritas File System (VxFS), a commercial journaling file system for Unix-like systems including Solaris, HP-UX, and Linux, allocates space using extents from its early versions.[42] Extents in VxFS are groups of contiguous blocks, with allocation policies favoring large extents for sequential access; it includes features like extent attributes for tuning and supports filesystems up to 256 terabytes, optimized for high-availability storage.[43] Btrfs, a modern Linux file system, leverages extents in conjunction with copy-on-write (CoW) semantics to provide advanced features like subvolumes and snapshots. Extents represent contiguous data blocks shared across files or subvolumes, with CoW ensuring that modifications create new extents rather than overwriting existing ones, thus preserving snapshot integrity without immediate duplication.[44] This extent sharing facilitates space efficiency in snapshots and clones—read-only or writable copies that initialize with zero additional storage cost—and supports deduplication via external tools where identical data blocks are referenced by multiple files to reclaim space; subvolumes function as logical partitions within the filesystem.[44][45] Apple File System (APFS), used in macOS and other Apple platforms since 2017, incorporates extents as part of its B-tree-based structure for mapping file data, emphasizing contiguous allocation where possible to optimize for flash storage.[46] Extents track physical block addresses and lengths in multiples of the filesystem block size (typically 4 KiB), with reference counts managing shared usage. Cloning enhances space efficiency by creating file copies that initially share extents with the original, avoiding data duplication until modifications occur; this is tracked via inode flags like INODE_WAS_CLONED, enabling efficient operations such as document versioning or backups on the same volume.[46]

In Other Operating Systems

The New Technology File System (NTFS), introduced with Windows NT 3.1 in 1993, employs extents to allocate disk space for files through structures known as runlists, which map virtual cluster numbers to sequences of contiguous logical clusters on disk.[47] These runlists enable efficient representation of both allocated and unallocated regions, particularly supporting sparse files where gaps in the runlist indicate zero-filled areas without consuming physical storage.[48] In NTFS, the $DATA attribute of a file's Master File Table (MFT) entry stores this runlist, allowing files to span multiple non-contiguous extents while minimizing fragmentation overhead.[49] The High Performance File System (HPFS), developed for OS/2 and released with version 1.2 in 1989, represents files as collections of one or more contiguous sector runs called extents, anchored by F-nodes that store file metadata and pointers to up to eight direct extents.[50] Each F-node, located near its associated data for performance, includes the starting sector and length for these extents; for files exceeding eight extents, additional allocation nodes (ANodes) extend the structure, each supporting up to 48 more extents.[51] This design, rooted in late-1980s development efforts to surpass FAT limitations, optimizes for larger volumes and reduces seek times by favoring contiguous allocation where possible.[52] In IBM's z/OS operating system, extents form a core component of Virtual Storage Access Method (VSAM) data sets, where space is allocated in contiguous blocks that can be extended dynamically across cylinders and tracks.[53] VSAM clusters, including key-sequenced, entry-sequenced, and relative-record data sets, manage extents through control intervals, with the system automatically consolidating adjacent extents during extensions on the same volume to improve efficiency.[53] This approach builds on foundational extent concepts from OS/360 in the 1960s, with z/OS enhancements since the 2000s enabling larger, extended-format VSAM data sets that support up to 123 extents per volume for non-striped configurations.[54] Database management systems like Oracle Database and Microsoft SQL Server adopt extent-based allocation analogous to file systems, organizing storage into fixed-size units for tables and indexes. In Oracle, extents consist of contiguous blocks with a minimum size of 64 KB (eight 8 KB blocks by default), allocated from tablespaces to minimize overhead in locally managed configurations.[55] Similarly, SQL Server defines an extent as eight contiguous 8 KB pages totaling 64 KB, used to allocate space for objects like tables, with mixed extents shared among small objects and uniform extents dedicated to larger ones.[56] These mechanisms, while not full file systems, parallel extent usage by enabling efficient growth and deallocation within database files.

Advantages and Limitations

Benefits

Extents in file systems offer significant reductions in metadata overhead compared to traditional block-based allocation schemes. In block-based systems, each data block requires a separate entry in the inode or indirect blocks, leading to substantial metadata bloat for large files; for instance, a 500 MB file might require over 0.5 MB of metadata in ext2 due to individual block pointers. In contrast, extent-based systems like ext4 represent contiguous ranges of blocks with a single entry, typically 12 bytes per extent, resulting in just 48 bytes of metadata for the same 500 MB file divided into four extents—a savings of over 10,000 times in metadata size.[29] This efficiency scales with file size, providing up to 100-fold reductions for files spanning thousands of blocks, as one extent can cover up to 128 MB.[57] By promoting contiguous allocation, extents substantially lower internal fragmentation within files and reduce the overall fragmentation of the file system. This contiguity enables sequential reads and writes, which are far more efficient than scattered access patterns; on mechanical hard drives, sequential I/O can be 2-5 times faster than random scattered reads due to minimized seek times and optimized prefetching.[58] Even on SSDs, where random access is faster, extents decrease the number of metadata operations and align data for better throughput, yielding sustained performance for large sequential workloads. Extents enhance space efficiency, particularly for sparse files, by supporting "unwritten" or hole extents that mark unused ranges without allocating physical storage. This allows files with large gaps—common in databases or virtual machine images—to consume disk space only for actual data, avoiding the waste of zero-filling empty regions as in block-based systems.[57] Empirical studies demonstrate tangible performance metrics from extent adoption. Benchmarks on ext4 show 35-46% higher throughput for creating and accessing large files (e.g., 1 GB sequential writes) compared to ext3's block mapping, attributed to fewer metadata updates and better allocation contiguity.[57][59][60]

Drawbacks

Extent-based file allocation, while efficient for sequential access, is susceptible to external fragmentation, where free space becomes scattered across the disk in small, non-contiguous chunks. This occurs as files are created, modified, and deleted, leaving gaps that prevent the allocation of large contiguous extents even when sufficient total free space exists. For instance, a file requiring a 1 MB contiguous extent may fail to allocate despite 1 MB of available space distributed in smaller fragments.[61][31] Managing fragmentation adds complexity to extent-based systems, often necessitating specialized defragmentation tools to rearrange data and consolidate free space. In copy-on-write implementations, such as those in Btrfs, updates require rewriting entire extents rather than modifying in place, leading to write amplification where the volume of data written to storage significantly exceeds the user-requested amount. This amplification can reach factors of up to 32× for file overwrites due to metadata updates in B+ trees and log structures.[62][63] For small files, extent allocation introduces overhead similar to traditional block allocation, as files smaller than the filesystem's block size still consume a full block, resulting in internal fragmentation. Even with extents as small as one block, the metadata required to describe the extent—such as start block and length—adds to the inefficiency, particularly in systems with large block sizes like 4 KB, where a 1-byte file wastes nearly the entire block.[64][65] To mitigate these issues, extent-based filesystems employ strategies like online defragmentation, which rearranges extents without unmounting the filesystem, and delayed allocation to encourage larger, more contiguous writes. For example, ext4's e4defrag tool optimizes extent layouts during runtime, reducing fragmentation levels while minimizing performance impact.[66]

References

User Avatar
No comments yet.