/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2000, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

/* 
   Author : Guillaume Knispel <k_guillaume@libertysurf.fr> 
   Report bug to <bug-parted@gnu.org>
*/

#include <config.h>

#include <parted/parted.h>
#include <parted/endian.h>
#include <parted/debug.h>
#include <stdint.h>

#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) dgettext (PACKAGE, String)
#else
#  define _(String) (String)
#endif /* ENABLE_NLS */

#include "hfs.h"
#include "probe.h"

uint8_t* hfs_block = NULL;
uint8_t* hfsp_block = NULL;
unsigned hfs_block_count;
unsigned hfsp_block_count;

#define HFS_BLOCK_SIZES       ((int[2]){512, 0})
#define HFSP_BLOCK_SIZES       ((int[2]){512, 0})
#define HFSX_BLOCK_SIZES       ((int[2]){512, 0})

#ifndef DISCOVER_ONLY
#include "file.h"
#include "reloc.h"
#include "advfs.h"

static PedFileSystemType hfs_type;
static PedFileSystemType hfsplus_type;


/* ----- HFS ----- */

/* This is a very unundoable operation */
/* Maybe I shouldn't touch the alternate MDB ? */
/* Anyway clobber is call before other fs creation */
/* So this is a non-issue */
static int
hfs_clobber (PedGeometry* geom)
{
	uint8_t	buf[PED_SECTOR_SIZE_DEFAULT];

	memset (buf, 0, PED_SECTOR_SIZE_DEFAULT);
	
	/* destroy boot blocks, mdb, alternate mdb ... */
	return	(!!ped_geometry_write (geom, buf, 0, 1)) &
		(!!ped_geometry_write (geom, buf, 1, 1)) &
		(!!ped_geometry_write (geom, buf, 2, 1)) &
		(!!ped_geometry_write (geom, buf, geom->length - 2, 1)) &
		(!!ped_geometry_write (geom, buf, geom->length - 1, 1)) &
		(!!ped_geometry_sync  (geom));
}

static PedFileSystem*
hfs_open (PedGeometry* geom)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedFileSystem*		fs;
	HfsMasterDirectoryBlock* mdb;
	HfsPrivateFSData* 	priv_data;

	if (!hfsc_can_use_geom (geom))
		return NULL;

	/* Read MDB */
	if (!ped_geometry_read (geom, buf, 2, 1))
		return NULL;
	
	/* Allocate memory */
	fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
	if (!fs) goto ho;
	mdb = (HfsMasterDirectoryBlock*)
		ped_malloc (sizeof (HfsMasterDirectoryBlock));
	if (!mdb) goto ho_fs;
	priv_data = (HfsPrivateFSData*)
		ped_malloc (sizeof (HfsPrivateFSData));
	if (!priv_data) goto ho_mdb;

	memcpy (mdb, buf, sizeof (HfsMasterDirectoryBlock));

	/* init structures */
	priv_data->mdb = mdb;
	priv_data->bad_blocks_loaded = 0;
	priv_data->bad_blocks_xtent_nb = 0;
	priv_data->bad_blocks_xtent_list = NULL;
	priv_data->extent_file =
	    hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
			   mdb->extents_file_rec,
			   PED_CPU_TO_BE32 (mdb->extents_file_size)
			   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->extent_file) goto ho_pd;
	priv_data->catalog_file =
	    hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
			   mdb->catalog_file_rec,
			   PED_CPU_TO_BE32 (mdb->catalog_file_size)
			   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->catalog_file) goto ho_ce;
	/* Read allocation blocks */
	if (!ped_geometry_read(geom, priv_data->alloc_map,
			       PED_BE16_TO_CPU (mdb->volume_bitmap_block),
			       ( PED_BE16_TO_CPU (mdb->total_blocks)
			         + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
			       / (PED_SECTOR_SIZE_DEFAULT * 8) ) )
		goto ho_cf;

	fs->type = &hfs_type;
	fs->geom = ped_geometry_duplicate (geom);
	if (!fs->geom) goto ho_cf;
	fs->type_specific = (void*) priv_data;
	fs->checked = ( PED_BE16_TO_CPU (mdb->volume_attributes)
			>> HFS_UNMOUNTED ) & 1;

	return fs;

/*--- clean error handling ---*/
ho_cf:	hfs_file_close(priv_data->catalog_file);
ho_ce:	hfs_file_close(priv_data->extent_file);
ho_pd:	ped_free(priv_data);
ho_mdb: ped_free(mdb);
ho_fs:	ped_free(fs);
ho:	return NULL;
}

