Пример #1
0
static void gauge_handler(const char *name, unsigned int value, void *data,
			  int determined, int update_header,
			  int update_footer)
{
	PedTimer *timer = (PedTimer *) data;
	ped_timer_set_state_name(timer, name);
	ped_timer_update(timer, 1.0 * value / 100);
}
Пример #2
0
PyObject *py_ped_timer_set_state_name(PyObject *s, PyObject *args) {
    char *str = NULL;
    PedTimer *timer = NULL;

    if (!PyArg_ParseTuple(args, "z", &str)) {
        return NULL;
    }

    timer = _ped_Timer2PedTimer(s);
    if (timer == NULL) {
        return NULL;
    }

    ped_timer_set_state_name(timer, str);

    ped_timer_destroy(timer);
    free(str);

    Py_INCREF(Py_None);
    return Py_None;
}
Пример #3
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;
}
Пример #4
0
static int
hfsplus_volume_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	unsigned int		nblock, nfree, mblock;
	unsigned int		block, to_free, old_blocks;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsPVolumeHeader* 	vh = priv_data->vh;
	int			resize = 1;
	unsigned int		hfsp_sect_block =
				    ( PED_BE32_TO_CPU (vh->block_size)
				      / PED_SECTOR_SIZE_DEFAULT );
	unsigned int		map_sectors;

	old_blocks = PED_BE32_TO_CPU (vh->total_blocks);

	/* Flush caches */
	if (!ped_geometry_sync(priv_data->plus_geom))
		return 0;

	/* Clear the unmounted bit */
	/* and set the implementation code (Apple Creator Code) */
	vh->attributes &= PED_CPU_TO_BE32 (~( 1 << HFS_UNMOUNTED ));
	vh->last_mounted_version = PED_CPU_TO_BE32(HFSP_IMPL_Shnk);
	if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1))
		return 0;
	memcpy (buf, vh, sizeof (HfsPVolumeHeader));
	if (   !ped_geometry_write (priv_data->plus_geom, buf, 2, 1)
	    || !ped_geometry_sync (priv_data->plus_geom))
		return 0;

	ped_timer_reset (timer);
	ped_timer_set_state_name(timer, _("shrinking"));
	ped_timer_update(timer, 0.0);
	/* relocate data */
	to_free = ( priv_data->plus_geom->length
	          - geom->length + hfsp_sect_block
		  - 1 ) / hfsp_sect_block;
	block = hfsplus_find_start_pack (fs, to_free);
	if (!hfsplus_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_VH;
	}

	/* Calculate new block number and other VH field */
	/* nblock must be rounded _down_ */
	nblock = geom->length / hfsp_sect_block;
	nfree = PED_BE32_TO_CPU (vh->free_blocks)
		- (old_blocks - nblock);
	/* free block readjustement is only needed when incorrect nblock
	   was used by my previous implementation, so detect the case */
	if (priv_data->plus_geom->length < old_blocks
					   * ( PED_BE32_TO_CPU (vh->block_size)
					       / PED_SECTOR_SIZE_DEFAULT) ) {
		if (priv_data->plus_geom->length % hfsp_sect_block == 1)
			nfree++;
	}

	/* Check that all block after future end are really free */
	mblock = ( priv_data->plus_geom->length - 2 )
		 / hfsp_sect_block;
	if (mblock > old_blocks - 1)
		mblock = old_blocks - 1;
	for ( block = nblock;
	      block < mblock;
	      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 at the end "
				  "of the volume."));
			goto write_VH;
		}
	}

	/* Mark out of volume blocks as used */
	map_sectors = ( ( old_blocks + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
	                / (PED_SECTOR_SIZE_DEFAULT * 8) )
		      * (PED_SECTOR_SIZE_DEFAULT * 8);
	for ( block = nblock; block < map_sectors; ++block)
		SET_BLOC_OCCUPATION(priv_data->alloc_map, block);

	/* Update geometry */
	if (resize) {
		/* update in fs structure */
		if (PED_BE32_TO_CPU (vh->next_allocation) >= nblock)
			vh->next_allocation = PED_CPU_TO_BE32 (0);
		vh->total_blocks = PED_CPU_TO_BE32 (nblock);
		vh->free_blocks = PED_CPU_TO_BE32 (nfree);
		/* update parted structure */
		priv_data->plus_geom->length = geom->length;
		priv_data->plus_geom->end = priv_data->plus_geom->start
					    + geom->length - 1;
	}

	/* Effective write */
    write_VH:
    	/* lasts two sectors are allocated by the alternate VH
	   and a reserved sector, and last block is always reserved */
	block = (priv_data->plus_geom->length - 1) / hfsp_sect_block;
	if (block < PED_BE32_TO_CPU (vh->total_blocks))
		SET_BLOC_OCCUPATION(priv_data->alloc_map, block);
	block = (priv_data->plus_geom->length - 2) / hfsp_sect_block;
	if (block < PED_BE32_TO_CPU (vh->total_blocks))
		SET_BLOC_OCCUPATION(priv_data->alloc_map, block);
	SET_BLOC_OCCUPATION(priv_data->alloc_map,
			    PED_BE32_TO_CPU (vh->total_blocks) - 1);

	/* Write the _old_ area to set out of volume blocks as used */
	map_sectors = ( old_blocks + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
	              / (PED_SECTOR_SIZE_DEFAULT * 8);
	if (!hfsplus_file_write (priv_data->allocation_file,
				 priv_data->alloc_map, 0, map_sectors)) {
		resize = 0;
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Error while writing the allocation file."));
	} else {
	/* Write remaining part of allocation bitmap */
	/* This is necessary to handle pre patch-11 and third party */
	/* implementations */
		memset(buf, 0xFF, PED_SECTOR_SIZE_DEFAULT);
		for (block = map_sectors;
		     block < priv_data->allocation_file->sect_nb;
		     ++block) {
			if (!hfsplus_file_write_sector (
					priv_data->allocation_file,
					buf, block)) {
				ped_exception_throw (
					PED_EXCEPTION_WARNING,
					PED_EXCEPTION_IGNORE,
					_("Error while writing the "
					  "compatibility part of the "
					  "allocation file."));
				break;
			}
		}
	}
	ped_geometry_sync (priv_data->plus_geom);

	if (resize) {
		/* Set the unmounted bit and clear the inconsistent bit */
		vh->attributes |= PED_CPU_TO_BE32 ( 1 << HFS_UNMOUNTED );
		vh->attributes &= ~ PED_CPU_TO_BE32 ( 1 << HFSP_INCONSISTENT );
	}

	ped_timer_set_state_name(timer, _("writing HFS+ Volume Header"));
	if (!hfsplus_update_vh(fs)) {
		ped_geometry_sync(priv_data->plus_geom);
		return 0;
	}

	if (!ped_geometry_sync(priv_data->plus_geom))
		return 0;

	ped_timer_update(timer, 1.0);

	return (resize);
}
Пример #5
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);
}
Пример #6
0
static PedFileSystem *reiserfs_copy(const PedFileSystem *fs,
				    PedGeometry *geom, PedTimer *timer)
{
	dal_t *dal;
	PedGeometry *fs_geom;
	PedFileSystem *new_fs;
	blk_t fs_len, min_needed_blk;

	reiserfs_fs_t *dest_fs, *src_fs;
	reiserfs_gauge_t *gauge = NULL;

	fs_geom = ped_geometry_duplicate(geom);

	if (!(dal = geom_dal_create(fs_geom, DEFAULT_BLOCK_SIZE, O_RDWR))) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Couldn't create reiserfs device "
				      "abstraction handler."));
		goto error_free_fs_geom;
	}

	src_fs = fs->type_specific;

	fs_len =
	    (geom->length / (reiserfs_fs_block_size(src_fs) / PED_SECTOR_SIZE_DEFAULT));
	min_needed_blk = reiserfs_fs_bitmap_used(src_fs);

	if (fs_len <= min_needed_blk) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Device is too small for %lu blocks."),
				    min_needed_blk);
		goto error_free_dal;
	}

	if (! (new_fs = (PedFileSystem *) ped_malloc(sizeof(PedFileSystem))))
		goto error_free_dal;

	ped_timer_reset(timer);
	ped_timer_set_state_name(timer, _("copying"));
	ped_timer_update(timer, 0.0);

	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (! (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			goto error_free_new_fs;
	}

	if (!(dest_fs = reiserfs_fs_copy(src_fs, dal, gauge)))
		goto error_free_gauge;

	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);

	new_fs->type = reiserfs_type;
	new_fs->geom = fs_geom;
	new_fs->type_specific = (void *) dest_fs;

	return new_fs;

