Computer virtualization is a technique that involves encapsulating a physical computing machine platform into a virtual machine that is executed under the control of virtualization software on a hardware computing platform, or “host.” A virtual machine has both virtual system hardware and guest operating system software. Virtual system hardware typically includes at least one “virtual disk,” a single file or a set of files that appear as a typical storage drive to the guest operating system. The virtual disk may be stored on the host platform or on a remote storage device. Typically, a virtual machine (VM) uses the virtual disk to store the guest operating system, application programs, and application data.
In a virtualized environment, application programs executing on the VM access the physical disk space via a virtualization stack. The virtualization stack includes multiple software layers (referred to herein as the “logical layers”) above the ultimate physical storage layer, the physical disk. Logical layers of the virtualization stack include the guest operating system, the hypervisor and the virtual machine file system (VMFS) driver. Each logical layer is associated with a data block layer that maintains and tracks the allocation of logical data blocks in response to requests received from the applications executing on the VM. Translation mechanisms in each logical layer allow for managing the relationships between data blocks across different data block layers.
Storage access requests from applications executing on the VM are transmitted to the top-most layer of the virtualization stack, which identifies the logical data blocks in the associated data block layer that correspond to the request. The top layer then transmits the request to the next layer of the virtual storage stack, which in turn identifies the logical data blocks in the associated data block layer that correspond to the request. In such a manner, the request traverses the virtual storage stack until the request reaches the physical layer, where the request is serviced.
In response to write requests received from applications executing on the VM, data blocks in each data block layer associated with a logical layer are allocated for servicing the request. Ultimately, once the logical layers are traversed, disk space in the physical storage layer is allocated for storing the data associated with the write request. In operation, storage virtualization has over-commit goals that lead to sparse allocation of storage blocks in the physical storage layer. More specifically, at each logical layer, storage block allocation is sequenced in order of first writes such that, after a region has been provisioned, block allocation and the underlying physical storage allocation is delayed until a first write occurs in the provisioned region. Such delayed allocation may not preserve spatial locality at the physical storage layer, which may have served other allocation requests in between the receipt of the provisioning request and the allocation request from the particular logical layer. Such a phenomenon leads to fragmentation at the physical storage layer, where storage blocks that should be stored contiguously from a logical point of view are not physically laid out contiguously. Physical fragmentation is highly undesirable because physical co-location of data blocks that are to be accessed sequentially allows for significantly faster access than if those data blocks are not physically co-located.
One solution to reduce fragmentation at the physical storage layer is to increase the size of data blocks in the data block layers associated with the physical layers. With such an approach, a single write request from the application results in allocating enough of extra contiguous physical storage to accommodate physical co-locality of future writes. Such an approach, however, has limitations. More specifically, future writes may never occur and, thus, the allocated space may never be used. Further, large storage block sizes may have an adverse impact on the storage services that a virtualized environment can provide. For example, a large block size is undesirable for de-duplication where probability of finding duplicates depends on blocks sizes being small. Storage related services, like snapshotting, that use copy on write are also adversely affected if the blocks size is too large as larger blocks are to be read before doing a copy on write and eliminating copy on write overheads in cases of full overwrites are reduced. As the foregoing illustrates, there remains a need in the art for an effective storage block allocation technique that reduces the amount of fragmentation.