static int
hfs_close (PedFileSystem *fs)
{
	HfsPrivateFSData* priv_data = (HfsPrivateFSData*) fs->type_specific;

	hfs_file_close (priv_data->extent_file);
	hfs_file_close (priv_data->catalog_file);
	if (priv_data->bad_blocks_loaded)
		hfs_free_bad_blocks_list (priv_data->bad_blocks_xtent_list);
	ped_free (priv_data->mdb);
	ped_free (priv_data);
	ped_geometry_destroy (fs->geom);
	ped_free (fs);

	return 1;
}

static PedConstraint* 
hfs_get_resize_constraint (const PedFileSystem *fs)
{
	PedDevice*	dev = fs->geom->dev;
	PedAlignment	start_align;
	PedGeometry	start_sector;
	PedGeometry	full_dev;
	PedSector	min_size;

	if (!ped_alignment_init (&start_align, fs->geom->start, 0))
		return NULL;
	if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
		return NULL;
	if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
		return NULL;
	/* 2 = last two sectors (alternate MDB and unused sector) */
	min_size = hfs_get_empty_end(fs) + 2;
	if (min_size == 2) return NULL;

	return ped_constraint_new (&start_align, ped_alignment_any,
				   &start_sector, &full_dev, min_size,
				   fs->geom->length);
}

static 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, return 0);
	PED_ASSERT (fs->geom != NULL, return 0);
	PED_ASSERT (geom != NULL, return 0);
#ifdef DEBUG
        PED_ASSERT ((hgee = hfs_get_empty_end(fs)) != 0, return 0);
#else
        if ((hgee = hfs_get_empty_end(fs)) == 0)
                return 0;
#endif

	PED_ASSERT ((hgee = hfs_get_empty_end(fs)) != 0, return 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);
}

/* ----- HFS+ ----- */

#include "file_plus.h"
#include "advfs_plus.h"
#include "reloc_plus.h"
#include "journal.h"

static int
hfsplus_clobber (PedGeometry* geom)
{
	unsigned int i = 1;
	uint8_t				buf[PED_SECTOR_SIZE_DEFAULT];
	HfsMasterDirectoryBlock		*mdb;

	mdb = (HfsMasterDirectoryBlock *) buf;

	if (!ped_geometry_read (geom, buf, 2, 1))
		return 0;

	if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE) {
		/* embedded hfs+ */
		PedGeometry	*embedded;

		i = PED_BE32_TO_CPU(mdb->block_size) / PED_SECTOR_SIZE_DEFAULT;
		embedded = ped_geometry_new (
		    geom->dev,
		    (PedSector) geom->start
		     + PED_BE16_TO_CPU (mdb->start_block)
		     + (PedSector) PED_BE16_TO_CPU (
			mdb->old_new.embedded.location.start_block ) * i, 
		    (PedSector) PED_BE16_TO_CPU (
			mdb->old_new.embedded.location.block_count ) * i );
		if (!embedded) i = 0;
		else {
			i = hfs_clobber (embedded);
			ped_geometry_destroy (embedded);
		}
	}

	/* non-embedded or envelop destroy as hfs */
	return ( hfs_clobber (geom) && i );
}

