Beispiel #1
0
static int
_amiga_find_free_blocks(const PedDisk *disk, uint32_t *table,
	struct LinkedBlock *block, uint32_t first, uint32_t type)
{
	PedSector next;

	PED_ASSERT(disk != NULL);
	PED_ASSERT(disk->dev != NULL);

	for (next = first; next != LINK_END; next = PED_BE32_TO_CPU(block->lk_Next)) {
		if (table[next] != IDNAME_FREE) {
			switch (ped_exception_throw(PED_EXCEPTION_ERROR,
				PED_EXCEPTION_FIX | PED_EXCEPTION_IGNORE | PED_EXCEPTION_CANCEL,
				_("%s : Loop detected at block %d."), __func__, next))
			{
				case PED_EXCEPTION_CANCEL :
					return 0;
				case PED_EXCEPTION_FIX :
					/* TODO : Need to add fixing code */
				case PED_EXCEPTION_IGNORE :
				case PED_EXCEPTION_UNHANDLED :
				default :
					return 1;
			}
		}

		if (!_amiga_read_block (disk->dev, AMIGA(block), next, NULL)) {
			return 0;
		}
		if (PED_BE32_TO_CPU(block->lk_ID) != type) {
			switch (ped_exception_throw(PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("%s : The %s list seems bad at block %s."),
				__func__, _amiga_block_id(PED_BE32_TO_CPU(block->lk_ID)), next))
			{
				/* TODO : to more subtile things here */
				case PED_EXCEPTION_CANCEL :
				case PED_EXCEPTION_UNHANDLED :
				default :
					return 0;
			}
		}
		table[next] = type;
		if (PED_BE32_TO_CPU(block->lk_ID) == IDNAME_FILESYSHEADER) {
			if (_amiga_find_free_blocks(disk, table, block,
				PED_BE32_TO_CPU(LNK2(block)->lk2_Linked),
				IDNAME_LOADSEG) == 0) return 0;
		}
	}
	return 1;
}
Beispiel #2
0
static uint32_t
_amiga_find_rdb (PedDevice *dev, struct RigidDiskBlock *rdb) {
	int i;
	struct AmigaIds *ids;

	ids = _amiga_add_id (IDNAME_RIGIDDISK, NULL);

	for (i = 0; i<RDB_LOCATION_LIMIT; i++) {
		if (!_amiga_read_block (dev, AMIGA(rdb), i, ids)) {
			continue;
		}
		if (PED_BE32_TO_CPU (rdb->rdb_ID) == IDNAME_RIGIDDISK) {
			_amiga_free_ids (ids);
			return i;
		}
	}
	_amiga_free_ids (ids);
	return AMIGA_RDB_NOT_FOUND;
}
Beispiel #3
0
/* We have already allocated a rdb, we are now reading it from the disk */
static int
amiga_read (PedDisk* disk)
{
	struct RigidDiskBlock *rdb;
	struct PartitionBlock *partition;
	uint32_t partblock;
	uint32_t partlist[AMIGA_MAX_PARTITIONS];
	PedSector cylblocks;
	int i;

	PED_ASSERT(disk != NULL);
	PED_ASSERT(disk->dev != NULL);
	PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
	PED_ASSERT(disk->disk_specific != NULL);
	rdb = RDSK(disk->disk_specific);

	if (_amiga_find_rdb (disk->dev, rdb) == AMIGA_RDB_NOT_FOUND) {
		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("%s : Didn't find rdb block, should never happen."), __func__);
		return 0;
	}

	/* Let's copy the rdb read geometry to the dev */
	/* FIXME: should this go into disk->dev->bios_geom instead? */
	disk->dev->hw_geom.cylinders = PED_BE32_TO_CPU (rdb->rdb_Cylinders);
	disk->dev->hw_geom.heads = PED_BE32_TO_CPU (rdb->rdb_Heads);
	disk->dev->hw_geom.sectors = PED_BE32_TO_CPU (rdb->rdb_Sectors);
	cylblocks = (PedSector) PED_BE32_TO_CPU (rdb->rdb_Heads) *
		(PedSector) PED_BE32_TO_CPU (rdb->rdb_Sectors);

	/* Remove all partitions in the former in memory table */
	ped_disk_delete_all (disk);

	/* Let's allocate a partition block */
	if (!(partition = ped_malloc (disk->dev->sector_size)))
		return 0;

	/* We initialize the hardblock free list to detect loops */
	for (i = 0; i < AMIGA_MAX_PARTITIONS; i++) partlist[i] = LINK_END;

	for (i = 1, partblock = PED_BE32_TO_CPU(rdb->rdb_PartitionList);
		i < AMIGA_MAX_PARTITIONS && partblock != LINK_END;
		i++, partblock = PED_BE32_TO_CPU(partition->pb_Next))
	{
		PedPartition *part;
		PedSector start, end;

		/* Let's look for loops in the partition table */
		if (_amiga_loop_check(partblock, partlist, i)) {
			break;
		}

		/* Let's allocate and read a partition block to get its geometry*/
		if (!_amiga_read_block (disk->dev, AMIGA(partition),
		                        (PedSector)partblock, NULL)) {
			free(partition);
			return 0;
		}

		start = ((PedSector) PED_BE32_TO_CPU (partition->de_LowCyl))
			* cylblocks;
		end = (((PedSector) PED_BE32_TO_CPU (partition->de_HighCyl))
			+ 1) * cylblocks - 1;

		/* We can now construct a new partition */
		if (!(part = ped_partition_new (disk, PED_PARTITION_NORMAL,
                                                NULL, start, end))) {
			free(partition);
			return 0;
		}
		/* And copy over the partition block */
		memcpy(part->disk_specific, partition, 256);

		part->num = i;
		part->type = 0;
		/* Let's probe what file system is present on the disk */
		part->fs_type = ped_file_system_probe (&part->geom);

		PedConstraint *constraint_exact
			= ped_constraint_exact (&part->geom);
		if (constraint_exact == NULL)
			return 0;
		bool ok = ped_disk_add_partition (disk, part, constraint_exact);
		ped_constraint_destroy (constraint_exact);
		if (!ok) {
			ped_partition_destroy(part);
			free(partition);
			return 0;
		}
	}
	free(partition);
	return 1;
}