/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 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
*/

#ifndef DISCOVER_ONLY

#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 "file_plus.h"
#include "advfs_plus.h"
#include "cache.h"
#include "journal.h"

#include "reloc_plus.h"

/* This function moves data of size blocks starting at block *ptr_fblock
   to block *ptr_to_fblock */
/* return new start or -1 on failure */
/* -1 is ok because there can only be 2^32-1 blocks, so the max possible
   last one is 2^32-2 (and anyway it contains Alternate VH), so
   -1 (== 2^32-1[2^32]) never represent a valid block */
static int
hfsplus_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
			    unsigned int *ptr_to_fblock, unsigned int size)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	unsigned int		i, ok = 0;
	unsigned int		next_to_fblock;
	unsigned int		start, stop;

	PED_ASSERT (hfsp_block != NULL, return -1);
	PED_ASSERT (*ptr_to_fblock <= *ptr_fblock, return -1);
	/* quiet GCC */
	next_to_fblock = start = stop = 0;

/*
	Try to fit the extent AT or _BEFORE_ the wanted place,
	or then in the gap between dest and source.
	If failed try to fit the extent after source, for 2 pass relocation
	The extent is always copied in a non overlapping way
*/

	/* Backward search */
	/* 1 pass relocation AT or BEFORE *ptr_to_fblock */
	if (*ptr_to_fblock != *ptr_fblock) {
		start = stop = *ptr_fblock < *ptr_to_fblock+size ?
			       *ptr_fblock : *ptr_to_fblock+size;
		while (start && stop-start != size) {
			--start;
			if (TST_BLOC_OCCUPATION(priv_data->alloc_map,start))
				stop = start;
		}
		ok = (stop-start == size);
	}
	
	/* Forward search */
	/* 1 pass relocation in the gap merged with 2 pass reloc after source */
	if (!ok && *ptr_to_fblock != *ptr_fblock) {
		start = stop = *ptr_to_fblock+1;
		while (stop < PED_BE32_TO_CPU(priv_data->vh->total_blocks)
		       && stop-start != size) {
			if (TST_BLOC_OCCUPATION(priv_data->alloc_map,stop))
				start = stop + 1;
			++stop;
		}
		ok = (stop-start == size);
	}

	/* new non overlapping room has been found ? */
	if (ok) {
		/* enough room */
		PedSector	abs_sector;
		unsigned int	ai, j, block;
		unsigned int 	block_sz = (PED_BE32_TO_CPU (
					priv_data->vh->block_size)
					/ PED_SECTOR_SIZE_DEFAULT);

		if (stop > *ptr_to_fblock && stop <= *ptr_fblock)
			/* Fit in the gap */
			next_to_fblock = stop;
		else
			/* Before or after the gap */
			next_to_fblock = *ptr_to_fblock;

		/* move blocks */
		for (i = 0; i < size; /*i++*/) {
			j = size - i; j = (j < hfsp_block_count) ?
					   j : hfsp_block_count ;

			abs_sector = (PedSector) (*ptr_fblock + i) * block_sz;
			if (!ped_geometry_read (priv_data->plus_geom,
						hfsp_block, abs_sector,
						block_sz * j))
				return -1;

			abs_sector = (PedSector) (start + i) * block_sz;
			if (!ped_geometry_write (priv_data->plus_geom,
						 hfsp_block, abs_sector,
						 block_sz * j))
				return -1;

			for (ai = i+j; i < ai; i++) {
				/* free source block */
				block = *ptr_fblock + i;
				CLR_BLOC_OCCUPATION(priv_data->alloc_map,block);
				SET_BLOC_OCCUPATION(priv_data->dirty_alloc_map,
						    block/(PED_SECTOR_SIZE_DEFAULT*8));

				/* set dest block */
				block = start + i;
				SET_BLOC_OCCUPATION(priv_data->alloc_map,block);
				SET_BLOC_OCCUPATION(priv_data->dirty_alloc_map,
						    block/(PED_SECTOR_SIZE_DEFAULT*8));
			}
		}
		if (!ped_geometry_sync_fast (priv_data->plus_geom))
			return -1;

		*ptr_fblock += size;
		*ptr_to_fblock = next_to_fblock;
	} else {
		if (*ptr_fblock != *ptr_to_fblock)
			/* not enough room */
			ped_exception_throw (PED_EXCEPTION_WARNING,
			      PED_EXCEPTION_IGNORE,
			      _("An extent has not been relocated."));
		start = *ptr_fblock;
		*ptr_fblock = *ptr_to_fblock = start + size;
	}

	return start;
}