static int
hfsplus_close (PedFileSystem *fs)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;

	if (priv_data->bad_blocks_loaded)
		hfsplus_free_bad_blocks_list(priv_data->bad_blocks_xtent_list);
	ped_free(priv_data->alloc_map);
	ped_free(priv_data->dirty_alloc_map);
	hfsplus_file_close (priv_data->allocation_file);
	hfsplus_file_close (priv_data->attributes_file);
	hfsplus_file_close (priv_data->catalog_file);
	hfsplus_file_close (priv_data->extents_file);
	if (priv_data->free_geom) ped_geometry_destroy (priv_data->plus_geom);
	if (priv_data->wrapper) hfs_close(priv_data->wrapper);
	ped_geometry_destroy (fs->geom);
	ped_free(priv_data->vh);
	ped_free(priv_data);
	ped_free(fs);

	return 1;
}

static PedFileSystem*
hfsplus_open (PedGeometry* geom)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedFileSystem*		fs;
	HfsPVolumeHeader*	vh;
	HfsPPrivateFSData* 	priv_data;
	PedGeometry*		wrapper_geom;
	unsigned int		map_sectors;

	if (!hfsc_can_use_geom (geom))
		return NULL;

	fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
	if (!fs) goto hpo;
	vh = (HfsPVolumeHeader*) ped_malloc (sizeof (HfsPVolumeHeader));
	if (!vh) goto hpo_fs;
	priv_data = (HfsPPrivateFSData*)ped_malloc (sizeof (HfsPPrivateFSData));
	if (!priv_data) goto hpo_vh;

	fs->geom = ped_geometry_duplicate (geom);
	if (!fs->geom) goto hpo_pd;
	fs->type_specific = (void*) priv_data;

	if ((wrapper_geom = hfs_and_wrapper_probe (geom))) {
		HfsPrivateFSData* 	hfs_priv_data;
		PedSector		abs_sect, length;
		unsigned int		bs;

		ped_geometry_destroy (wrapper_geom);
		priv_data->wrapper = hfs_open(geom);
		if (!priv_data->wrapper) goto hpo_gm;
		hfs_priv_data = (HfsPrivateFSData*)
			priv_data->wrapper->type_specific;
		bs = PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
		     / PED_SECTOR_SIZE_DEFAULT;
		abs_sect = (PedSector) geom->start
			   + (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->start_block)
			   + (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->old_new
					    .embedded.location.start_block )
			                 * bs;
		length = (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->old_new
					    .embedded.location.block_count)
				     * bs;
		priv_data->plus_geom = ped_geometry_new (geom->dev, abs_sect,
							 length);
		if (!priv_data->plus_geom) goto hpo_wr;
		priv_data->free_geom = 1;
	} else {
		priv_data->wrapper = NULL;
		priv_data->plus_geom = fs->geom;
		priv_data->free_geom = 0;
	}

	if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1)) goto hpo_pg;
	memcpy (vh, buf, sizeof (HfsPVolumeHeader));
	priv_data->vh = vh;

	if (vh->signature != PED_CPU_TO_BE16(HFSP_SIGNATURE)
	    && vh->signature != PED_CPU_TO_BE16(HFSX_SIGNATURE)) {
		ped_exception_throw (
			PED_EXCEPTION_BUG,
			PED_EXCEPTION_CANCEL,
			_("No valid HFS[+X] signature has been found while "
			  "opening."));
		goto hpo_pg;
	}

	if (vh->signature == PED_CPU_TO_BE16(HFSP_SIGNATURE)
	    && vh->version != PED_CPU_TO_BE16(HFSP_VERSION)) {
		if (ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Version %d of HFS+ isn't supported."),
			PED_BE16_TO_CPU(vh->version))
				!= PED_EXCEPTION_IGNORE)
			goto hpo_pg;
	}

	if (vh->signature == PED_CPU_TO_BE16(HFSX_SIGNATURE)
	    && vh->version != PED_CPU_TO_BE16(HFSX_VERSION)) {
		if (ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Version %d of HFSX isn't supported."),
			PED_BE16_TO_CPU(vh->version))
				!= PED_EXCEPTION_IGNORE)
			goto hpo_pg;
	}

	priv_data->jib_start_block = 0;
	priv_data->jl_start_block = 0;
	if (vh->attributes & PED_CPU_TO_BE32(1<<HFSP_JOURNALED)) {
		if (!hfsj_replay_journal(fs))
			goto hpo_pg;
	}

	priv_data->bad_blocks_loaded = 0;
	priv_data->bad_blocks_xtent_nb = 0;
	priv_data->bad_blocks_xtent_list = NULL;
	priv_data->extents_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
				   vh->extents_file.extents,
				   PED_BE64_TO_CPU (
					vh->extents_file.logical_size )
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->extents_file) goto hpo_pg;
	priv_data->catalog_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
				   vh->catalog_file.extents,
				   PED_BE64_TO_CPU (
					vh->catalog_file.logical_size )
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->catalog_file) goto hpo_ce;
	priv_data->attributes_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ATTRIB_ID),
				   vh->attributes_file.extents,
				   PED_BE64_TO_CPU (
					vh->attributes_file.logical_size)
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->attributes_file) goto hpo_cc;

	map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks) 
	                + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
		      / (PED_SECTOR_SIZE_DEFAULT * 8);
	priv_data->dirty_alloc_map = (uint8_t*)
		ped_malloc ((map_sectors + 7) / 8);
	if (!priv_data->dirty_alloc_map) goto hpo_cl;
	memset(priv_data->dirty_alloc_map, 0, (map_sectors + 7) / 8);
	priv_data->alloc_map = (uint8_t*)
		ped_malloc (map_sectors * PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->alloc_map) goto hpo_dm;

	priv_data->allocation_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
				   vh->allocation_file.extents,
				   PED_BE64_TO_CPU (
					vh->allocation_file.logical_size)
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->allocation_file) goto hpo_am;
	if (!hfsplus_file_read (priv_data->allocation_file,
				priv_data->alloc_map, 0, map_sectors)) {
		hfsplus_close(fs);
		return NULL;
	}

	fs->type = &hfsplus_type;
	fs->checked = ((PED_BE32_TO_CPU (vh->attributes) >> HFS_UNMOUNTED) & 1)
	      && !((PED_BE32_TO_CPU (vh->attributes) >> HFSP_INCONSISTENT) & 1);

	return fs;

