Exemple #1
0
/*         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;
}
Exemple #2
0
PyObject *py_ped_geometry_sync_fast(PyObject *s, PyObject *args) {
    int ret = -1;
    PedGeometry *geom = NULL;

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

    ret = ped_geometry_sync_fast(geom);
    if (ret == 0) {
        PyErr_SetString(IOException, "Could not sync");
        return NULL;
    }

    if (ret) {
        Py_RETURN_TRUE;
    } else {
        Py_RETURN_FALSE;
    }
}
Exemple #3
0
/* -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);
	PED_ASSERT (*ptr_to_fblock <= *ptr_fblock);
	/* quiet GCC */
	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;
}
Exemple #4
0
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);
			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 new_start;
}