/* Returns 0 on error */
/*         1 on succes */
int
hfsplus_update_vh (PedFileSystem *fs)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];

    	if (!ped_geometry_read (priv_data->plus_geom, node, 2, 1))
		return 0;
	memcpy (node, priv_data->vh, sizeof (HfsPVolumeHeader));
	if (!ped_geometry_write (priv_data->plus_geom, node, 2, 1)
	    || !ped_geometry_write (priv_data->plus_geom, node,
				 priv_data->plus_geom->length - 2, 1)
	    || !ped_geometry_sync_fast (priv_data->plus_geom))
		return 0;
	return 1;
}

static int
hfsplus_do_move (PedFileSystem* fs, unsigned int *ptr_src,
		 unsigned int *ptr_dest, HfsCPrivateCache* cache,
		 HfsCPrivateExtent* ref)
{
	HfsPPrivateFSData*	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsPPrivateFile*	file;
	HfsPExtDescriptor*	extent;
	HfsCPrivateExtent*	move;
	int			new_start;

	new_start = hfsplus_effect_move_extent (fs, ptr_src, ptr_dest,
						ref->ext_length);

	if (new_start == -1) return -1;
	
	if (ref->ext_start != (unsigned) new_start) {
		switch (ref->where) {
		/************ VH ************/
		    case CR_PRIM_CAT :
			priv_data->catalog_file
			->first[ref->ref_index].start_block = 
				PED_CPU_TO_BE32(new_start);
			goto CR_PRIM;
		    case CR_PRIM_EXT :
			priv_data->extents_file
			->first[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			goto CR_PRIM;
		    case CR_PRIM_ATTR :
			priv_data->attributes_file
			->first[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			goto CR_PRIM;
		    case CR_PRIM_ALLOC :
			priv_data->allocation_file
			->first[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			goto CR_PRIM;
		    case CR_PRIM_START :
			/* No startup file opened */
		    CR_PRIM :
			extent = ( HfsPExtDescriptor* )
				 ( (uint8_t*)priv_data->vh + ref->ref_offset );
			extent[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			if (!hfsplus_update_vh(fs))
				return -1;
			break;

		/************** BTREE *************/
		    case CR_BTREE_CAT_JIB :
			if (!hfsj_update_jib(fs, new_start))
				return -1;
			goto BTREE_CAT;

		    case CR_BTREE_CAT_JL :
			if (!hfsj_update_jl(fs, new_start))
				return -1;
			goto BTREE_CAT;

		    BTREE_CAT:
		    case CR_BTREE_CAT :
			file = priv_data->catalog_file;
			goto CR_BTREE;

		    case CR_BTREE_ATTR :
			file = priv_data->attributes_file;
			goto CR_BTREE;

		    case CR_BTREE_EXT_ATTR :
			if (priv_data->attributes_file
			    ->cache[ref->ref_index].start_block
			    == PED_CPU_TO_BE32(ref->ext_start))
				priv_data->attributes_file
				->cache[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			goto CR_BTREE_EXT;
		    case CR_BTREE_EXT_CAT :
			if (priv_data->catalog_file
			    ->cache[ref->ref_index].start_block
			    == PED_CPU_TO_BE32(ref->ext_start))
				priv_data->catalog_file
				->cache[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			goto CR_BTREE_EXT;
		    case CR_BTREE_EXT_ALLOC :
			if (priv_data->allocation_file
			    ->cache[ref->ref_index].start_block
			    == PED_CPU_TO_BE32(ref->ext_start))
				priv_data->allocation_file
				->cache[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			goto CR_BTREE_EXT;
		    case CR_BTREE_EXT_START :
		    	/* No startup file opened */
		    CR_BTREE_EXT :
		    case CR_BTREE_EXT_0 :
			file = priv_data->extents_file;

		    CR_BTREE :
			PED_ASSERT(PED_SECTOR_SIZE_DEFAULT * ref->sect_by_block
				   > ref->ref_offset, return -1 );
			if (!hfsplus_file_read(file, hfsp_block, 
				(PedSector)ref->ref_block * ref->sect_by_block,
				ref->sect_by_block))
				return -1;
			extent = ( HfsPExtDescriptor* )
				( hfsp_block + ref->ref_offset );
			extent[ref->ref_index].start_block =
				PED_CPU_TO_BE32(new_start);
			if (!hfsplus_file_write(file, hfsp_block,
				(PedSector)ref->ref_block * ref->sect_by_block,
				ref->sect_by_block)
			    || !ped_geometry_sync_fast (priv_data->plus_geom))
				return -1;
			break;

		    /********** BUG *********/
		    default :
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("A reference to an extent comes from a place "
				  "it should not.  You should check the file "
				  "system!"));
			return -1;
			break;
		}

		move = hfsc_cache_move_extent(cache, ref->ext_start, new_start);
		if (!move) return -1;
		PED_ASSERT(move == ref, return -1);
	}

	return new_start;
}

/* save any dirty sector of the allocation bitmap file */
static int
hfsplus_save_allocation(PedFileSystem *fs)
{
	HfsPPrivateFSData*	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	unsigned int		map_sectors, i, j;
	int			ret = 1;

	map_sectors = ( PED_BE32_TO_CPU (priv_data->vh->total_blocks) 
			+ PED_SECTOR_SIZE_DEFAULT * 8 - 1 ) / (PED_SECTOR_SIZE_DEFAULT * 8);

	for (i = 0; i < map_sectors;) {
		for (j = i; 
		     (TST_BLOC_OCCUPATION(priv_data->dirty_alloc_map,j));
		     ++j)
			CLR_BLOC_OCCUPATION(priv_data->dirty_alloc_map,j);
		if (j-i) {
			ret = hfsplus_file_write(priv_data->allocation_file,
				    priv_data->alloc_map + i * PED_SECTOR_SIZE_DEFAULT,
				    i, j-i) && ret;
			i = j;
		} else
			++i;
	}

	return ret;
}

/* This function moves an extent starting at block fblock
   to block to_fblock if there's enough room */
/* Return 1 if everything was fine */
/* Return -1 if an error occurred */
/* Return 0 if no extent was found */
static int
hfsplus_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
				 unsigned int *ptr_to_fblock,
				 HfsCPrivateCache* cache)
{
	HfsCPrivateExtent*	ref;
	unsigned int		old_start, new_start;

	ref = hfsc_cache_search_extent(cache, *ptr_fblock);
	if (!ref) return 0;

	old_start = *ptr_fblock;
	new_start = hfsplus_do_move(fs, ptr_fblock, ptr_to_fblock, cache, ref);
	if (new_start == (unsigned)-1) return -1;
	if (new_start > old_start) {
		new_start = hfsplus_do_move(fs, &new_start, ptr_to_fblock,
					    cache, ref);
		if (new_start == (unsigned)-1 || new_start > old_start)
			return -1;
	}

	hfsplus_save_allocation(fs);
	return 1;
}

static int
hfsplus_cache_from_vh(HfsCPrivateCache* cache, PedFileSystem* fs,
		      PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsPExtDescriptor*	extent;
	unsigned int		j;

	extent = priv_data->vh->allocation_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_ALLOC,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->extents_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_EXT,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->catalog_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_CAT,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->attributes_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_ATTR,
			j )
		   )
			return 0;
	}

	extent = priv_data->vh->startup_file.extents;
	for (j = 0; j < HFSP_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE32_TO_CPU(extent[j].start_block),
			PED_BE32_TO_CPU(extent[j].block_count),
			0, /* unused for vh */
			((uint8_t*)extent) - ((uint8_t*)priv_data->vh),
			1, /* load / save 1 sector */
			CR_PRIM_START,
			j )
		   )
			return 0;
	}

	return 1;
}

