h6. [[FileCore]] h6(. » [[FileCore Technical Details|Technical Details]] h6((. » Disc Map New h2(#maps). Disc Map New h3(#mapdef). Definitions used table(bordered). |_<^{width:8em}. Term |_<^. Meaning | |<^. _new map_ |<^. Used to define a specific map type supported by [[FileCore]] | |<^. _zone_ |<^. Discs are dvidided into a number of zones, each of which is contiguous section of the disc | |<^. _nzones_ |<^. The number of zones on a disc | |<^. _map block_ |<^. Each sector of the map is known as a _map block_, and controls the allocation of a zone of the disc | |<^. _ZoneCheck_ |<^. Check byte for a zone's map block. Is used to check that this zone’s map block is valid | |<^. _FreeLink_ |<^. Link to first free fragment in a specific zone. Is a fragment block giving the offset to the first free space fragment block in the allocation bytes | |<^. _CrossCheck_ |<^. Cross check byte for complete map. They are combined to check that the whole map is self-consistent | h3(#mapoverview). Overview of New Disc Map A disc has a section of information defined as a Map. It controls the allocation of the disc to the files and directories. table(bordered). |_<^{width:8em}. Map |_<^{width"8em}. Information Stored |_<^. Compaction Required |_<^. Recovery Story | |<^. _New_ |<^. Space allocation |<^. No |<^. Two copies stored | The type of map used is dependent on the format of the disc. These are detailed "here":FileCore%20Overview#laylogic. The advantages of the New map discs are: * Files need not be stored contiguously, so you don’t need to compact the disc. (However, [[FileCore]] does try to create new map files in one block, and will also try to merge file fragments back together again if it is compacting a zone of the disc.) * The disc map has no limit on size or number of entries, so ‘Map full’ errors do not occur * The map keeps a record of defects when the disc is formatted, so omits defective sectors * Defects are kept as objects on the disc, so they don’t need to be taken into account when calculating disc addresses, and can be mapped out without reformatting h3(#order). Zone Numbering The numbering of zones start at 0, and successively contain higher numbered sectors on a disc. The map's length is _nzones_ × sectors long. table(bordered). |_<^{width:8em}. Zone Number |_<^. Detail | |<^. 0 |<^. Contains the *lowest numbered* sectors on the disc | |<^. 1 |<^. | |<^. 2 |<^. | |<^. ... |<^. | |<^. _nzones_ - 2 |<^. | |<^. _nzones_ - 1 |<^. Contains the *highest numbered* sectors on the disc | h3(#maplocation). Map Location The location of the map is stored in the middle zone, or as close to the middle as possible, based on whether the number of zones are odd or even. The map's location is: _nzones_/2 (rounded down). So a disc where _nzones_ = 99, the map's location is at the start of zone 49 A disc where _nzones_ = 100, the map's location is at the start of zone 50 h3(#mapblockformat). Map Block Format The _map block_ controls the allocation of a zone of the disc. The first _map block_ controls zone 0, the second controls zone 1, and so on. The general format of a _map block_ is: table(bordered). |_<^{width:8em}. Contents |_<^. Notes | |<^. "Header":#mapblockheader |<^. | |<^. "Disc Record":#discrecord |<^. The Disc Record is only stored in Zone 0 | |<^. "Allocation Bytes":#allocation |<^. | |<^. Unused |<^. | h3(#mapblockheader). Header Contents table(bordered). |_<^{width:8em}. Offset |_<^{width:8em}. Name |_<^. Meaning | |<^. 0 |<^. _ZoneCheck_ |<^. Check byte for this zone's map block | |<^. 1 |<^. _FreeLink_ |<^. Link to first free fragment in this zone | |<^. 3 |<^. _CrossCheck_ |<^. Cross check byte for complete map | h3(#discrecord). Disc Record Multiple Disc Record Types are supported by FileCore. The Current default used by FileCore is the _Large_ Disc Record Type. h3(#allocation). Allocation Bytes The _Allocation Byte_ is the part of the _map block_ that controls the allocation of a zone. Together, the allocation bytes from all the _map block_ control the allocation of the whole disc. Each bit corresponds to an _allocation unit_ on the disc. The size of an allocation unit is defined in the disc record by _log2bpmb_, and so must be a power of two bytes. An allocation unit is not necessarily one sector – it may be smaller or larger. Not only must space be logically mapped in whole allocation units; it must also be physically allocated in whole sectors. Consequently, the smallest unit by which allocation may be changed is the larger of the sector size and the allocation unit. This unit is known as the granularity. A disc is split into a number of disc objects, each of which consists of one or more fragments spread over the surface of the disc. Fragments need not be held in the same zone, and their size can vary by whole units of granularity. Fragments have a minimum size, which is explained below: Three disc objects are special, and contain: * Bad sectors (for a perfect disc, this disc object will not be present) * Boot block, map and root directory * Free space All other disc objects contain either a directory (optionally with small files held within that directory), or one or more files that are held in a common disc object. h4(#fragments). Fragments The allocation bytes are treated as an array of bits, with the lsb of a byte coming before the msb in the array. The array is split into a series of fragment blocks, each representing a fragment. Since each bit in the array corresponds with an allocation unit on the disc, the length of the fragment block (in bits) must be the same as the size of the fragment (in allocation units). The stream of 0 bits are used to pad the fragment block to the correct length, and the 1 bit to terminate the fragment block. There are two fragment IDs with special meanings: table(bordered). |_<^{width:8em}. ID # |_<^. Meaning | |<^. 1 |<^. Represents the object which contains all bad sectors, and the spare piece of map which hangs over the real end of the disc | |<^. 2 |<^. Represents the object which contains the boot block, the map, and the root directory | Other fragment IDs represent either free space fragments, or allocated fragments: * A fragment id for a free space fragment is the unsigned offset, in bits, from the beginning of its fragment block to the beginning of the next free space fragment block in the same map block (or 0 if there are no more). The chain hence always runs from the beginning of the map block to the end. The offset to the first free space fragment block is given by the FreeLink fragment block in the map block’s header. Because that fragment block is 2 bytes long, and must have a terminating 1 bit, idlen cannot be greater than 15. * A fragment id for an allocated fragment is a unique identifier for the disc object to which that space is allocated. Any other fragments allocated to the same disc object will have the same fragment id. Therefore, the following deductions can be made: table(bordered). |_<^{width:24em}. Info |_<^. Explanation | |<^. Smallest fragment size |<^. (_idlen_ + 1) × allocation unit (rounded up to the nearest unit of granularity)<br /> This is because a fragment block cannot be smaller that _idlen_ + 1 bits (the _fragment id_, and the terminating 1 bit) | |<^. Minimum size of _idlen_ |<^. _log2secsize_ + 3<br /> This is to ensure that it is large enough to hold the maximum possible bit offset to the next free fragment block | |<^. Maximum number of _fragment ids_ in a _map block_, and hence disc objects in a zone) |<^. allocation bytes × 8 / (__idlen__ + 1) i.e. allocation bits / minimum fragment size<br /> This value is smaller for Zone 0 than other zones because it has a copy of the disc record, and hence fewer allocation bytes<br /> The value for zones other than Zone 0 is – for a given disc – always the same, and is known as the __ids per zone__. It is easiest to calculate using fields from the disc record:<br /> ((1 << (__log2secsize__ + 3)) – __zone_spare__) / (__idlen__ + 1) | |<^. Allocation Unit Size |<^. The allocation unit cannot be so small as to require more than 15 bits to represent all the fragment ids possible<br /> (__ids per zone__ × __nzones__) ≤ 2 ^15^<br /> since the fragment id cannot be more than 15 bits long | An object may have a number of fragments allocated to it in several zones. These fragments must be logically joined together in some way to make the object appear as a contiguous sequence of bytes. The naïve approach would be to have the first fragment on the disc be the first fragment of the object. New map discs do not do this. The first fragment in an object is the first fragment on the disc searching from zone (__fragment id__ / __ids per zone__) upwards, wrapping round from the disc’s end to its start. Any subsequent fragments belonging to the same disc object are joined in the order they are found by this search. Object 2, being the object which carries the map with it, is special. It is always at the beginning of the middle zone, as opposed to being at the beginning of zone 0. h4. See also * [[FileCore Overview]]