/*--- clean error handling ---*/
hpo_am: ped_free(priv_data->alloc_map);
hpo_dm: ped_free(priv_data->dirty_alloc_map);
hpo_cl: hfsplus_file_close (priv_data->attributes_file);
hpo_cc:	hfsplus_file_close (priv_data->catalog_file);
hpo_ce:	hfsplus_file_close (priv_data->extents_file);
hpo_pg: if (priv_data->free_geom) ped_geometry_destroy (priv_data->plus_geom);
hpo_wr: if (priv_data->wrapper) hfs_close(priv_data->wrapper);
hpo_gm: ped_geometry_destroy (fs->geom);
hpo_pd: ped_free(priv_data);
hpo_vh: ped_free(vh);
hpo_fs: ped_free(fs);
hpo:	return NULL;
}

static PedConstraint* 
hfsplus_get_resize_constraint (const PedFileSystem *fs)
{
	PedDevice*	dev = fs->geom->dev;
	PedAlignment	start_align;
	PedGeometry	start_sector;
	PedGeometry	full_dev;
	PedSector	min_size;

	if (!ped_alignment_init (&start_align, fs->geom->start, 0))
		return NULL;
	if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
		return NULL;
	if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
		return NULL;

	min_size = hfsplus_get_min_size (fs);
	if (!min_size) return NULL;

	return ped_constraint_new (&start_align, ped_alignment_any,
				   &start_sector, &full_dev, min_size,
				   fs->geom->length);
}

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);
}

/* Update the HFS wrapper mdb and bad blocks file to reflect
   the new geometry of the embedded HFS+ volume */