static int
hfsplus_cache_from_catalog(HfsCPrivateCache* cache, PedFileSystem* fs,
			   PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	uint8_t			node_1[PED_SECTOR_SIZE_DEFAULT];
	uint8_t*		node;
	HfsPHeaderRecord*	header;
	HfsPNodeDescriptor*	desc = (HfsPNodeDescriptor*) node_1;
	HfsPCatalogKey*		catalog_key;
	HfsPCatalog*		catalog_data;
	HfsPExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j, size, bsize;
	uint32_t		jib = priv_data->jib_start_block,
				jl  = priv_data->jl_start_block;

	if (!priv_data->catalog_file->sect_nb) {
		ped_exception_throw (
			PED_EXCEPTION_INFORMATION,
			PED_EXCEPTION_OK,
			_("This HFS+ volume has no catalog file.  "
			  "This is very unusual!"));
		return 1;
	}

	/* Search the extent starting at *ptr_block in the catalog file */
	if (!hfsplus_file_read_sector (priv_data->catalog_file, node_1, 0))
		return 0;
	header = (HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC);
	leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	bsize = PED_BE16_TO_CPU (header->node_size);
	size = bsize / PED_SECTOR_SIZE_DEFAULT;
	PED_ASSERT(size < 256, return 0);

	node = (uint8_t*) ped_malloc(bsize);
	if (!node) return 0;
	desc = (HfsPNodeDescriptor*) node;

	for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfsplus_file_read (priv_data->catalog_file, node,
					(PedSector) leaf_node * size, size)) {
			ped_free (node);
			return 0;
		}
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; i++) {
			unsigned int	skip;
			uint8_t		where;

			catalog_key = (HfsPCatalogKey*)
			    ( node + PED_BE16_TO_CPU (*((uint16_t *)
					(node+(bsize - 2*i)))) );
			skip = ( 2 + PED_BE16_TO_CPU (catalog_key->key_length)
				 + 1) & ~1;
			catalog_data = (HfsPCatalog*)
					    (((uint8_t*)catalog_key) + skip);
			/* check for obvious error in FS */
			if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)catalog_data - node
			        >= (signed) bsize
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				ped_free (node);
				return 0;
			}

			if (PED_BE16_TO_CPU(catalog_data->type)!=HFS_CAT_FILE)
				continue;

			extent = catalog_data->sel.file.data_fork.extents;
			for (j = 0; j < HFSP_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				where = CR_BTREE_CAT;
				if ( PED_BE32_TO_CPU(extent[j].start_block)
				     == jib ) {
					jib = 0;
					where = CR_BTREE_CAT_JIB;
				} else
				  if ( PED_BE32_TO_CPU(extent[j].start_block)
				       == jl ) {
					jl = 0;
					where = CR_BTREE_CAT_JL;
				}
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE32_TO_CPU(extent[j].start_block),
					PED_BE32_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					size,
					where,
					j )
				   ) {
					ped_free (node);
				 	return 0;
				}
			}

			extent = catalog_data->sel.file.res_fork.extents;
			for (j = 0; j < HFSP_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE32_TO_CPU(extent[j].start_block),
					PED_BE32_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					size,
					CR_BTREE_CAT,
					j )
				   ) {
					ped_free (node);
				 	return 0;
				}
			}
		}
	}

	ped_free (node);
	return 1;
}

