예제 #1
0
파일: ufs.c 프로젝트: Excito/parted
static PedGeometry*
ufs_probe_sun (PedGeometry* geom)
{
	int8_t buf[512 * 3];
	struct ufs_super_block *sb;

	if (geom->length < 5)
		return 0;
	if (!ped_geometry_read (geom, buf, 16, 3))
		return 0;

	sb = (struct ufs_super_block *)buf;

	if (PED_BE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
		PedSector block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
		PedSector block_count = PED_BE32_TO_CPU(sb->fs_size);
		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}
	if (PED_LE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
		PedSector block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
		PedSector block_count = PED_LE32_TO_CPU(sb->fs_size);
		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}
	return NULL;
}
예제 #2
0
파일: xfs.c 프로젝트: inteos/WBSAirback
static PedGeometry*
xfs_probe (PedGeometry* geom)
{
	PedSector	block_size;
	PedSector	block_count;
	union {
		struct xfs_sb	sb;
		char		bytes [512];
	} buf;

	if (geom->length < XFS_SB_DADDR + 1)
		return NULL;
	if (!ped_geometry_read (geom, &buf, XFS_SB_DADDR, 1))
		return NULL;

	if (PED_LE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
		block_size = PED_LE32_TO_CPU (buf.sb.sb_blocksize) / 512;
		block_count = PED_LE64_TO_CPU (buf.sb.sb_dblocks);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}

	if (PED_BE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
		block_size = PED_BE32_TO_CPU (buf.sb.sb_blocksize) / 512;
		block_count = PED_BE64_TO_CPU (buf.sb.sb_dblocks);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}

	return NULL;
}
예제 #3
0
static int
bsd_read (PedDisk* disk)
{
	BSDDiskData*	bsd_specific = (BSDDiskData*) disk->disk_specific;
	BSDRawLabel*	label;
	int 		i;

	ped_disk_delete_all (disk);

	void *s0;
	if (!ptt_read_sector (disk->dev, 0, &s0))
		return 0;

	memcpy (bsd_specific->boot_code, s0, sizeof (bsd_specific->boot_code));
	free (s0);

	label = (BSDRawLabel *) (bsd_specific->boot_code + BSD_LABEL_OFFSET);

	for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
		PedPartition* 		part;
		BSDPartitionData*	bsd_part_data;
		PedSector		start;
		PedSector		end;
		PedConstraint*		constraint_exact;

		if (!label->d_partitions[i - 1].p_size
		    || !label->d_partitions[i - 1].p_fstype)
			continue;
		start = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset);
		end = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset)
		      + PED_LE32_TO_CPU(label->d_partitions[i - 1].p_size) - 1;
		part = ped_partition_new (disk, PED_PARTITION_NORMAL,
                                          NULL, start, end);
		if (!part)
			goto error;
		bsd_part_data = part->disk_specific;
		bsd_part_data->type = label->d_partitions[i - 1].p_fstype;
		part->num = i;
		part->fs_type = ped_file_system_probe (&part->geom);

		constraint_exact = ped_constraint_exact (&part->geom);
		if (!ped_disk_add_partition (disk, part, constraint_exact))
			goto error;
		ped_constraint_destroy (constraint_exact);
	}

	return 1;