static int
hfsplus_wrapper_update (PedFileSystem* fs)
{
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];
	HfsCPrivateLeafRec	ref;
	HfsExtentKey		key;
	HfsNodeDescriptor*	node_desc = (HfsNodeDescriptor*) node;
	HfsExtentKey*		ret_key;
	HfsExtDescriptor*	ret_data;
	unsigned int		i;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	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 ;
	PedSector		hfsplus_sect = (PedSector)
			PED_BE32_TO_CPU (priv_data->vh->total_blocks)
			* ( PED_BE32_TO_CPU (priv_data->vh->block_size)
			    / PED_SECTOR_SIZE_DEFAULT );
	unsigned int		hfs_blocks_embedded =
				    (hfsplus_sect + hfs_sect_block - 1)
				    / hfs_sect_block;
	unsigned int		hfs_blocks_embedded_old;

	/* update HFS wrapper MDB */
	hfs_blocks_embedded_old = PED_BE16_TO_CPU (
					hfs_priv_data->mdb->old_new
					.embedded.location.block_count );
	hfs_priv_data->mdb->old_new.embedded.location.block_count =
		PED_CPU_TO_BE16 (hfs_blocks_embedded);
	/* maybe macOS will boot with this */
	/* update : yes it does \o/ :) */
	hfs_priv_data->mdb->free_blocks =
	    PED_CPU_TO_BE16 ( PED_BE16_TO_CPU (hfs_priv_data->mdb->free_blocks)
	                    + hfs_blocks_embedded_old
			    - hfs_blocks_embedded );

	if (!hfs_update_mdb(priv_data->wrapper))
		return 0;

	/* force reload bad block list */
	if (hfs_priv_data->bad_blocks_loaded) {
		hfs_free_bad_blocks_list (hfs_priv_data->bad_blocks_xtent_list);
		hfs_priv_data->bad_blocks_xtent_list = NULL;
		hfs_priv_data->bad_blocks_xtent_nb = 0;
		hfs_priv_data->bad_blocks_loaded = 0;
	}

	/* clean HFS wrapper allocation map */
	for (i = PED_BE16_TO_CPU (
			hfs_priv_data->mdb->old_new.embedded
			.location.start_block )
		 + hfs_blocks_embedded;
	     i < PED_BE16_TO_CPU (
	    		hfs_priv_data->mdb->old_new.embedded
			.location.start_block )
		 + hfs_blocks_embedded_old;
	     i++ ) {
		CLR_BLOC_OCCUPATION(hfs_priv_data->alloc_map, i);
	}
	/* and save it */
	if (!ped_geometry_write (fs->geom, hfs_priv_data->alloc_map,
				 PED_BE16_TO_CPU (
				      hfs_priv_data->mdb->volume_bitmap_block ),
				 ( PED_BE16_TO_CPU (
				        hfs_priv_data->mdb->total_blocks ) 
				   + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
				 / (PED_SECTOR_SIZE_DEFAULT * 8)))
		return 0;
	if (!ped_geometry_sync (fs->geom))
		return 0;

	/* search and update the bad blocks file */
	key.key_length = sizeof(key) - 1;
	key.type = HFS_DATA_FORK;
	key.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
	key.start = 0;
	if (!hfs_btree_search (hfs_priv_data->extent_file,
			       (HfsPrivateGenericKey*) &key, NULL, 0, &ref)) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("An error occurred while looking for the mandatory "
			  "bad blocks file."));
		return 0;
	}
	if (!hfs_file_read_sector (hfs_priv_data->extent_file, node,
				   ref.node_number))
		return 0;
	ret_key = (HfsExtentKey*) (node + ref.record_pos);
	ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
					 + sizeof (HfsExtentKey) );

	while (ret_key->type == key.type && ret_key->file_ID == key.file_ID) {
		for (i = 0; i < HFS_EXT_NB; i++) {
			if ( ret_data[i].start_block 
			     == hfs_priv_data->mdb->old_new
			        .embedded.location.start_block) {
				ret_data[i].block_count =
				    hfs_priv_data->mdb->old_new
				    .embedded.location.block_count;
				/* found ! : update */
				if (!hfs_file_write_sector (
					  hfs_priv_data->extent_file,
					  node, ref.node_number)
				    || !ped_geometry_sync(fs->geom))
					return 0;
				return 1;
			}
		}

		if (ref.record_number < PED_BE16_TO_CPU (node_desc->rec_nb)) {
			ref.record_number++;
		} else {
			ref.node_number = PED_BE32_TO_CPU (node_desc->next);
			if (!ref.node_number
			    || !hfs_file_read_sector(hfs_priv_data->extent_file,
						     node, ref.node_number))
				goto bb_not_found;
			ref.record_number = 1;
		}

		ref.record_pos =
			PED_BE16_TO_CPU (*((uint16_t *)
				(node + (PED_SECTOR_SIZE_DEFAULT
				         - 2*ref.record_number))));
		ret_key = (HfsExtentKey*) (node + ref.record_pos);
		ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
						 + sizeof (HfsExtentKey) );
	}