static int
hfsplus_cache_from_extent(HfsCPrivateCache* cache, PedFileSystem* fs,
			  PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	uint8_t			node_1[PED_SECTOR_SIZE_DEFAULT];
	uint8_t*		node;
	HfsPHeaderRecord*	header;
	HfsPNodeDescriptor*	desc = (HfsPNodeDescriptor*) node_1;
	HfsPExtentKey*		extent_key;
	HfsPExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j, size, bsize;

	if (!priv_data->extents_file->sect_nb) {
		ped_exception_throw (
			PED_EXCEPTION_INFORMATION,
			PED_EXCEPTION_OK,
			_("This HFS+ volume has no extents overflow "
			  "file.  This is quite unusual!"));
		return 1;
	}

	if (!hfsplus_file_read_sector (priv_data->extents_file, node_1, 0))
		return 0;
	header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
	leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	bsize = PED_BE16_TO_CPU (header->node_size);
	size = bsize / PED_SECTOR_SIZE_DEFAULT;
	PED_ASSERT(size < 256, return 0);

	node = (uint8_t*) ped_malloc (bsize);
	if (!node) return -1;
	desc = (HfsPNodeDescriptor*) node;

	for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfsplus_file_read (priv_data->extents_file, node,
					(PedSector) leaf_node * size, size)) {
			ped_free (node);
			return 0;
		}
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; i++) {
			uint8_t where;
			extent_key = (HfsPExtentKey*)
			    (node + PED_BE16_TO_CPU(*((uint16_t *)
					    (node+(bsize - 2*i)))));
			extent = (HfsPExtDescriptor*)
			    (((uint8_t*)extent_key) + sizeof (HfsPExtentKey));
			/* check for obvious error in FS */
			if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)extent - node
			        >= (signed)bsize
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				ped_free (node);
				return -1;
			}
			
			switch (extent_key->file_ID) {
			    case PED_CPU_TO_BE32 (HFS_XTENT_ID) :
				if (ped_exception_throw (
					PED_EXCEPTION_WARNING,
					PED_EXCEPTION_IGNORE_CANCEL,
					_("The extents overflow file should not"
					" contain its own extents!  You should "
					"check the file system."))
						!= PED_EXCEPTION_IGNORE)
					return 0;
				where = CR_BTREE_EXT_EXT;
				break;
			    case PED_CPU_TO_BE32 (HFS_CATALOG_ID) :
				where = CR_BTREE_EXT_CAT;
				break;
			    case PED_CPU_TO_BE32 (HFSP_ALLOC_ID) :
				where = CR_BTREE_EXT_ALLOC;
				break;
			    case PED_CPU_TO_BE32 (HFSP_STARTUP_ID) :
				where = CR_BTREE_EXT_START;
				break;
			    case PED_CPU_TO_BE32 (HFSP_ATTRIB_ID) :
			    	where = CR_BTREE_EXT_ATTR;
				break;
			    default :
			    	where = CR_BTREE_EXT_0;
				break;
			}
			
			for (j = 0; j < HFSP_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE32_TO_CPU(extent[j].start_block),
					PED_BE32_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					size,
					where,
					j )
				   ) {
					ped_free (node);
					return 0;
				}
			}
		}
	}
	
	ped_free (node);
	return 1;
}