error:
	return 0;
}
예제 #4
0
static PedGeometry*
jfs_probe (PedGeometry* geom)
{
	union {
		struct superblock	sb;
		char			bytes[512];
	} buf;

        /* FIXME: for now, don't even try to deal with larger sector size.  */
	if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
		return NULL;

	if (geom->length < JFS_SUPER_SECTOR + 1)
		return NULL;
	if (!ped_geometry_read (geom, &buf, JFS_SUPER_SECTOR, 1))
		return NULL;

	if (strncmp (buf.sb.s_magic, JFS_MAGIC, 4) == 0) {
		PedSector block_size = PED_LE32_TO_CPU (buf.sb.s_pbsize) / 512;
		PedSector block_count = PED_LE64_TO_CPU (buf.sb.s_size);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	} else {
		return NULL;
	}
}
예제 #5
0
파일: reiserfs.c 프로젝트: NekPoN/parted
static PedGeometry *reiserfs_probe(PedGeometry *geom)
{
	int i;
	reiserfs_super_block_t sb;

	PED_ASSERT(geom != NULL);

	for (i = 0; reiserfs_super_offset[i] != -1; i++) {
		if (reiserfs_super_offset[i] >= geom->length)
			continue;
		if (!ped_geometry_read (geom, &sb, reiserfs_super_offset[i], 1))
			continue;

		if (strncmp(REISERFS_SIGNATURE, sb.s_magic,
		            strlen(REISERFS_SIGNATURE)) == 0
		    || strncmp(REISER2FS_SIGNATURE, sb.s_magic,
			       strlen(REISER2FS_SIGNATURE)) == 0
		    || strncmp(REISER3FS_SIGNATURE, sb.s_magic,
			       strlen(REISER3FS_SIGNATURE)) == 0) {
			PedSector block_size;
			PedSector block_count;

			block_size = PED_LE16_TO_CPU(sb.s_blocksize)
					/ PED_SECTOR_SIZE_DEFAULT;
			block_count = PED_LE32_TO_CPU(sb.s_block_count);

			return ped_geometry_new(geom->dev, geom->start,
						block_size * block_count);
		}
	}
	return NULL;
}
예제 #6
0
파일: ufs.c 프로젝트: Excito/parted
static PedGeometry*
ufs_probe_hp (PedGeometry* geom)
{
	int8_t buf[1536];
	struct ufs_super_block *sb;
	PedSector block_size;
	PedSector block_count;

	if (geom->length < 5)
		return 0;
	if (!ped_geometry_read (geom, buf, 16, 3))
		return 0;

	sb = (struct ufs_super_block *)buf;

	/* Try sane bytesex */
	switch (PED_BE32_TO_CPU(sb->fs_magic)) {
		case UFS_MAGIC_LFN:
		case UFS_MAGIC_FEA:
		case UFS_MAGIC_4GB:
			block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
			block_count = PED_BE32_TO_CPU(sb->fs_size);
			return ped_geometry_new (geom->dev, geom->start,
						 block_size * block_count);
	}

	/* Try perverted bytesex */
	switch (PED_LE32_TO_CPU(sb->fs_magic)) {
		case UFS_MAGIC_LFN:
		case UFS_MAGIC_FEA:
		case UFS_MAGIC_4GB:
			block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
			block_count = PED_LE32_TO_CPU(sb->fs_size);
			return ped_geometry_new (geom->dev, geom->start,
						 block_size * block_count);
	}
	return NULL;
}
예제 #7
0
파일: bootsector.c 프로젝트: bcl/parted
int
fat_info_sector_read (FatInfoSector** isp, const PedFileSystem* fs)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
	int		status;

	PED_ASSERT (isp != NULL);

	if (!ped_geometry_read_alloc (fs->geom, (void **)isp, fs_info->info_sector_offset, 1))
		return 0;
	FatInfoSector *is = *isp;
	if (PED_LE32_TO_CPU (is->signature_2) != FAT32_INFO_MAGIC2) {
		status = ped_exception_throw (PED_EXCEPTION_WARNING,
				PED_EXCEPTION_IGNORE_CANCEL,
				_("The information sector has the wrong "
				"signature (%x).  Select cancel for now, "
				"and send in a bug report.  If you're "
				"desperate, it's probably safe to ignore."),
				PED_LE32_TO_CPU (is->signature_2));
		if (status == PED_EXCEPTION_CANCEL) return 0;
	}
	return 1;
}
예제 #8
0
static PedGeometry*
jfs_probe (PedGeometry* geom)
{
	union {
		struct superblock	sb;
		char			bytes[512];
	} buf;

	if (geom->length < JFS_SUPER_SECTOR + 1)
		return NULL;
	if (!ped_geometry_read (geom, &buf, JFS_SUPER_SECTOR, 1))
		return NULL;

	if (strncmp (buf.sb.s_magic, JFS_MAGIC, 4) == 0) {
		PedSector block_size = PED_LE32_TO_CPU (buf.sb.s_pbsize) / 512;
		PedSector block_count = PED_LE64_TO_CPU (buf.sb.s_size);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	} else {
		return NULL;
	}
}
예제 #9
0
static int
bsd_probe (const PedDevice *dev)
{
	BSDRawLabel	*partition;

	PED_ASSERT (dev != NULL);

        if (dev->sector_size < 512)
                return 0;

	void *label;
	if (!ptt_read_sector (dev, 0, &label))
		return 0;

	partition = (BSDRawLabel *) ((char *) label + BSD_LABEL_OFFSET);

	alpha_bootblock_checksum(label);

	/* check magic */
        bool found = PED_LE32_TO_CPU (partition->d_magic) == BSD_DISKMAGIC;
	free (label);
	return found;
}
예제 #10
0
/* 1 => Success, the journal has been completly replayed, or don't need to */
int
hfsj_replay_journal(PedFileSystem* fs)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedSector		sector, length;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						    fs->type_specific;
	HfsJJournalInfoBlock*	jib;
	HfsJJournalHeader*	jh;
	int			binsect;
	uint32_t		cksum;

	binsect = PED_BE32_TO_CPU(priv_data->vh->block_size) / PED_SECTOR_SIZE_DEFAULT;
	priv_data->jib_start_block =
		PED_BE32_TO_CPU(priv_data->vh->journal_info_block);
	sector  = (PedSector) priv_data->jib_start_block * binsect;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jib = (HfsJJournalInfoBlock*) buf;

	if (    (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
	    && !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
		priv_data->jl_start_block = HFS_64_TO_CPU(jib->offset, is_le)
					    / ( PED_SECTOR_SIZE_DEFAULT * binsect );
	}

	if (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_NEED_INIT))
		return 1;

	if (  !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
	    || (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Journal stored outside of the volume are "
			  "not supported.  Try to desactivate the "
			  "journal and run Parted again."));
		return 0;
	}

	if (   (PED_BE64_TO_CPU(jib->offset) % PED_SECTOR_SIZE_DEFAULT)
	    || (PED_BE64_TO_CPU(jib->size)   % PED_SECTOR_SIZE_DEFAULT) ) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Journal offset or size is not multiple of "
			  "the sector size."));
		return 0;
	}

	sector = PED_BE64_TO_CPU(jib->offset) / PED_SECTOR_SIZE_DEFAULT;
	length = PED_BE64_TO_CPU(jib->size)   / PED_SECTOR_SIZE_DEFAULT;

	jib = NULL;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jh = (HfsJJournalHeader*) buf;

	if (jh->endian == PED_LE32_TO_CPU(HFSJ_ENDIAN_MAGIC))
	    is_le = 1;

	if (   (jh->magic  != HFS_32_TO_CPU(HFSJ_HEADER_MAGIC, is_le))
	    || (jh->endian != HFS_32_TO_CPU(HFSJ_ENDIAN_MAGIC, is_le)) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Incorrect magic values in the journal header."));
		return 0;
	}

	if ( (HFS_64_TO_CPU(jh->size, is_le)%PED_SECTOR_SIZE_DEFAULT)
	  || (HFS_64_TO_CPU(jh->size, is_le)/PED_SECTOR_SIZE_DEFAULT
		  != (uint64_t)length) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Journal size mismatch between journal info block "
			  "and journal header."));
		return 0;
	}

	if (   (HFS_64_TO_CPU(jh->start, is_le) % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_64_TO_CPU(jh->end, is_le)   % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_32_TO_CPU(jh->blhdr_size, is_le) % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_32_TO_CPU(jh->jhdr_size, is_le)  % PED_SECTOR_SIZE_DEFAULT) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Some header fields are not multiple of the sector "
			  "size."));
		return 0;
	}

	if (HFS_32_TO_CPU(jh->jhdr_size, is_le) != PED_SECTOR_SIZE_DEFAULT) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("The sector size stored in the journal is not 512 "
			  "bytes.  Parted only supports 512 bytes length "
			  "sectors."));
		return 0;
	}

	cksum = HFS_32_TO_CPU(jh->checksum, is_le);
	jh->checksum = 0;
	if (cksum != hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh))) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Bad journal checksum."));
		return 0;
	}
	jh->checksum = HFS_CPU_TO_32(cksum, is_le);

	/* The 2 following test are in the XNU Darwin source code */
	/* so I assume they're needed */
	if (jh->start == jh->size)
		jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);
	if (jh->end   == jh->size)
		jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);

	if (jh->start == jh->end)
		return 1;

	if (ped_exception_throw (
		PED_EXCEPTION_WARNING,
		PED_EXCEPTION_FIX | PED_EXCEPTION_CANCEL,
		_("The journal is not empty.  Parted must replay the "
		  "transactions before opening the file system.  This will "
		  "modify the file system."))
			!= PED_EXCEPTION_FIX)
		return 0;

	while (jh->start != jh->end) {
		/* Replay one complete transaction */
		if (!hfsj_replay_transaction(fs, jh, sector, length))
			return 0;

		/* Recalculate cksum of the journal header */
		jh->checksum = 0; /* need to be 0 while calculating the cksum */
		cksum = hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh));
		jh->checksum = HFS_CPU_TO_32(cksum, is_le);

		/* Update the Journal Header */
		if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
		    || !ped_geometry_sync(priv_data->plus_geom))
			return 0;
	}

	if (hfsj_vh_replayed) {
		/* probe could have reported incorrect info ! */
		/* is there a way to ask parted to quit ? */
		ped_exception_throw(
			PED_EXCEPTION_WARNING,
			PED_EXCEPTION_OK,
			_("The volume header or the master directory block has "
			  "changed while replaying the journal.  You should "
			  "restart Parted."));
		return 0;
	}

	return 1;
}
예제 #11
0
uint32_t
fat_dir_entry_get_length (FatDirEntry* dir_entry)
{
	return PED_LE32_TO_CPU (dir_entry->length);
}
예제 #12
0
파일: bootsector.c 프로젝트: bcl/parted
/* Analyses the boot sector, and sticks appropriate numbers in
   fs->type_specific.

   Note: you need to subtract (2 * cluster_sectors) off cluster offset,
   because the first cluster is number 2.  (0 and 1 are not real clusters,
   and referencing them is a bug)
 */
