Exemple #1
0
PyObject *py_ped_geometry_test_equal(PyObject *s, PyObject *args) {
    int ret = -1;
    PyObject *in_b = NULL;
    PedGeometry *out_a = NULL, *out_b = NULL;

    if (!PyArg_ParseTuple(args, "O!", &_ped_Geometry_Type_obj, &in_b)) {
        return NULL;
    }

    out_a = _ped_Geometry2PedGeometry(s);
    if (out_a == NULL) {
        return NULL;
    }

    out_b = _ped_Geometry2PedGeometry(in_b);
    if (out_b == NULL) {
        return NULL;
    }

    ret = ped_geometry_test_equal(out_a, out_b);

    if (ret) {
        Py_RETURN_TRUE;
    } else {
        Py_RETURN_FALSE;
    }
}
Exemple #2
0
int
hfsplus_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data;
	PedTimer*		timer_plus;
	PedGeometry*		embedded_geom;
	PedSector		hgms;

	/* check preconditions */
	PED_ASSERT (fs != NULL);
	PED_ASSERT (fs->geom != NULL);
	PED_ASSERT (geom != NULL);
	PED_ASSERT (fs->geom->dev == geom->dev);
#ifdef DEBUG
        PED_ASSERT ((hgms = hfsplus_get_min_size (fs)) != 0);
#else
        if ((hgms = hfsplus_get_min_size (fs)) == 0)
                return 0;
#endif

	if (ped_geometry_test_equal(fs->geom, geom))
		return 1;

	priv_data = (HfsPPrivateFSData*) fs->type_specific;

	if (fs->geom->start != geom->start
	    || geom->length > fs->geom->length
	    || geom->length < hgms) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Sorry, HFS+ cannot be resized that way yet."));
		return 0;
	}

	if (priv_data->wrapper) {
		PedSector		red, hgee;
		HfsPrivateFSData* 	hfs_priv_data = (HfsPrivateFSData*)
					    priv_data->wrapper->type_specific;
		unsigned int		hfs_sect_block =
			    PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
			    / PED_SECTOR_SIZE_DEFAULT;

		/* There is a wrapper so we must calculate the new geometry
		   of the embedded HFS+ volume */
		red = ( (fs->geom->length - geom->length + hfs_sect_block - 1)
			/ hfs_sect_block ) * hfs_sect_block;
		/* Can't we shrink the hfs+ volume by the desired size ? */
		hgee = hfsplus_get_empty_end (fs);
		if (!hgee) return 0;
		if (red > priv_data->plus_geom->length - hgee) {
			/* No, shrink hfs+ by the greatest possible value */
			hgee = ((hgee + hfs_sect_block - 1) / hfs_sect_block)
			       * hfs_sect_block;
			red = priv_data->plus_geom->length - hgee;
		}
		embedded_geom = ped_geometry_new (geom->dev,
						  priv_data->plus_geom->start,
						  priv_data->plus_geom->length
						  - red);

		/* There is a wrapper so the resize process is a two stages
		   process (embedded resizing then wrapper resizing) :
		   we create a sub timer */
		ped_timer_reset (timer);
		ped_timer_set_state_name (timer,
					  _("shrinking embedded HFS+ volume"));
		ped_timer_update(timer, 0.0);
		timer_plus = ped_timer_new_nested (timer, 0.98);
	} else {
		/* No wrapper : the desired geometry is the desired
		   HFS+ volume geometry */
		embedded_geom = geom;
		timer_plus = timer;
	}

	/* Resize the HFS+ volume */
	if (!hfsplus_volume_resize (fs, embedded_geom, timer_plus)) {
		if (timer_plus != timer) ped_timer_destroy_nested (timer_plus);
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Resizing the HFS+ volume has failed."));
		return 0;
	}

	if (priv_data->wrapper) {
		ped_geometry_destroy (embedded_geom);
		ped_timer_destroy_nested (timer_plus);
		ped_timer_set_state_name(timer, _("shrinking HFS wrapper"));
		timer_plus = ped_timer_new_nested (timer, 0.02);
		/* There's a wrapper : second stage = resizing it */
		if (!hfsplus_wrapper_update (fs)
		    || !hfs_resize (priv_data->wrapper, geom, timer_plus)) {
			ped_timer_destroy_nested (timer_plus);
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Updating the HFS wrapper has failed."));
			return 0;
		}
		ped_timer_destroy_nested (timer_plus);
	}
	ped_timer_update(timer, 1.0);

	return 1;
}
Exemple #3
0
int
hfs_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	unsigned int		nblock, nfree;
	unsigned int		block, to_free;
	HfsPrivateFSData* 	priv_data;
	HfsMasterDirectoryBlock* mdb;
	int			resize = 1;
	unsigned int		hfs_sect_block;
	PedSector		hgee;

	/* check preconditions */
	PED_ASSERT (fs != NULL);
	PED_ASSERT (fs->geom != NULL);
	PED_ASSERT (geom != NULL);