bb_not_found:
	/* not found : not a valid hfs+ wrapper : failure */
	ped_exception_throw (
		PED_EXCEPTION_ERROR,
		PED_EXCEPTION_CANCEL,
		_("It seems there is an error in the HFS wrapper: the bad "
		  "blocks file doesn't contain the embedded HFS+ volume."));
	return 0;
}

static 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, return 0);
	PED_ASSERT (fs->geom != NULL, return 0); 
	PED_ASSERT (geom != NULL, return 0);
	PED_ASSERT (fs->geom->dev == geom->dev, return 0);
#ifdef DEBUG
        PED_ASSERT ((hgms = hfsplus_get_min_size (fs)) != 0, return 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;
}

#ifdef HFS_EXTRACT_FS
/* The following is for debugging purpose only, NOT for packaging */

#include <stdio.h>

uint8_t* extract_buffer = NULL;

static int
hfs_extract_file(const char* filename, HfsPrivateFile* hfs_file)
{
	FILE*		fout;
	PedSector	sect;

	fout = fopen(filename, "w");
	if (!fout) return 0;

	for (sect = 0; sect < hfs_file->sect_nb; ++sect) {
		if (!hfs_file_read_sector(hfs_file, extract_buffer, sect))
			goto err_close;
		if (!fwrite(extract_buffer, PED_SECTOR_SIZE_DEFAULT, 1, fout))
			goto err_close;
	}

	return (fclose(fout) == 0 ? 1 : 0);

err_close:
	fclose(fout);
	return 0;
}

static int
hfs_extract_bitmap(const char* filename, PedFileSystem* fs)
{
	HfsPrivateFSData*		priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsMasterDirectoryBlock*	mdb = priv_data->mdb;
	unsigned int 	count;
	FILE*		fout;
	PedSector	sect;

	fout = fopen(filename, "w");
	if (!fout) return 0;

	for (sect = PED_BE16_TO_CPU(mdb->volume_bitmap_block);
	     sect < PED_BE16_TO_CPU(mdb->start_block);
	     sect += count) {
		uint16_t st_block = PED_BE16_TO_CPU(mdb->start_block);
		count = (st_block-sect) < BLOCK_MAX_BUFF ?
			(st_block-sect) : BLOCK_MAX_BUFF;
		if (!ped_geometry_read(fs->geom, extract_buffer, sect, count))
			goto err_close;
		if (!fwrite (extract_buffer, count * PED_SECTOR_SIZE_DEFAULT,
			     1, fout))
			goto err_close;
	}

	return (fclose(fout) == 0 ? 1 : 0);

err_close:
	fclose(fout);
	return 0;
}

static int
hfs_extract_mdb (const char* filename, PedFileSystem* fs)
{
	FILE*		fout;

	fout = fopen(filename, "w");
	if (!fout) return 0;

	if (!ped_geometry_read(fs->geom, extract_buffer, 2, 1))
		goto err_close;
	if (!fwrite(extract_buffer, PED_SECTOR_SIZE_DEFAULT, 1, fout))
		goto err_close;

	return (fclose(fout) == 0 ? 1 : 0);

err_close:
	fclose(fout);
	return 0;
}