int
fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs)
{
	FatSpecific*		fs_info = FAT_SPECIFIC (fs);
	int			fat_entry_size;

	PED_ASSERT (bs != NULL);

	fs_info->logical_sector_size = PED_LE16_TO_CPU (bs->sector_size) / 512;

	fs_info->sectors_per_track = PED_LE16_TO_CPU (bs->secs_track);
	fs_info->heads = PED_LE16_TO_CPU (bs->heads);
	if (fs_info->sectors_per_track < 1 || fs_info->sectors_per_track > 63
	    || fs_info->heads < 1 || fs_info->heads > 255) {
		PedCHSGeometry* bios_geom = &fs->geom->dev->bios_geom;
		int cyl_count = 0;

		if (fs_info->heads > 0 && fs_info->sectors_per_track > 0)
			cyl_count = fs->geom->dev->length / fs_info->heads
					/ fs_info->sectors_per_track;

		switch (ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_FIX + PED_EXCEPTION_IGNORE
			+ PED_EXCEPTION_CANCEL,
			_("The file system's CHS geometry is (%d, %d, %d), "
			  "which is invalid.  The partition table's CHS "
			  "geometry is (%d, %d, %d).  If you select Ignore, "
			  "the file system's CHS geometry will be left "
			  "unchanged.  If you select Fix, the file system's "
			  "CHS geometry will be set to match the partition "
			  "table's CHS geometry."),
			 cyl_count, fs_info->heads, fs_info->sectors_per_track,
			 bios_geom->cylinders, bios_geom->heads,
			 bios_geom->sectors)) {

		case PED_EXCEPTION_FIX:
			fs_info->sectors_per_track = bios_geom->sectors;
			fs_info->heads = bios_geom->heads;
			bs->secs_track
				= PED_CPU_TO_LE16 (fs_info->sectors_per_track);
			bs->heads = PED_CPU_TO_LE16 (fs_info->heads);
			if (!fat_boot_sector_write (bs, fs))
				return 0;
			break;

		case PED_EXCEPTION_CANCEL:
			return 0;

		case PED_EXCEPTION_IGNORE:
			break;

                default:
                        break;
		}
	}

	if (bs->sectors)
		fs_info->sector_count = PED_LE16_TO_CPU (bs->sectors)
						* fs_info->logical_sector_size;
	else
		fs_info->sector_count = PED_LE32_TO_CPU (bs->sector_count)
						* fs_info->logical_sector_size;

	fs_info->fat_table_count = bs->fats;
	fs_info->root_dir_entry_count = PED_LE16_TO_CPU (bs->dir_entries);
	fs_info->fat_offset = PED_LE16_TO_CPU (bs->reserved)
					* fs_info->logical_sector_size;
	fs_info->cluster_sectors = bs->cluster_size
				   * fs_info->logical_sector_size;
	fs_info->cluster_size = fs_info->cluster_sectors * 512;

	if (fs_info->logical_sector_size == 0) {
		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("FAT boot sector says logical sector size is 0.  "
			  "This is weird. "));
		return 0;
	}
	if (fs_info->fat_table_count == 0) {
		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("FAT boot sector says there are no FAT tables.  This "
			  "is weird. "));
		return 0;
	}
	if (fs_info->cluster_sectors == 0) {
		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("FAT boot sector says clusters are 0 sectors.  This "
			  "is weird. "));
		return 0;
	}

	fs_info->fat_type = fat_boot_sector_probe_type (bs, fs->geom);
	if (fs_info->fat_type == FAT_TYPE_FAT12) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("File system is FAT12, which is unsupported."));
		return 0;
	}
	if (fs_info->fat_type == FAT_TYPE_FAT16) {
		fs_info->fat_sectors = PED_LE16_TO_CPU (bs->fat_length)
				       * fs_info->logical_sector_size;
		fs_info->serial_number
			= PED_LE32_TO_CPU (bs->u.fat16.serial_number);
		fs_info->root_cluster = 0;
		fs_info->root_dir_offset
			= fs_info->fat_offset
			  + fs_info->fat_sectors * fs_info->fat_table_count;
		fs_info->root_dir_sector_count
			= fs_info->root_dir_entry_count * sizeof (FatDirEntry)
			  / (512 * fs_info->logical_sector_size);
		fs_info->cluster_offset
			= fs_info->root_dir_offset
			  + fs_info->root_dir_sector_count;
	}
	if (fs_info->fat_type == FAT_TYPE_FAT32) {
		fs_info->fat_sectors = PED_LE32_TO_CPU (bs->u.fat32.fat_length)
					* fs_info->logical_sector_size;
		fs_info->serial_number
			= PED_LE32_TO_CPU (bs->u.fat32.serial_number);
		fs_info->info_sector_offset
		    = PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.info_sector)
			  * fs_info->logical_sector_size;
		fs_info->boot_sector_backup_offset
		  = PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.backup_sector)
			  * fs_info->logical_sector_size;
		fs_info->root_cluster
			= PED_LE32_TO_CPU (bs->u.fat32.root_dir_cluster);
		fs_info->root_dir_offset = 0;
		fs_info->root_dir_sector_count = 0;
		fs_info->cluster_offset
			= fs_info->fat_offset
			  + fs_info->fat_sectors * fs_info->fat_table_count;
	}

	fs_info->cluster_count
		= (fs_info->sector_count - fs_info->cluster_offset)
		  / fs_info->cluster_sectors;

	fat_entry_size = fat_table_entry_size (fs_info->fat_type);
	if (fs_info->cluster_count + 2
			> fs_info->fat_sectors * 512 / fat_entry_size)
		fs_info->cluster_count
			= fs_info->fat_sectors * 512 / fat_entry_size - 2;

	fs_info->dir_entries_per_cluster
		= fs_info->cluster_size / sizeof (FatDirEntry);
	return 1;
}