формат супер-блока (второстепенные поля опущены)
За концом супеблока, на некотором отдалении от него, находится первая группа цилиндров. В начале каждой группы расположена служебная структура cg (далее по тексту — описатель группы цилиндров, термин мой — КК), содержащая магическую последовательность 55h 02h 09h по которую все уцелевшие группы можно найти даже при полностью испорченном супеблоке (штатным образом, стартовые адреса всех последующих групп вычисляются путем умножения номера группы на ее размер, содержащийся в поле fs_cgsize).
Другие важные параметры:
q cg_cgx — порядковой номер группы, отсчитываемый от нуля;
q cg_old_niblk — кол-во inode в данной группе;
q cg_ndblk — кол-во блоков данных в данной группе;
q csum — кол-во свободных inode и блоков данных в данной группе;
q cg_iusedoff — смещение карты занятых inod'e, отсчитываемое от начала данной группы и измеряемое в байтах;
q cg_freeoff — смещение карты свободного пространства (байты от начла группы);
Структура cg определена в файле /src/ufs/ffs/fs.h и выглядит следующим образом:
#define CG_MAGIC 0x090255
#define MAXFRAG 8
struct cg {
/* 0x00 */ int32_t cg_firstfield; /* historic cyl groups linked list */
/* 0x04 */ int32_t cg_magic; /* magic number */
/* 0x08 */ int32_t cg_old_time; /* time last written */
/* 0x0С */ int32_t cg_cgx; /* we are the cgx'th cylinder group */
/* 0x10 */ int16_t cg_old_ncyl; /* number of cyl's this cg */
/* 0x12 */ int16_t cg_old_niblk; /* number of inode blocks this cg */
/* 0x14 */ int32_t cg_ndblk; /* number of data blocks this cg */
/* 0x18 */ struct csum cg_cs; /* cylinder summary information */
/* 0x28 */ int32_t cg_rotor; /* position of last used block */
/* 0x2С */ int32_t cg_frotor; /* position of last used frag */
/* 0x30 */ int32_t cg_irotor; /* position of last used inode */
/* 0x34 */ int32_t cg_frsum[MAXFRAG]; /* counts of available frags */
/* 0x54 */ int32_t cg_old_btotoff; /* (int32) block totals per cylinder */
/* 0x58 */ int32_t cg_old_boff; /* (u_int16) free block positions */
/* 0x5С */ int32_t cg_iusedoff; /* (u_int8) used inode map */
/* 0x60 */ int32_t cg_freeoff; /* (u_int8) free block map */
/* 0x64 */ int32_t cg_nextfreeoff; /* (u_int8) next available space */
/* 0x68 */ int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */
/* 0x6С */ int32_t cg_clusteroff; /* (u_int8) free cluster map */
/* 0x70 */ int32_t cg_nclusterblks; /* number of clusters this cg */
/* 0x74 */ int32_t cg_niblk; /* number of inode blocks this cg */
/* 0x78 */ int32_t cg_initediblk; /* last initialized inode */
/* 0x7С */ int32_t cg_sparecon32[3]; /* reserved for future use */
/* 0x00 */ ufs_time_t cg_time; /* time last written */
/* 0x00 */ int64_t cg_sparecon64[3]; /* reserved for future use */
/* 0x00 */ u_int8_t cg_space[1]; /* space for cylinder group maps */
/* actually longer */