static int
hfs_extract (PedFileSystem* fs, PedTimer* timer)
{
	HfsPrivateFSData*	priv_data = (HfsPrivateFSData*)
						fs->type_specific;

	ped_exception_throw (
		PED_EXCEPTION_INFORMATION,
		PED_EXCEPTION_OK,
		_("This is not a real %s check.  This is going to extract "
		  "special low level files for debugging purposes."),
		"HFS");

	extract_buffer = ped_malloc(BLOCK_MAX_BUFF * PED_SECTOR_SIZE_DEFAULT);
	if (!extract_buffer) return 0;

	hfs_extract_mdb(HFS_MDB_FILENAME, fs);
	hfs_extract_file(HFS_CATALOG_FILENAME, priv_data->catalog_file);
	hfs_extract_file(HFS_EXTENTS_FILENAME, priv_data->extent_file);
	hfs_extract_bitmap(HFS_BITMAP_FILENAME, fs);

	ped_free(extract_buffer); extract_buffer = NULL;
	return 0; /* nothing has been fixed by us ! */
}

static int
hfsplus_extract_file(const char* filename, HfsPPrivateFile* hfsp_file)
{
	FILE*		fout;
	unsigned int	cp_sect;
	PedSector	rem_sect;

	fout = fopen(filename, "w");
	if (!fout) return 0;

	for (rem_sect = hfsp_file->sect_nb; rem_sect; rem_sect -= cp_sect) {
		cp_sect = rem_sect < BLOCK_MAX_BUFF ? rem_sect : BLOCK_MAX_BUFF;
		if (!hfsplus_file_read(hfsp_file, extract_buffer, 
				       hfsp_file->sect_nb - rem_sect, cp_sect))
			goto err_close;
		if (!fwrite (extract_buffer, cp_sect * PED_SECTOR_SIZE_DEFAULT,
			     1, fout))
			goto err_close;
	}

	return (fclose(fout) == 0 ? 1 : 0);

err_close:
	fclose(fout);
	return 0;
}

static int
hfsplus_extract_vh (const char* filename, PedFileSystem* fs)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	FILE*		fout;
	PedGeometry*	geom = priv_data->plus_geom;


	fout = fopen(filename, "w");
	if (!fout) return 0;

	if (!ped_geometry_read(geom, extract_buffer, 2, 1))
		goto err_close;
	if (!fwrite(extract_buffer, PED_SECTOR_SIZE_DEFAULT, 1, fout))
		goto err_close;

	return (fclose(fout) == 0 ? 1 : 0);

err_close:
	fclose(fout);
	return 0;
}

/* TODO : use the timer to report what is happening */
/* TODO : use exceptions to report errors */
static int
hfsplus_extract (PedFileSystem* fs, PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsPVolumeHeader*	vh = priv_data->vh;
	HfsPPrivateFile*	startup_file;

	if (priv_data->wrapper) {
		/* TODO : create nested timer */
		hfs_extract (priv_data->wrapper, timer);
	}

	ped_exception_throw (
		PED_EXCEPTION_INFORMATION,
		PED_EXCEPTION_OK,
		_("This is not a real %s check.  This is going to extract "
		  "special low level files for debugging purposes."),
		"HFS+");

	extract_buffer = ped_malloc(BLOCK_MAX_BUFF * PED_SECTOR_SIZE_DEFAULT);
	if (!extract_buffer) return 0;

	hfsplus_extract_vh(HFSP_VH_FILENAME, fs);
	hfsplus_extract_file(HFSP_CATALOG_FILENAME, priv_data->catalog_file);
	hfsplus_extract_file(HFSP_EXTENTS_FILENAME, priv_data->extents_file);
	hfsplus_extract_file(HFSP_ATTRIB_FILENAME, priv_data->attributes_file);
	hfsplus_extract_file(HFSP_BITMAP_FILENAME, priv_data->allocation_file);

	startup_file = hfsplus_file_open(fs, PED_CPU_TO_BE32(HFSP_STARTUP_ID),
					vh->startup_file.extents,
					PED_BE64_TO_CPU (
					   vh->startup_file.logical_size)
					/ PED_SECTOR_SIZE_DEFAULT);
	if (startup_file) {
		hfsplus_extract_file(HFSP_STARTUP_FILENAME, startup_file);
		hfsplus_file_close(startup_file); startup_file = NULL;
	}

	ped_free(extract_buffer); extract_buffer = NULL;
	return 0; /* nothing has been fixed by us ! */
}
#endif /* HFS_EXTRACT_FS */

