/* * The ADFS map is basically a set of sectors. Each sector is called a * zone which contains a bitstream made up of variable sized fragments. * Each bit refers to a set of bytes in the filesystem, defined by * log2bpmb. This may be larger or smaller than the sector size, but * the overall size it describes will always be a round number of * sectors. A fragment id is always idlen bits long. * * < idlen > < n > <1> * +---------+-------//---------+---+ * | frag id | 0000....000000 | 1 | * +---------+-------//---------+---+ * * The physical disk space used by a fragment is taken from the start of * the fragment id up to and including the '1' bit - ie, idlen + n + 1 * bits. * * A fragment id can be repeated multiple times in the whole map for * large or fragmented files. The first map zone a fragment starts in * is given by fragment id / ids_per_zone - this allows objects to start * from any zone on the disk. * * Free space is described by a linked list of fragments. Each free * fragment describes free space in the same way as the other fragments, * however, the frag id specifies an offset (in map bits) from the end * of this fragment to the start of the next free fragment. * * Objects stored on the disk are allocated object ids (we use these as * our inode numbers.) Object ids contain a fragment id and an optional * offset. This allows a directory fragment to contain small files * associated with that directory.
*/
/* * For the future...
*/ static DEFINE_RWLOCK(adfs_map_lock);
/* * This is fun. We need to load up to 19 bits from the map at an * arbitrary bit alignment. (We're limited to 19 bits by F+ version 2).
*/ #define GET_FRAG_ID(_map,_start,_idmask) \
({ \ unsignedchar *_m = _map + (_start >> 3); \
u32 _frag = get_unaligned_le32(_m); \
_frag >>= (_start & 7); \
_frag & _idmask; \
})
/* * return the map bit offset of the fragment frag_id in the zone dm. * Note that the loop is optimised for best asm code - look at the * output of: * gcc -D__KERNEL__ -O2 -I../../include -o - -S map.c
*/ staticint lookup_zone(conststruct adfs_discmap *dm, constunsignedint idlen, const u32 frag_id, unsignedint *offset)
{ constunsignedint endbit = dm->dm_endbit; const u32 idmask = (1 << idlen) - 1; unsignedchar *map = dm->dm_bh->b_data; unsignedint start = dm->dm_startbit; unsignedint freelink, fragend;
u32 frag;
int adfs_map_lookup(struct super_block *sb, u32 frag_id, unsignedint offset)
{ struct adfs_sb_info *asb = ADFS_SB(sb); unsignedint zone, mapoff; int result;
/* * map & root fragment is special - it starts in the center of the * disk. The other fragments start at zone (frag / ids_per_zone)
*/ if (frag_id == ADFS_ROOT_FRAG)
zone = asb->s_map_size >> 1; else
zone = frag_id / asb->s_ids_per_zone;
/* * Layout the map - the first zone contains a copy of the disc record, * and the last zone must be limited to the size of the filesystem.
*/ staticvoid adfs_map_layout(struct adfs_discmap *dm, unsignedint nzones, struct adfs_discrecord *dr)
{ unsignedint zone, zone_size;
u64 size;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.