error_free_gauge:
	if (gauge)
		libreiserfs_gauge_free(gauge);
error_free_new_fs:
	free(new_fs);
error_free_dal:
	geom_dal_free(dal);
error_free_fs_geom:
	ped_geometry_destroy(fs_geom);
	return NULL;
}
Пример #7
0
static int reiserfs_resize(PedFileSystem *fs, PedGeometry *geom,
			   PedTimer *timer)
{
	dal_t *dal;
	blk_t fs_len;
	PedSector old_length;
	reiserfs_fs_t *fs_info;
	reiserfs_gauge_t *gauge = NULL;

	PED_ASSERT(fs != NULL);

	old_length = fs->geom->length;

	PED_ASSERT (fs->geom->dev == geom->dev);

	if (fs->geom->start != geom->start) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Sorry, can't move the start of "
				      "reiserfs partitions yet."));
		return 0;
	}

	fs_info = fs->type_specific;

	fs_len = (blk_t) (geom->length / (reiserfs_fs_block_size(fs_info) /
					  PED_SECTOR_SIZE_DEFAULT));

	dal = reiserfs_fs_host_dal(fs_info);

	if (dal_flags(dal) && O_RDONLY) {
		if (!geom_dal_reopen(dal, O_RDWR)) {
			ped_exception_throw(PED_EXCEPTION_ERROR,
					    PED_EXCEPTION_CANCEL,
					    _("Couldn't reopen device "
					      "abstraction layer for "
					      "read/write."));
			return 0;
		}
	}

	ped_timer_reset(timer);

	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (!
		    (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			return 0;
	}

	if (old_length > geom->length) {

		ped_timer_set_state_name(timer, _("shrinking"));
		ped_timer_update(timer, 0.0);

		if (!reiserfs_fs_resize(fs_info, fs_len, gauge))
			goto error_free_gauge;

		ped_geometry_set_end (fs->geom, geom->end);
		dal_realize(dal);
	} else {
		ped_geometry_set_end (fs->geom, geom->end);
		dal_realize(dal);

		ped_timer_set_state_name(timer, _("expanding"));
		ped_timer_update(timer, 0.0);

		if (!reiserfs_fs_resize(fs_info, fs_len, gauge))
			goto error_free_gauge;
	}

	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);

	return 1;