#ifdef DEBUG
        PED_ASSERT ((hgee = hfs_get_empty_end(fs)) != 0);
#else
        if ((hgee = hfs_get_empty_end(fs)) == 0)
                return 0;
#endif

	PED_ASSERT ((hgee = hfs_get_empty_end(fs)) != 0);

	if (ped_geometry_test_equal(fs->geom, geom))
		return 1;

	priv_data = (HfsPrivateFSData*) fs->type_specific;
	mdb = priv_data->mdb;
	hfs_sect_block = PED_BE32_TO_CPU (mdb->block_size)
			 / PED_SECTOR_SIZE_DEFAULT;

	if (fs->geom->start != geom->start
	    || geom->length > fs->geom->length
	    || geom->length < hgee + 2) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Sorry, HFS cannot be resized that way yet."));
		return 0;
	}

	/* Flush caches */
	if (!ped_geometry_sync(fs->geom))
		return 0;

	/* Clear the unmounted bit */
	mdb->volume_attributes &= PED_CPU_TO_BE16 (~( 1 << HFS_UNMOUNTED ));
	if (!ped_geometry_read (fs->geom, buf, 2, 1))
		return 0;
	memcpy (buf, mdb, sizeof (HfsMasterDirectoryBlock));
	if (   !ped_geometry_write (fs->geom, buf, 2, 1)
	    || !ped_geometry_sync  (fs->geom))
		return 0;

	ped_timer_reset (timer);
	ped_timer_set_state_name(timer, _("shrinking"));
	ped_timer_update(timer, 0.0);
	/* relocate data */
	to_free = ( fs->geom->length - geom->length
		    + hfs_sect_block - 1 )
		  / hfs_sect_block ;
	block = hfs_find_start_pack (fs, to_free);
	if (!hfs_pack_free_space_from_block (fs, block,	timer, to_free)) {
		resize = 0;
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Data relocation has failed."));
		goto write_MDB;
	}

	/* Calculate new block number and other MDB field */
	nblock = ( geom->length - (PED_BE16_TO_CPU (mdb->start_block) + 2) )
		 / hfs_sect_block;
	nfree = PED_BE16_TO_CPU (mdb->free_blocks)
		- ( PED_BE16_TO_CPU (mdb->total_blocks) - nblock );

	/* Check that all block after future end are really free */
	for (block = nblock;
	     block < PED_BE16_TO_CPU (mdb->total_blocks);
	     block++) {
		if (TST_BLOC_OCCUPATION(priv_data->alloc_map,block)) {
			resize = 0;
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Data relocation left some data in the end "
				  "of the volume."));
			goto write_MDB;
		}
	}

	/* Mark out of volume blocks as used
	(broken implementations compatibility) */
	for ( block = nblock; block < (1 << 16); ++block)
		SET_BLOC_OCCUPATION(priv_data->alloc_map,block);

	/* save the allocation map
	I do not write until start of allocation blocks
	but only until pre-resize end of bitmap blocks
	because the specifications do _not_ assert that everything
	until allocation blocks is boot, mdb and alloc */
	ped_geometry_write(fs->geom, priv_data->alloc_map,
		PED_BE16_TO_CPU (priv_data->mdb->volume_bitmap_block),
		( PED_BE16_TO_CPU (priv_data->mdb->total_blocks)
		  + PED_SECTOR_SIZE_DEFAULT * 8 - 1)
		/ (PED_SECTOR_SIZE_DEFAULT * 8));

	/* Update geometry */
	if (resize) {
		/* update in fs structure */
		if (PED_BE16_TO_CPU (mdb->next_allocation) >= nblock)
			mdb->next_allocation = PED_CPU_TO_BE16 (0);
		mdb->total_blocks = PED_CPU_TO_BE16 (nblock);
		mdb->free_blocks = PED_CPU_TO_BE16 (nfree);
		/* update parted structure */
		fs->geom->length = geom->length;
		fs->geom->end = fs->geom->start + geom->length - 1;
	}

	/* Set the unmounted bit */
	mdb->volume_attributes |= PED_CPU_TO_BE16 ( 1 << HFS_UNMOUNTED );

	/* Effective write */
    write_MDB:
	ped_timer_set_state_name(timer,_("writing HFS Master Directory Block"));

	if (!hfs_update_mdb(fs)) {
		ped_geometry_sync(geom);
		return 0;
	}

	if (!ped_geometry_sync(geom))
		return 0;

	ped_timer_update(timer, 1.0);

	return (resize);
}