static int
hfsplus_cache_from_attributes(HfsCPrivateCache* cache, PedFileSystem* fs,
			      PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	uint8_t			node_1[PED_SECTOR_SIZE_DEFAULT];
	uint8_t*		node;
	HfsPHeaderRecord*	header;
	HfsPNodeDescriptor*	desc = (HfsPNodeDescriptor*) node_1;
	HfsPPrivateGenericKey*	generic_key;
	HfsPForkDataAttr*	fork_ext_data;
	HfsPExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j, size, bsize;

	/* attributes file is facultative */
	if (!priv_data->attributes_file->sect_nb)
		return 1;

	/* Search the extent starting at *ptr_block in the catalog file */
	if (!hfsplus_file_read_sector (priv_data->attributes_file, node_1, 0))
		return 0;
	header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
	leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	bsize = PED_BE16_TO_CPU (header->node_size);
	size = bsize / PED_SECTOR_SIZE_DEFAULT;
	PED_ASSERT(size < 256, return 0);

	node = (uint8_t*) ped_malloc(bsize);
	if (!node) return 0;
	desc = (HfsPNodeDescriptor*) node;

	for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfsplus_file_read (priv_data->attributes_file, node,
					(PedSector) leaf_node * size, size)) {
			ped_free (node);
			return 0;
		}
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; i++) {
			unsigned int	skip;
			generic_key = (HfsPPrivateGenericKey*)
				(node + PED_BE16_TO_CPU(*((uint16_t *)
					    (node+(bsize - 2*i)))));
			skip = ( 2 + PED_BE16_TO_CPU (generic_key->key_length)
			         + 1 ) & ~1;
			fork_ext_data = (HfsPForkDataAttr*)
					    (((uint8_t*)generic_key) + skip);
			/* check for obvious error in FS */
			if (((uint8_t*)generic_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)fork_ext_data - node
			        >= (signed) bsize
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				ped_free (node);
				return 0;
			}

			if (fork_ext_data->record_type
			    == PED_CPU_TO_BE32 ( HFSP_ATTR_FORK ) ) {
				extent = fork_ext_data->fork_res.fork.extents;
				for (j = 0; j < HFSP_EXT_NB; ++j) {
					if (!extent[j].block_count) break;
					if (!hfsc_cache_add_extent(
						cache,
						PED_BE32_TO_CPU (
							extent[j].start_block ),
						PED_BE32_TO_CPU (
							extent[j].block_count ),
						leaf_node,
						(uint8_t*)extent-node,
						size,
						CR_BTREE_ATTR,
						j )
					   ) {
						ped_free(node);
						return 0;
					}
				}
			} else if (fork_ext_data->record_type
			    == PED_CPU_TO_BE32 ( HFSP_ATTR_EXTENTS ) ) {
				extent = fork_ext_data->fork_res.extents;
				for (j = 0; j < HFSP_EXT_NB; ++j) {
					if (!extent[j].block_count) break;
					if (!hfsc_cache_add_extent(
						cache,
						PED_BE32_TO_CPU (
							extent[j].start_block ),
						PED_BE32_TO_CPU (
							extent[j].block_count ),
						leaf_node,
						(uint8_t*)extent-node,
						size,
						CR_BTREE_ATTR,
						j )
					   ) {
						ped_free(node);
						return 0;
					}
				}
			} else continue;
		}
	}

	ped_free (node);
	return 1;
}

