NAME
Sys::Export::VFAT::AllocationTable - Track which FAT clusters are used, and by what
SYNOPSIS
$alloc= Sys::Export::VFAT::AllocationTable->new();
$alloc->alloc_file(\%file_attrs);
DESCRIPTION
This module manages an allocation table for a FAT filesystem. The allocation table is an array with one element per disk cluster (aside from index 0 and 1 which do not have a cluster allocated), which acts like a linked list. The value of each element says whether the cluster is used (>0), what cluster follows it, and whether it is the final cluster in the chain. For FAT32, it also has bits to flag clusters with disk errors.
This module can also pair file/directory metadata with the starting cluster of each chain.
CONSTRUCTORS
new
$at= Sys::Export::VFAT::AllocationTable->new(%attrs);
Currently the only attribute that can actually be set in the constructor is max_cluster_id.
ATTRIBUTES
fat
Direct access to the allocation table array. Don't modify it directly.
chains
Hash keyed by starting-cluster ID which holds metadata about what is stored there. The metadata may include invlist which is an inversion-list representation of the chain, or dir which is an unpacked directory.
max_cluster_id
The maximum value for a cluster ID, which is also the maximum element of the "fat" array. This may be undef to avoid exceptions while sizing up your data.
max_used_cluster_id
The maximum cluster number which was allocated so far.
first_free_cluster
When dynamically growing the table (undef max_cluster_id) this is always defined as the next unallocated cluster number. When there is a defined max_cluster_id, this becomes undef after all clusters have been allocated.
free_cluster_count
When dynamically growing the table (undef max_cluster_id) this only reports free "holes" in the allocations so far, and 0 otherwise. When max_cluster_id is defined, this gives the actual number of unallocated clusters.
METHODS
set_max_cluster_id
This can change the allocation between dynamically-growing (undef) and fixed-length. The number must be 2 or greater, and cannot be less than max_used_cluster_id.
get_chain
$metadata= $self->get_chain($cluster_id);
Returns the metadata associated with the head cluster of a cluster chain. Clusters which are not the heads of chains return nothing.
alloc
$cl_head= $at->alloc($cl_count);
Create a cluster chain of $cl_count clusters from anywhere in the table and return the cluster ID of the head of the chain. $cl_count must be an integer. A request for 0 clusters returns cluster ID 0.
alloc_range
$cl_head= $at->alloc_range($cl_id, $cl_count);
Create a cluster chain from a specific extent of clusters. If any cluster was already allocated this fails and returns false. $cl_id must be 2 or larger. A request for 0 clusters returns cluster ID 0.
alloc_contiguous
$cl_head= $at->alloc_contiguous($cl_count, $align=1, $align_ofs=0);
Allocate the first available contiguous span of $cl_count clusters, optionally restricted to the cluster ID being a multiple of a power-of-two alignment, when offset by $align_ofs.
See "get_cluster_alignment_of_device_alignment" in Sys::Export::VFAT::Geometry.
pack
$buf= $at->pack
Pack the allocation table into bytes. This selects FAT12/FAT16/FAT32 by the total number of clusters. Make sure you set "max_cluster_id" correctly before calling this.
VERSION
version 0.005
AUTHOR
Michael Conrad <mike@nrdvana.net>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Michael Conrad.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.