#endif /* !DISCOVER_ONLY */

static PedFileSystemOps hfs_ops = {
	probe:		hfs_probe,
#ifndef DISCOVER_ONLY
	clobber:	hfs_clobber,
	open:		hfs_open,
	create:		NULL,
	close:		hfs_close,
#ifndef HFS_EXTRACT_FS
	check:		NULL,
#else
	check:		hfs_extract,
#endif
	copy:		NULL,
	resize:		hfs_resize,
	get_create_constraint:	NULL,
	get_resize_constraint:	hfs_get_resize_constraint,
	get_copy_constraint:	NULL,
#else /* DISCOVER_ONLY */
	clobber:	NULL,
	open:		NULL,
	create:		NULL,
	close:		NULL,
	check:		NULL,
	copy:		NULL,
	resize:		NULL,
	get_create_constraint:	NULL,
	get_resize_constraint:	NULL,
	get_copy_constraint:	NULL,
#endif /* DISCOVER_ONLY */
};

static PedFileSystemOps hfsplus_ops = {
	probe:		hfsplus_probe,
#ifndef DISCOVER_ONLY
	clobber:	hfsplus_clobber,
	open:		hfsplus_open,
	create:		NULL,
	close:		hfsplus_close,
#ifndef HFS_EXTRACT_FS
	check:		NULL,
#else
	check:		hfsplus_extract,
#endif
	copy:		NULL,
	resize:		hfsplus_resize,
	get_create_constraint:	NULL,
	get_resize_constraint:	hfsplus_get_resize_constraint,
	get_copy_constraint:	NULL,
#else /* DISCOVER_ONLY */
	clobber:	NULL,
	open:		NULL,
	create:		NULL,
	close:		NULL,
	check:		NULL,
	copy:		NULL,
	resize:		NULL,
	get_create_constraint:	NULL,
	get_resize_constraint:	NULL,
	get_copy_constraint:	NULL,
#endif /* DISCOVER_ONLY */
};

static PedFileSystemOps hfsx_ops = {
	probe:		hfsx_probe,
#ifndef DISCOVER_ONLY
	clobber:	hfs_clobber, /* NOT hfsplus_clobber !
					HFSX can't be embedded */
	open:		hfsplus_open,
	create:		NULL,
	close:		hfsplus_close,
#ifndef HFS_EXTRACT_FS
	check:		NULL,
#else
	check:		hfsplus_extract,
#endif
	copy:		NULL,
	resize:		hfsplus_resize,
	get_create_constraint:	NULL,
	get_resize_constraint:	hfsplus_get_resize_constraint,
	get_copy_constraint:	NULL,
#else /* DISCOVER_ONLY */
	clobber:	NULL,
	open:		NULL,
	create:		NULL,
	close:		NULL,
	check:		NULL,
	copy:		NULL,
	resize:		NULL,
	get_create_constraint:	NULL,
	get_resize_constraint:	NULL,
	get_copy_constraint:	NULL,
#endif /* DISCOVER_ONLY */
};


static PedFileSystemType hfs_type = {
	next:	NULL,
	ops:	&hfs_ops,
	name:	"hfs",
	block_sizes: HFS_BLOCK_SIZES
};

static PedFileSystemType hfsplus_type = {
	next:	NULL,
	ops:	&hfsplus_ops,
	name:	"hfs+",
	block_sizes: HFSP_BLOCK_SIZES
};

static PedFileSystemType hfsx_type = {
	next:	NULL,
	ops:	&hfsx_ops,
	name:	"hfsx",
	block_sizes: HFSX_BLOCK_SIZES
};

void
ped_file_system_hfs_init ()
{
	ped_file_system_type_register (&hfs_type);
	ped_file_system_type_register (&hfsplus_type);
	ped_file_system_type_register (&hfsx_type);
}

void
ped_file_system_hfs_done ()
{
	ped_file_system_type_unregister (&hfs_type);
	ped_file_system_type_unregister (&hfsplus_type);
	ped_file_system_type_unregister (&hfsx_type);
}