static HfsCPrivateCache*
hfsplus_cache_extents(PedFileSystem* fs, PedTimer* timer)
{
	HfsPPrivateFSData*	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsCPrivateCache*	ret;
	unsigned int		file_number, block_number;

	file_number = PED_BE32_TO_CPU(priv_data->vh->file_count);
	block_number = PED_BE32_TO_CPU(priv_data->vh->total_blocks);
	ret = hfsc_new_cache(block_number, file_number);
	if (!ret) return NULL;

	if (!hfsplus_cache_from_vh(ret, fs, timer) ||
	    !hfsplus_cache_from_catalog(ret, fs, timer) ||
	    !hfsplus_cache_from_extent(ret, fs, timer) ||
	    !hfsplus_cache_from_attributes(ret, fs, timer)) {
		ped_exception_throw(
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Could not cache the file system in memory."));
		hfsc_delete_cache(ret);
		return NULL;
	}

	return ret;
}

/* This function moves file's data to compact used and free space,
   starting at fblock block */
/* return 0 on error */
int
hfsplus_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
				    PedTimer* timer, unsigned int to_free)
{
	PedSector		bytes_buff;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsPVolumeHeader*	vh = priv_data->vh;
	HfsCPrivateCache*	cache;
	unsigned int 		to_fblock = fblock;
	unsigned int		start = fblock;
	unsigned int		divisor = PED_BE32_TO_CPU (vh->total_blocks)
				          + 1 - start - to_free;
	int			ret;

	PED_ASSERT (!hfsp_block, return 0);

	cache = hfsplus_cache_extents (fs, timer);
	if (!cache)
		return 0;

	/* Calculate the size of the copy buffer :
	 * Takes BLOCK_MAX_BUFF HFS blocks, but if > BYTES_MAX_BUFF
	 * takes the maximum number of HFS blocks so that the buffer
	 * will remain smaller than or equal to BYTES_MAX_BUFF, with
	 * a minimum of 1 HFS block */
	bytes_buff = PED_BE32_TO_CPU (priv_data->vh->block_size)
		     * (PedSector) BLOCK_MAX_BUFF;
	if (bytes_buff > BYTES_MAX_BUFF) {
		hfsp_block_count = BYTES_MAX_BUFF
				 / PED_BE32_TO_CPU (priv_data->vh->block_size);
		if (!hfsp_block_count)
			hfsp_block_count = 1;
		bytes_buff = (PedSector) hfsp_block_count
			     * PED_BE32_TO_CPU (priv_data->vh->block_size);
	} else
		hfsp_block_count = BLOCK_MAX_BUFF;

	/* If the cache code requests more space, give it to him */
	if (bytes_buff < hfsc_cache_needed_buffer (cache))
		bytes_buff = hfsc_cache_needed_buffer (cache);

	hfsp_block = (uint8_t*) ped_malloc (bytes_buff);
	if (!hfsp_block)
		goto error_cache;

	if (!hfsplus_read_bad_blocks (fs)) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Bad blocks list could not be loaded."));
		goto error_alloc;
	}

	while ( fblock < ( priv_data->plus_geom->length - 2 )
			 / ( PED_BE32_TO_CPU (vh->block_size)
			     / PED_SECTOR_SIZE_DEFAULT ) ) {
		if (TST_BLOC_OCCUPATION (priv_data->alloc_map, fblock)
		    && (!hfsplus_is_bad_block (fs, fblock))) {
			if (!(ret = hfsplus_move_extent_starting_at (fs,
						&fblock, &to_fblock, cache)))
				to_fblock = ++fblock;
			else if (ret == -1) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("An error occurred during extent "
					  "relocation."));
				goto error_alloc;
			}
		} else {
			fblock++;
		}

		ped_timer_update(timer, (float)(to_fblock - start) / divisor);
	}

	ped_free (hfsp_block); hfsp_block = NULL; hfsp_block_count = 0;
	hfsc_delete_cache (cache);
	return 1;

error_alloc:
	ped_free (hfsp_block); hfsp_block = NULL; hfsp_block_count = 0;
error_cache:
	hfsc_delete_cache (cache);
	return 0;
}

#endif /* !DISCOVER_ONLY */