error_free_gauge:
	if (gauge)
		libreiserfs_gauge_free(gauge);
	ped_geometry_set_end (fs->geom, fs->geom->start + old_length - 1);
	return 0;
}
Пример #8
0
static int reiserfs_check(PedFileSystem *fs, PedTimer *timer)
{
	reiserfs_fs_t *fs_info;
#ifdef HAVE_REISERFS_FS_CHECK
	reiserfs_gauge_t *gauge = NULL;
#endif

	PED_ASSERT(fs != NULL);

	fs_info = fs->type_specific;

	if (!reiserfs_fs_is_consistent(fs_info)) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("The file system is in an invalid "
				      "state.  Perhaps it is mounted?"));
		return 0;
	}

	if (!reiserfs_fs_is_resizeable(fs_info))
		ped_exception_throw(PED_EXCEPTION_WARNING,
				    PED_EXCEPTION_IGNORE,
				    _("The file system is in old "
				      "(unresizeable) format."));

	if (!reiserfs_fs_bitmap_check(fs_info)) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Invalid free blocks count.  Run "
				      "reiserfsck --check first."));
		return 0;
	}

#ifdef HAVE_REISERFS_FS_CHECK
	ped_timer_reset(timer);

	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (!
		    (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			return 0;
	}

	ped_timer_set_state_name(timer, _("checking"));
	ped_timer_update(timer, 0.0);

	if (!reiserfs_fs_check(fs_info, gauge)) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Reiserfs tree seems to be corrupted.  "
				      "Run reiserfsck --check first."));
		return 0;
	}

	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);
#endif

	ped_exception_throw(PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK,
			    _("The reiserfs file system passed a basic check.  "
			      "For a more comprehensive check, run "
			      "reiserfsck --check."));

	return 1;
}
Пример #9
0
static PedFileSystem *reiserfs_create(PedGeometry *geom, PedTimer *timer)
{
	dal_t *dal;
	uuid_t uuid;
	PedFileSystem *fs;
	PedGeometry *fs_geom;
	reiserfs_fs_t *fs_info;
	reiserfs_gauge_t *gauge = NULL;

	PED_ASSERT(geom != NULL);

	fs_geom = ped_geometry_duplicate(geom);

	if (!(dal = geom_dal_create(fs_geom, DEFAULT_BLOCK_SIZE, O_RDWR)))
		goto error_fs_geom_free;

	memset(uuid, 0, sizeof(uuid));
	uuid_generate(uuid);

	ped_timer_reset(timer);
	ped_timer_set_state_name(timer, _("creating"));

	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (! (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			goto error_free_dal;
	}

	if (!(fs_info = reiserfs_fs_create(dal, dal, 0, JOURNAL_MAX_TRANS,
					   DEFAULT_JOURNAL_SIZE,
					   DEFAULT_BLOCK_SIZE,
					   FS_FORMAT_3_6, R5_HASH, NULL,
					   (char *) uuid, dal_len(dal),
					   gauge)))
		goto error_free_gauge;

	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);

	if (!(fs = (PedFileSystem *) ped_malloc(sizeof(PedFileSystem))))
		goto error_free_fs_info;

	fs->type = reiserfs_type;
	fs->geom = fs_geom;
	fs->type_specific = (void *) fs_info;

	return fs;

error_free_fs_info:
	free(fs_info);
error_free_gauge:
	if (gauge)
		libreiserfs_gauge_free(gauge);
error_free_dal:
	geom_dal_free(dal);
error_fs_geom_free:
	ped_geometry_destroy(fs_geom);
	return NULL;
}