summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2011-05-16 14:21:44 +0200
committerJim Meyering <meyering@redhat.com>2011-05-27 17:07:45 +0200
commit71cc20bc9a6dbd31ebaa962c41be76fddb80d045 (patch)
tree22a50b1413773bd56b1a838a48b05b91ba9eaf2f
parent4ac1b368a5f5e77aac5f18d38871326caf9c1f13 (diff)
downloadparted-71cc20bc9a6dbd31ebaa962c41be76fddb80d045.tar.gz
hfs: remove all-but-probe FS-related code
-rw-r--r--libparted/fs/hfs/Makefile.am11
-rw-r--r--libparted/fs/hfs/advfs.c328
-rw-r--r--libparted/fs/hfs/advfs.h48
-rw-r--r--libparted/fs/hfs/advfs_plus.c382
-rw-r--r--libparted/fs/hfs/advfs_plus.h51
-rw-r--r--libparted/fs/hfs/cache.c238
-rw-r--r--libparted/fs/hfs/cache.h117
-rw-r--r--libparted/fs/hfs/file.c228
-rw-r--r--libparted/fs/hfs/file.h41
-rw-r--r--libparted/fs/hfs/file_plus.c273
-rw-r--r--libparted/fs/hfs/file_plus.h60
-rw-r--r--libparted/fs/hfs/hfs.c1173
-rw-r--r--libparted/fs/hfs/journal.c389
-rw-r--r--libparted/fs/hfs/journal.h44
-rw-r--r--libparted/fs/hfs/reloc.c669
-rw-r--r--libparted/fs/hfs/reloc.h35
-rw-r--r--libparted/fs/hfs/reloc_plus.c942
-rw-r--r--libparted/fs/hfs/reloc_plus.h36
18 files changed, 2 insertions, 5063 deletions
diff --git a/libparted/fs/hfs/Makefile.am b/libparted/fs/hfs/Makefile.am
index 053bce1..f85493c 100644
--- a/libparted/fs/hfs/Makefile.am
+++ b/libparted/fs/hfs/Makefile.am
@@ -1,16 +1,9 @@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
partedincludedir = -I$(top_srcdir)/include
noinst_LTLIBRARIES = libhfs.la
libhfs_la_SOURCES = hfs.c hfs.h \
- probe.c probe.h \
- cache.c cache.h \
- advfs.c advfs.h \
- file.c file.h \
- reloc.c reloc.h \
- advfs_plus.c advfs_plus.h \
- file_plus.c file_plus.h \
- reloc_plus.c reloc_plus.h \
- journal.c journal.h
+ probe.c probe.h
INCLUDES = $(partedincludedir) $(INTLINCS)
diff --git a/libparted/fs/hfs/advfs.c b/libparted/fs/hfs/advfs.c
deleted file mode 100644
index a8adfb3..0000000
--- a/libparted/fs/hfs/advfs.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#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.h"
-
-#include "advfs.h"
-
-/* - if a < b, 0 if a == b, + if a > b */
-/* Comparaison is done in the following order : */
-/* CNID, then fork type, then start block */
-/* Note that HFS implementation in linux has a bug */
-/* in this function */
-static int
-hfs_extent_key_cmp(HfsPrivateGenericKey* a, HfsPrivateGenericKey* b)
-{
- HfsExtentKey* key1 = (HfsExtentKey*) a;
- HfsExtentKey* key2 = (HfsExtentKey*) b;
-
- /* do NOT use a substraction, because */
- /* 0xFFFFFFFF - 1 = 0xFFFFFFFE so this */
- /* would return -2, despite the fact */
- /* 0xFFFFFFFF > 1 !!! (this is the 2.4 bug) */
- if (key1->file_ID != key2->file_ID)
- return PED_BE32_TO_CPU(key1->file_ID) <
- PED_BE32_TO_CPU(key2->file_ID) ?
- -1 : +1;
-
- if (key1->type != key2->type)
- return (int)(key1->type - key2->type);
-
- if (key1->start == key2->start)
- return 0;
- /* the whole thing wont work with 16 bits ints */
- /* anyway */
- return (int)( PED_BE16_TO_CPU(key1->start) -
- PED_BE16_TO_CPU(key2->start) );
-}
-
-/* do a B-Tree lookup */
-/* read the first record immediatly inferior or egal to the given key */
-/* return 0 on error */
-/* record_out _must_ be large enough to receive record_size bytes */
-/* WARNING : the compare function called only handle Extents BTree */
-/* so modify this function if you want to do lookup in */
-/* other BTrees has well */
-int
-hfs_btree_search (HfsPrivateFile* b_tree_file, HfsPrivateGenericKey* key,
- void *record_out, unsigned int record_size,
- HfsCPrivateLeafRec* record_ref)
-{
- uint8_t node[PED_SECTOR_SIZE_DEFAULT];
- HfsHeaderRecord* header;
- HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
- HfsPrivateGenericKey* record_key = NULL;
- unsigned int node_number, record_number;
- int i;
-
- /* Read the header node */
- if (!hfs_file_read_sector(b_tree_file, node, 0))
- return 0;
- header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
- (node+(PED_SECTOR_SIZE_DEFAULT-2))))));
-
- /* Get the node number of the root */
- node_number = PED_BE32_TO_CPU(header->root_node);
- if (!node_number)
- return 0;
-
- /* Read the root node */
- if (!hfs_file_read_sector(b_tree_file, node, node_number))
- return 0;
-
- /* Follow the white rabbit */
- while (1) {
- record_number = PED_BE16_TO_CPU (desc->rec_nb);
- for (i = record_number; i; i--) {
- record_key = (HfsPrivateGenericKey*)
- (node + PED_BE16_TO_CPU(*((uint16_t *)
- (node+(PED_SECTOR_SIZE_DEFAULT - 2*i)))));
- /* check for obvious error in FS */
- if (((uint8_t*)record_key - node < HFS_FIRST_REC)
- || ((uint8_t*)record_key - node
- >= PED_SECTOR_SIZE_DEFAULT
- - 2 * (signed)(record_number+1))) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("The file system contains errors."));
- return 0;
- }
- if (hfs_extent_key_cmp(record_key, key) <= 0)
- break;
- }
- if (!i) return 0;
- if (desc->type == HFS_IDX_NODE) {
- unsigned int skip;
-
- skip = (1 + record_key->key_length + 1) & ~1;
- node_number = PED_BE32_TO_CPU (*((uint32_t *)
- (((uint8_t *) record_key) + skip)));
- if (!hfs_file_read_sector(b_tree_file, node,
- node_number))
- return 0;
- } else
- break;
- }
-
- /* copy the result if needed */
- if (record_size)
- memcpy (record_out, record_key, record_size);
-
- /* send record reference if needed */
- if (record_ref) {
- record_ref->node_size = 1; /* in sectors */
- record_ref->node_number = node_number;
- record_ref->record_pos = (uint8_t*)record_key - node;
- record_ref->record_number = i;
- }
-
- /* success */
- return 1;
-}
-
-/* free the bad blocks linked list */
-void
-hfs_free_bad_blocks_list(HfsPrivateLinkExtent* first)
-{
- HfsPrivateLinkExtent* next;
-
- while (first) {
- next = first->next;
- free (first);
- first = next;
- }
-}
-
-/* This function reads bad blocks extents in the extents file
- and store it in f.s. specific data of fs */
-int
-hfs_read_bad_blocks (const PedFileSystem *fs)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
-
- if (priv_data->bad_blocks_loaded)
- return 1;
-
- {
- uint8_t record[sizeof (HfsExtentKey)
- + sizeof (HfsExtDataRec)];
- HfsExtentKey search;
- HfsExtentKey* ret_key = (HfsExtentKey*) record;
- HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
- (record + sizeof (HfsExtentKey));
- unsigned int block, last_start, first_pass = 1;
-
- search.key_length = sizeof (HfsExtentKey) - 1;
- search.type = HFS_DATA_FORK;
- search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-
- last_start = -1; block = 0;
- while (1) {
- int i;
-
- search.start = PED_CPU_TO_BE16 (block);
- if (!hfs_btree_search (priv_data->extent_file,
- (HfsPrivateGenericKey*) &search,
- record, sizeof (record), NULL)
- || ret_key->file_ID != search.file_ID
- || ret_key->type != search.type) {
- if (first_pass)
- break;
- else
- goto errbb;
- }
- if (PED_BE16_TO_CPU (ret_key->start) == last_start)
- break;
-
- last_start = PED_BE16_TO_CPU (ret_key->start);
- for (i = 0; i < HFS_EXT_NB; i++) {
- if (ret_cache[i].block_count) {
- HfsPrivateLinkExtent* new_xt =
- (HfsPrivateLinkExtent*) ped_malloc (
- sizeof (HfsPrivateLinkExtent));
- if (!new_xt)
- goto errbb;
- new_xt->next = priv_data->bad_blocks_xtent_list;
- memcpy(&(new_xt->extent), ret_cache+i,
- sizeof (HfsExtDescriptor));
- priv_data->bad_blocks_xtent_list = new_xt;
- priv_data->bad_blocks_xtent_nb++;
- block += PED_BE16_TO_CPU (
- ret_cache[i].block_count);
- }
- }
- first_pass = 0;
- }
-
- priv_data->bad_blocks_loaded = 1;
- return 1;}
-
-errbb: hfs_free_bad_blocks_list(priv_data->bad_blocks_xtent_list);
- priv_data->bad_blocks_xtent_list=NULL;
- priv_data->bad_blocks_xtent_nb=0;
- return 0;
-}
-
-/* This function check if fblock is a bad block */
-int
-hfs_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- HfsPrivateLinkExtent* walk;
-
- for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
- /* Won't compile without the strange cast ! gcc bug ? */
- /* or maybe C subtilties... */
- if ((fblock >= PED_BE16_TO_CPU (walk->extent.start_block)) &&
- (fblock < (unsigned int) (PED_BE16_TO_CPU (
- walk->extent.start_block)
- + PED_BE16_TO_CPU (
- walk->extent.block_count))))
- return 1;
- }
-
- return 0;
-}
-
-/* This function returns the first sector of the last free block of an
- HFS volume we can get after a hfs_pack_free_space_from_block call */
-/* On error this function returns 0 */
-PedSector
-hfs_get_empty_end (const PedFileSystem *fs)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- HfsMasterDirectoryBlock* mdb = priv_data->mdb;
- unsigned int block, last_bad, end_free_blocks;
-
- /* find the next block to the last bad block of the volume */
- if (!hfs_read_bad_blocks (fs))
- return 0;
-
- HfsPrivateLinkExtent* l;
- last_bad = 0;
- for (l = priv_data->bad_blocks_xtent_list; l; l = l->next) {
- if ((unsigned int) PED_BE16_TO_CPU (l->extent.start_block)
- + PED_BE16_TO_CPU (l->extent.block_count) > last_bad)
- last_bad = PED_BE16_TO_CPU (l->extent.start_block)
- + PED_BE16_TO_CPU (l->extent.block_count);
- }
-
- /* Count the free blocks from last_bad to the end of the volume */
- end_free_blocks = 0;
- for (block = last_bad;
- block < PED_BE16_TO_CPU (mdb->total_blocks);
- block++) {
- if (!TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- end_free_blocks++;
- }
-
- /* Calculate the block that will by the first free at the
- end of the volume */
- block = PED_BE16_TO_CPU (mdb->total_blocks) - end_free_blocks;
-
- return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
- + (PedSector) block * (PED_BE32_TO_CPU (mdb->block_size)
- / PED_SECTOR_SIZE_DEFAULT);
-}
-
-/* return the block which should be used to pack data to have at
- least free fblock blocks at the end of the volume */
-unsigned int
-hfs_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- unsigned int block;
-
- for (block = PED_BE16_TO_CPU (priv_data->mdb->total_blocks) - 1;
- block && fblock;
- block--) {
- if (!TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- fblock--;
- }
-
- while (block && !TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- block--;
- if (TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- block++;
-
- return block;
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/advfs.h b/libparted/fs/hfs/advfs.h
deleted file mode 100644
index aff503e..0000000
--- a/libparted/fs/hfs/advfs.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ADVFS_H
-#define _ADVFS_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-int
-hfs_btree_search (HfsPrivateFile* b_tree_file, HfsPrivateGenericKey* key,
- void *record_out, unsigned int record_size,
- HfsCPrivateLeafRec* record_ref);
-
-void
-hfs_free_bad_blocks_list(HfsPrivateLinkExtent* first);
-
-int
-hfs_read_bad_blocks (const PedFileSystem *fs);
-
-int
-hfs_is_bad_block (const PedFileSystem *fs, unsigned int fblock);
-
-PedSector
-hfs_get_empty_end (const PedFileSystem *fs);
-
-unsigned int
-hfs_find_start_pack (const PedFileSystem *fs, unsigned int fblock);
-
-#endif /* _ADVFS_H */
diff --git a/libparted/fs/hfs/advfs_plus.c b/libparted/fs/hfs/advfs_plus.c
deleted file mode 100644
index 08d2f61..0000000
--- a/libparted/fs/hfs/advfs_plus.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef DISCOVER_ONLY
-
-#include <config.h>
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#if ENABLE_NLS
-# include <libintl.h>
-# define _(String) dgettext (PACKAGE, String)
-#else
-# define _(String) (String)
-#endif /* ENABLE_NLS */
-
-#include "hfs.h"
-#include "advfs.h"
-#include "file_plus.h"
-
-#include "advfs_plus.h"
-
-/* - if a < b, 0 if a == b, + if a > b */
-/* Comparaison is done in the following order : */
-/* CNID, then fork type, then start block */
-static int
-hfsplus_extent_key_cmp(HfsPPrivateGenericKey* a, HfsPPrivateGenericKey* b)
-{
- HfsPExtentKey* key1 = (HfsPExtentKey*) a;
- HfsPExtentKey* key2 = (HfsPExtentKey*) b;
-
- if (key1->file_ID != key2->file_ID)
- return PED_BE32_TO_CPU(key1->file_ID) <
- PED_BE32_TO_CPU(key2->file_ID) ?
- -1 : +1;
-
- if (key1->type != key2->type)
- return (int)(key1->type - key2->type);
-
- if (key1->start == key2->start)
- return 0;
- return PED_BE32_TO_CPU(key1->start) <
- PED_BE32_TO_CPU(key2->start) ?
- -1 : +1;
-}
-
-/* do a B-Tree lookup */
-/* read the first record immediatly inferior or egal to the given key */
-/* return 0 on error */
-/* record_out _must_ be large enough to receive the whole record (key + data) */
-/* WARNING : the search function called only handle Extents BTree */
-/* so modify this function if you want to do lookup in */
-/* other BTrees has well */
-int
-hfsplus_btree_search (HfsPPrivateFile* b_tree_file, HfsPPrivateGenericKey* key,
- void *record_out, unsigned int record_size,
- HfsCPrivateLeafRec* record_ref)
-{
- uint8_t node_1[PED_SECTOR_SIZE_DEFAULT];
- uint8_t* node;
- HfsPHeaderRecord* header;
- HfsPPrivateGenericKey* record_key = NULL;
- unsigned int node_number, record_number, size, bsize;
- int i;
-
- /* Read the header node */
- if (!hfsplus_file_read_sector(b_tree_file, node_1, 0))
- return 0;
- header = (HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC);
-
- /* Get the node number of the root */
- node_number = PED_BE32_TO_CPU (header->root_node);
- if (!node_number)
- return 0;
-
- /* Get the size of a node in sectors and allocate buffer */
- size = (bsize = PED_BE16_TO_CPU (header->node_size)) / PED_SECTOR_SIZE_DEFAULT;
- node = (uint8_t*) ped_malloc (bsize);
- if (!node)
- return 0;
- HfsPNodeDescriptor *desc = (HfsPNodeDescriptor*) node;
-
- /* Read the root node */
- if (!hfsplus_file_read (b_tree_file, node,
- (PedSector) node_number * size, size))
- return 0;
-
- /* Follow the white rabbit */
- while (1) {
- record_number = PED_BE16_TO_CPU (desc->rec_nb);
- for (i = record_number; i; i--) {
- record_key = (HfsPPrivateGenericKey*)
- (node + PED_BE16_TO_CPU(*((uint16_t *)
- (node+(bsize - 2*i)))));
- /* check for obvious error in FS */
- if (((uint8_t*)record_key - node < HFS_FIRST_REC)
- || ((uint8_t*)record_key - node
- >= (signed)bsize
- - 2 * (signed)(record_number+1))) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("The file system contains errors."));
- free (node);
- return 0;
- }
- if (hfsplus_extent_key_cmp(record_key, key) <= 0)
- break;
- }
- if (!i) { free (node); return 0; }
- if (desc->type == HFS_IDX_NODE) {
- unsigned int skip;
-
- skip = ( 2 + PED_BE16_TO_CPU (record_key->key_length)
- + 1 ) & ~1;
- node_number = PED_BE32_TO_CPU (*((uint32_t *)
- (((uint8_t *) record_key) + skip)));
- if (!hfsplus_file_read(b_tree_file, node,
- (PedSector) node_number * size,
- size)) {
- free (node);
- return 0;
- }
- } else
- break;
- }
-
- /* copy the result if needed */
- if (record_size)
- memcpy (record_out, record_key, record_size);
-
- /* send record reference if needed */
- if (record_ref) {
- record_ref->node_size = size; /* in sectors */
- record_ref->node_number = node_number;
- record_ref->record_pos = (uint8_t*)record_key - node;
- record_ref->record_number = i;
- }
-
- /* success */
- free (node);
- return 1;
-}
-
-/* free the bad blocks linked list */
-void
-hfsplus_free_bad_blocks_list(HfsPPrivateLinkExtent* first)
-{
- HfsPPrivateLinkExtent* next;
-
- while (first) {
- next = first->next;
- free (first);
- first = next;
- }
-}
-
-/* This function reads bad blocks extents in the extents file
- and store it in f.s. specific data of fs */
-int
-hfsplus_read_bad_blocks (const PedFileSystem *fs)
-{
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
-
- if (priv_data->bad_blocks_loaded)
- return 1;
-
- {
- uint8_t record[sizeof (HfsPExtentKey)
- + sizeof (HfsPExtDataRec)];
- HfsPExtentKey search;
- HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
- HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
- (record + sizeof (HfsPExtentKey));
- int block, first_pass = 1;
- unsigned int last_start;
-
- search.key_length = sizeof (HfsExtentKey) - 2;
- search.type = HFS_DATA_FORK;
- search.pad = 0;
- search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-
- last_start = -1; block = 0;
- while (1) {
- int i;
-
- search.start = PED_CPU_TO_BE32 (block);
- if (!hfsplus_btree_search (priv_data->extents_file,
- (HfsPPrivateGenericKey*) &search,
- record, sizeof (record), NULL)
- || ret_key->file_ID != search.file_ID
- || ret_key->type != search.type) {
- if (first_pass)
- break;
- else
- goto errbbp;
- }
- if (PED_BE32_TO_CPU (ret_key->start) == last_start)
- break;
-
- last_start = PED_BE32_TO_CPU (ret_key->start);
- for (i = 0; i < HFSP_EXT_NB; i++) {
- if (ret_cache[i].block_count) {
- HfsPPrivateLinkExtent* new_xt =
- (HfsPPrivateLinkExtent*) ped_malloc (
- sizeof (HfsPPrivateLinkExtent));
- if (!new_xt)
- goto errbbp;
- new_xt->next = priv_data->bad_blocks_xtent_list;
- memcpy (&(new_xt->extent), ret_cache+i,
- sizeof (HfsPExtDescriptor));
- priv_data->bad_blocks_xtent_list = new_xt;
- priv_data->bad_blocks_xtent_nb++;
- block += PED_BE32_TO_CPU (
- ret_cache[i].block_count);
- }
- }
- first_pass = 0;
- }
-
- priv_data->bad_blocks_loaded = 1;
- return 1;}
-
-errbbp: hfsplus_free_bad_blocks_list(priv_data->bad_blocks_xtent_list);
- priv_data->bad_blocks_xtent_list=NULL;
- priv_data->bad_blocks_xtent_nb=0;
- return 0;
-}
-
-/* This function check if fblock is a bad block */
-int
-hfsplus_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-{
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
- HfsPPrivateLinkExtent* walk;
-
- for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
- /* Won't compile without the strange cast ! gcc bug ? */
- /* or maybe C subtilties... */
- if ((fblock >= PED_BE32_TO_CPU (walk->extent.start_block)) &&
- (fblock < (unsigned int)(PED_BE32_TO_CPU (
- walk->extent.start_block)
- + PED_BE32_TO_CPU (walk->extent.block_count))))
- return 1;
- }
-
- return 0;
-}
-
-/* This function returns the first sector of the last free block of
- an HFS+ volume we can get after a hfsplus_pack_free_space_from_block call */
-PedSector
-hfsplus_get_empty_end (const PedFileSystem *fs)
-{
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
- HfsPVolumeHeader* vh = priv_data->vh;
- unsigned int block, last_bad, end_free_blocks;
-
- /* find the next block to the last bad block of the volume */
- if (!hfsplus_read_bad_blocks (fs)) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Bad blocks could not be read."));
- return 0;
- }
-
- HfsPPrivateLinkExtent* l;
- last_bad = 0;
- for (l = priv_data->bad_blocks_xtent_list; l; l = l->next) {
- if ((unsigned int) PED_BE32_TO_CPU (l->extent.start_block)
- + PED_BE32_TO_CPU (l->extent.block_count) > last_bad)
- last_bad = PED_BE32_TO_CPU (l->extent.start_block)
- + PED_BE32_TO_CPU (l->extent.block_count);
- }
-
- /* Count the free blocks from last_bad to the end of the volume */
- end_free_blocks = 0;
- for (block = last_bad;
- block < PED_BE32_TO_CPU (vh->total_blocks);
- block++) {
- if (!TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- end_free_blocks++;
- }
-
- /* Calculate the block that will by the first free at
- the end of the volume */
- block = PED_BE32_TO_CPU (vh->total_blocks) - end_free_blocks;
-
- return (PedSector) block * ( PED_BE32_TO_CPU (vh->block_size)
- / PED_SECTOR_SIZE_DEFAULT );
-}
-
-/* On error, returns 0 */
-PedSector
-hfsplus_get_min_size (const PedFileSystem *fs)
-{
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
- PedSector min_size;
-
- /* don't need to add anything because every sector
- can be part of allocation blocks in HFS+, and
- the last block _must_ be reserved */
- min_size = hfsplus_get_empty_end(fs);
- if (!min_size) return 0;
-
- if (priv_data->wrapper) {
- HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
- priv_data->wrapper->type_specific;
- unsigned int hfs_sect_block;
- PedSector hgee;
- hfs_sect_block =
- PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
- / PED_SECTOR_SIZE_DEFAULT;
- /*
- * if hfs+ is embedded in an hfs wrapper then the new size is :
- * the new size of the hfs+ volume rounded up to the size
- * of hfs blocks
- * + the minimum size of the hfs wrapper without any hfs+
- * modification
- * - the current size of the hfs+ volume in the hfs wrapper
- */
- hgee = hfs_get_empty_end(priv_data->wrapper);
- if (!hgee) return 0;
- min_size = ((min_size + hfs_sect_block - 1) / hfs_sect_block)
- * hfs_sect_block
- + hgee + 2
- - (PedSector) PED_BE16_TO_CPU ( hfs_priv_data->mdb
- ->old_new.embedded
- .location.block_count )
- * hfs_sect_block;
- }
-
- return min_size;
-}
-
-/* return the block which should be used to pack data to have
- at least free fblock blocks at the end of the volume */
-unsigned int
-hfsplus_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-{
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
- unsigned int block;
-
- for (block = PED_BE32_TO_CPU (priv_data->vh->total_blocks) - 1;
- block && fblock;
- block--) {
- if (!TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- fblock--;
- }
-
- while (block && !TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- block--;
- if (TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
- block++;
-
- return block;
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/advfs_plus.h b/libparted/fs/hfs/advfs_plus.h
deleted file mode 100644
index fdf61c6..0000000
--- a/libparted/fs/hfs/advfs_plus.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ADVFS_PLUS_H
-#define _ADVFS_PLUS_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-int
-hfsplus_btree_search (HfsPPrivateFile* b_tree_file, HfsPPrivateGenericKey* key,
- void *record_out, unsigned int record_size,
- HfsCPrivateLeafRec* record_ref);
-
-void
-hfsplus_free_bad_blocks_list(HfsPPrivateLinkExtent* first);
-
-int
-hfsplus_read_bad_blocks (const PedFileSystem *fs);
-
-int
-hfsplus_is_bad_block (const PedFileSystem *fs, unsigned int fblock);
-
-PedSector
-hfsplus_get_empty_end (const PedFileSystem *fs);
-
-PedSector
-hfsplus_get_min_size (const PedFileSystem *fs);
-
-unsigned int
-hfsplus_find_start_pack (const PedFileSystem *fs, unsigned int fblock);
-
-#endif /* _ADVFS_PLUS_H */
diff --git a/libparted/fs/hfs/cache.c b/libparted/fs/hfs/cache.c
deleted file mode 100644
index 97dcca7..0000000
--- a/libparted/fs/hfs/cache.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#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 "cache.h"
-
-static HfsCPrivateCacheTable*
-hfsc_new_cachetable(unsigned int size)
-{
- HfsCPrivateCacheTable* ret;
-
- ret = (HfsCPrivateCacheTable*) ped_malloc(sizeof(*ret));
- if (!ret) return NULL;
-
- ret->next_cache = NULL;
- ret->table_size = size;
- ret->table_first_free = 0;
-
- ret->table = ped_malloc(sizeof(*ret->table)*size);
- if (!ret->table) { free(ret); return NULL; }
- memset(ret->table, 0, sizeof(*ret->table)*size);
-
- return ret;
-}
-
-HfsCPrivateCache*
-hfsc_new_cache(unsigned int block_number, unsigned int file_number)
-{
- unsigned int cachetable_size, i;
- HfsCPrivateCache* ret;
-
- ret = (HfsCPrivateCache*) ped_malloc(sizeof(*ret));
- if (!ret) return NULL;
- ret->block_number = block_number;
- /* following code avoid integer overflow */
- ret->linked_ref_size = block_number > block_number + ((1<<CR_SHIFT)-1) ?
- ( block_number >> CR_SHIFT ) + 1 :
- ( block_number + ((1<<CR_SHIFT)-1) ) >> CR_SHIFT
- ;
-
- ret->linked_ref = (HfsCPrivateExtent**)
- ped_malloc( sizeof(*ret->linked_ref)
- * ret->linked_ref_size );
- if (!ret->linked_ref) { free(ret); return NULL; }
-
- cachetable_size = file_number + file_number / CR_OVER_DIV + CR_ADD_CST;
- if (cachetable_size < file_number) cachetable_size = (unsigned) -1;
- ret->first_cachetable_size = cachetable_size;
- ret->table_list = hfsc_new_cachetable(cachetable_size);
- if (!ret->table_list) {
- free(ret->linked_ref);
- free(ret);
- return NULL;
- }
- ret->last_table = ret->table_list;
-
- for (i = 0; i < ret->linked_ref_size; ++i)
- ret->linked_ref[i] = NULL;
-
- ret->needed_alloc_size = 0;
-
- return ret;
-}
-
-static void
-hfsc_delete_cachetable(HfsCPrivateCacheTable* list)
-{
- HfsCPrivateCacheTable* next;
-
- while (list) {
- free (list->table);
- next = list->next_cache;
- free (list);
- list = next;
- }
-}
-
-void
-hfsc_delete_cache(HfsCPrivateCache* cache)
-{
- hfsc_delete_cachetable(cache->table_list);
- free(cache->linked_ref);
- free(cache);
-}
-
-HfsCPrivateExtent*
-hfsc_cache_add_extent(HfsCPrivateCache* cache, uint32_t start, uint32_t length,
- uint32_t block, uint16_t offset, uint8_t sbb,
- uint8_t where, uint8_t ref_index)
-{
- HfsCPrivateExtent* ext;
- unsigned int idx = start >> CR_SHIFT;
-
- PED_ASSERT(idx < cache->linked_ref_size);
-
- for (ext = cache->linked_ref[idx];
- ext && start != ext->ext_start;
- ext = ext->next);
-
- if (ext) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Trying to register an extent starting at block "
- "0x%X, but another one already exists at this "
- "position. You should check the file system!"),
- start);
- return NULL;
- }
-
- if ( cache->last_table->table_first_free
- == cache->last_table->table_size ) {
- cache->last_table->next_cache =
- hfsc_new_cachetable( ( cache->first_cachetable_size
- / CR_NEW_ALLOC_DIV )
- + CR_ADD_CST );
- if (!cache->last_table->next_cache)
- return NULL;
- cache->last_table = cache->last_table->next_cache;
- }
-
- ext = cache->last_table->table+(cache->last_table->table_first_free++);
-
- ext->ext_start = start;
- ext->ext_length = length;
- ext->ref_block = block;
- ext->ref_offset = offset;
- ext->sect_by_block = sbb;
- ext->where = where;
- ext->ref_index = ref_index;
-
- ext->next = cache->linked_ref[idx];
- cache->linked_ref[idx] = ext;
-
- cache->needed_alloc_size = cache->needed_alloc_size >
- (unsigned) PED_SECTOR_SIZE_DEFAULT * sbb ?
- cache->needed_alloc_size :
- (unsigned) PED_SECTOR_SIZE_DEFAULT * sbb;
-
- return ext;
-}
-
-HfsCPrivateExtent*
-hfsc_cache_search_extent(HfsCPrivateCache* cache, uint32_t start)
-{
- HfsCPrivateExtent* ret;
- unsigned int idx = start >> CR_SHIFT;
-
- PED_ASSERT(idx < cache->linked_ref_size);
-
- for (ret = cache->linked_ref[idx];
- ret && start != ret->ext_start;
- ret = ret->next);
-
- return ret;
-}
-
-/* Can't fail if extent begining at old_start exists */
-/* Returns 0 if no such extent, or on error */
-HfsCPrivateExtent*
-hfsc_cache_move_extent(HfsCPrivateCache* cache, uint32_t old_start,
- uint32_t new_start)
-{
- HfsCPrivateExtent** ppext;
- HfsCPrivateExtent* pext;
-
- unsigned int idx1 = old_start >> CR_SHIFT;
- unsigned int idx2 = new_start >> CR_SHIFT;
-
- PED_ASSERT(idx1 < cache->linked_ref_size);
- PED_ASSERT(idx2 < cache->linked_ref_size);
-
- for (pext = cache->linked_ref[idx2];
- pext && new_start != pext->ext_start;
- pext = pext->next);
-
- if (pext) {
- ped_exception_throw (
- PED_EXCEPTION_BUG,
- PED_EXCEPTION_CANCEL,
- _("Trying to move an extent from block Ox%X to block "
- "Ox%X, but another one already exists at this "
- "position. This should not happen!"),
- old_start, new_start);
- return NULL;
- }
-
- for (ppext = &(cache->linked_ref[idx1]);
- (*ppext) && old_start != (*ppext)->ext_start;
- ppext = &((*ppext)->next));
-
- if (!(*ppext)) return NULL;
-
- /* removing the extent from the cache */
- pext = *ppext;
- (*ppext) = pext->next;
-
- /* change ext_start and insert the extent again */
- pext->ext_start = new_start;
- pext->next = cache->linked_ref[idx2];
- cache->linked_ref[idx2] = pext;
-
- return pext;
-}
-
-#endif /* DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/cache.h b/libparted/fs/hfs/cache.h
deleted file mode 100644
index e0c73e0..0000000
--- a/libparted/fs/hfs/cache.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CACHE_H
-#define _CACHE_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-/* CR => CACHE REF */
-#define CR_NULL 0 /* reserved */
-#define CR_PRIM_CAT 1
-#define CR_PRIM_EXT 2
-#define CR_PRIM_ATTR 3
-#define CR_PRIM_ALLOC 4
-#define CR_PRIM_START 5
-#define CR_BTREE_CAT 6
-#define CR_BTREE_ATTR 7
-#define CR_BTREE_EXT_0 8
-#define CR_BTREE_EXT_CAT 9
-#define CR_BTREE_EXT_EXT 10 /* should not happen ! */
-#define CR_BTREE_EXT_ATTR 11
-#define CR_BTREE_EXT_ALLOC 12
-#define CR_BTREE_EXT_START 13 /* unneeded in current code */
-#define CR_BTREE_CAT_JIB 14 /* journal info block */
-#define CR_BTREE_CAT_JL 15 /* journal */
-/* 16 -> 31 || high order bit */ /* reserved */
-
-/* tuning */
-#define CR_SHIFT 8 /* number of bits to shift start_block by */
- /* to get the index of the linked list */
-#define CR_OVER_DIV 16 /* alloc a table for (1+1/CR_OVER_DIV) *
- file_number + CR_ADD_CST */
-#define CR_ADD_CST 16
-#define CR_NEW_ALLOC_DIV 4 /* divide the size of the first alloc table
- by this value to allocate next tables */
-
-/* See DOC for an explaination of this structure */
-/* Access read only from outside cache.c */
-struct _HfsCPrivateExtent {
- struct _HfsCPrivateExtent* next;
- uint32_t ext_start;
- uint32_t ext_length;
- uint32_t ref_block;
- uint16_t ref_offset;
- uint8_t sect_by_block;
- unsigned where : 5;
- unsigned ref_index : 3; /* 0 -> 7 */
-};
-typedef struct _HfsCPrivateExtent HfsCPrivateExtent;
-
-/* Internaly used by cache.c for custom memory managment only */
-struct _HfsCPrivateCacheTable {
- struct _HfsCPrivateCacheTable* next_cache;
- HfsCPrivateExtent* table;
- unsigned int table_size;
- unsigned int table_first_free;
- /* first_elemt ? */
-};
-typedef struct _HfsCPrivateCacheTable HfsCPrivateCacheTable;
-
-/* Internaly used by cache.c for custom memory managment
- and cache handling only */
-struct _HfsCPrivateCache {
- HfsCPrivateCacheTable* table_list;
- HfsCPrivateCacheTable* last_table;
- HfsCPrivateExtent** linked_ref;
- unsigned int linked_ref_size;
- unsigned int block_number;
- unsigned int first_cachetable_size;
- unsigned int needed_alloc_size;
-};
-typedef struct _HfsCPrivateCache HfsCPrivateCache;
-
-HfsCPrivateCache*
-hfsc_new_cache(unsigned int block_number, unsigned int file_number);
-
-void
-hfsc_delete_cache(HfsCPrivateCache* cache);
-
-HfsCPrivateExtent*
-hfsc_cache_add_extent(HfsCPrivateCache* cache, uint32_t start, uint32_t length,
- uint32_t block, uint16_t offset, uint8_t sbb,
- uint8_t where, uint8_t index);
-
-HfsCPrivateExtent*
-hfsc_cache_search_extent(HfsCPrivateCache* cache, uint32_t start);
-
-HfsCPrivateExtent*
-hfsc_cache_move_extent(HfsCPrivateCache* cache, uint32_t old_start,
- uint32_t new_start);
-
-static __inline__ unsigned int
-hfsc_cache_needed_buffer(HfsCPrivateCache* cache)
-{
- return cache->needed_alloc_size;
-}
-
-#endif /* _CACHE_H */
diff --git a/libparted/fs/hfs/file.c b/libparted/fs/hfs/file.c
deleted file mode 100644
index 9fc501b..0000000
--- a/libparted/fs/hfs/file.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#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 "advfs.h"
-
-#include "file.h"
-
-/* Open the data fork of a file with its first three extents and its CNID */
-HfsPrivateFile*
-hfs_file_open (PedFileSystem *fs, uint32_t CNID,
- HfsExtDataRec ext_desc, PedSector sect_nb)
-{
- HfsPrivateFile* file;
-
- file = (HfsPrivateFile*) ped_malloc (sizeof (HfsPrivateFile));
- if (!file) return NULL;
-
- file->fs = fs;
- file->sect_nb = sect_nb;
- file->CNID = CNID;
- memcpy(file->first, ext_desc, sizeof (HfsExtDataRec));
- file->start_cache = 0;
-
- return file;
-}
-
-/* Close an HFS file */
-void
-hfs_file_close (HfsPrivateFile* file)
-{
- free (file);
-}
-
-/* warning : only works on data forks */
-static int
-hfs_get_extent_containing (HfsPrivateFile* file, unsigned int block,
- HfsExtDataRec cache, uint16_t* ptr_start_cache)
-{
- uint8_t record[sizeof (HfsExtentKey)
- + sizeof (HfsExtDataRec)];
- HfsExtentKey search;
- HfsExtentKey* ret_key = (HfsExtentKey*) record;
- HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
- (record + sizeof (HfsExtentKey));
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- file->fs->type_specific;
-
- search.key_length = sizeof (HfsExtentKey) - 1;
- search.type = HFS_DATA_FORK;
- search.file_ID = file->CNID;
- search.start = PED_CPU_TO_BE16 (block);
-
- if (!hfs_btree_search (priv_data->extent_file,
- (HfsPrivateGenericKey*) &search,
- record, sizeof (record), NULL))
- return 0;
-
- if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
- return 0;
-
- memcpy (cache, ret_cache, sizeof(HfsExtDataRec));
- *ptr_start_cache = PED_BE16_TO_CPU (ret_key->start);
-
- return 1;
-}
-
-/* find and return the nth sector of a file */
-/* return 0 on error */
-static PedSector
-hfs_file_find_sector (HfsPrivateFile* file, PedSector sector)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- file->fs->type_specific;
- unsigned int sect_by_block = PED_BE32_TO_CPU (
- priv_data->mdb->block_size)
- / PED_SECTOR_SIZE_DEFAULT;
- unsigned int i, s, vol_block;
- unsigned int block = sector / sect_by_block;
- unsigned int offset = sector % sect_by_block;
-
- /* in the three first extent */
- for (s = 0, i = 0; i < HFS_EXT_NB; i++) {
- if ((block >= s) && ( block < s + PED_BE16_TO_CPU (
- file->first[i].block_count))) {
- vol_block = (block - s) + PED_BE16_TO_CPU (
- file->first[i].start_block);
- goto sector_found;
- }
- s += PED_BE16_TO_CPU (file->first[i].block_count);
- }
-
- /* in the three cached extent */
- if (file->start_cache && block >= file->start_cache)
- for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++) {
- if ((block >= s) && (block < s + PED_BE16_TO_CPU (
- file->cache[i].block_count))) {
- vol_block = (block - s) + PED_BE16_TO_CPU (
- file->cache[i].start_block);
- goto sector_found;
- }
- s += PED_BE16_TO_CPU (file->cache[i].block_count);
- }
-
- /* update cache */
- if (!hfs_get_extent_containing (file, block, file->cache,
- &(file->start_cache))) {
- ped_exception_throw (
- PED_EXCEPTION_WARNING,
- PED_EXCEPTION_CANCEL,
- _("Could not update the extent cache for HFS file with "
- "CNID %X."),
- PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
-
- /* in the three cached extent */
- PED_ASSERT(file->start_cache && block >= file->start_cache);
- for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++) {
- if ((block >= s) && (block < s + PED_BE16_TO_CPU (
- file->cache[i].block_count))) {
- vol_block = (block - s) + PED_BE16_TO_CPU (
- file->cache[i].start_block);
- goto sector_found;
- }
- s += PED_BE16_TO_CPU (file->cache[i].block_count);
- }
-
- return 0;
-
- sector_found:
- return (PedSector) PED_BE16_TO_CPU (priv_data->mdb->start_block)
- + (PedSector) vol_block * sect_by_block
- + offset;
-}
-
-/* Read the nth sector of a file */
-/* return 0 on error */
-int
-hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-{
- PedSector abs_sector;
-
- if (sector >= file->sect_nb) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Trying to read HFS file with CNID %X behind EOF."),
- PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
-
- abs_sector = hfs_file_find_sector (file, sector);
- if (!abs_sector) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Could not find sector %lli of HFS file with "
- "CNID %X."),
- sector, PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
-
- return ped_geometry_read (file->fs->geom, buf, abs_sector, 1);
-}
-
-/* Write the nth sector of a file */
-/* return 0 on error */
-int
-hfs_file_write_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-{
- PedSector abs_sector;
-
- if (sector >= file->sect_nb) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Trying to write HFS file with CNID %X behind EOF."),
- PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
-
- abs_sector = hfs_file_find_sector (file, sector);
- if (!abs_sector) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Could not find sector %lli of HFS file with "
- "CNID %X."),
- sector, PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
-
- return ped_geometry_write (file->fs->geom, buf, abs_sector, 1);
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/file.h b/libparted/fs/hfs/file.h
deleted file mode 100644
index a16f835..0000000
--- a/libparted/fs/hfs/file.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _FILE_H
-#define _FILE_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-HfsPrivateFile*
-hfs_file_open (PedFileSystem *fs, uint32_t CNID,
- HfsExtDataRec ext_desc, PedSector sect_nb);
-
-void
-hfs_file_close (HfsPrivateFile* file);
-
-int
-hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector);
-
-int
-hfs_file_write_sector (HfsPrivateFile* file, void *buf, PedSector sector);
-
-#endif /* _FILE_H */
diff --git a/libparted/fs/hfs/file_plus.c b/libparted/fs/hfs/file_plus.c
deleted file mode 100644
index acacc93..0000000
--- a/libparted/fs/hfs/file_plus.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#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 "advfs_plus.h"
-
-#include "file_plus.h"
-
-/* Open the data fork of a file with its first eight extents and its CNID */
-/* CNID and ext_desc must be in disc order, sect_nb in CPU order */
-/* return null on failure */
-HfsPPrivateFile*
-hfsplus_file_open (PedFileSystem *fs, HfsPNodeID CNID,
- HfsPExtDataRec ext_desc, PedSector sect_nb)
-{
- HfsPPrivateFile* file;
-
- file = (HfsPPrivateFile*) ped_malloc (sizeof (HfsPPrivateFile));
- if (!file) return NULL;
-
- file->fs = fs;
- file->sect_nb = sect_nb;
- file->CNID = CNID;
- memcpy(file->first, ext_desc, sizeof (HfsPExtDataRec));
- file->start_cache = 0;
-
- return file;
-}
-
-/* Close an HFS+ file */
-void
-hfsplus_file_close (HfsPPrivateFile* file)
-{
- free (file);
-}
-
-/* warning : only works on data forks */
-static int
-hfsplus_get_extent_containing (HfsPPrivateFile* file, unsigned int block,
- HfsPExtDataRec cache, uint32_t* ptr_start_cache)
-{
- uint8_t record[sizeof (HfsPExtentKey)
- + sizeof (HfsPExtDataRec)];
- HfsPExtentKey search;
- HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
- HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
- (record + sizeof (HfsPExtentKey));
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- file->fs->type_specific;
-
- search.key_length = PED_CPU_TO_BE16 (sizeof (HfsPExtentKey) - 2);
- search.type = HFS_DATA_FORK;
- search.pad = 0;
- search.file_ID = file->CNID;
- search.start = PED_CPU_TO_BE32 (block);
-
- if (!hfsplus_btree_search (priv_data->extents_file,
- (HfsPPrivateGenericKey*) &search,
- record, sizeof (record), NULL))
- return 0;
-
- if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
- return 0;
-
- memcpy (cache, ret_cache, sizeof(HfsPExtDataRec));
- *ptr_start_cache = PED_BE32_TO_CPU (ret_key->start);
-
- return 1;
-}
-
-/* find a sub extent contained in the desired area */
-/* and with the same starting point */
-/* return 0 in sector_count on error, or the physical area */
-/* on the volume corresponding to the logical area in the file */
-static HfsPPrivateExtent
-hfsplus_file_find_extent (HfsPPrivateFile* file, PedSector sector,
- unsigned int nb)
-{
- HfsPPrivateExtent ret = {0,0};
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- file->fs->type_specific;
- unsigned int sect_by_block = PED_BE32_TO_CPU (
- priv_data->vh->block_size)
- / PED_SECTOR_SIZE_DEFAULT;
- unsigned int i, s, vol_block, size;
- PedSector sect_size;
- unsigned int block = sector / sect_by_block;
- unsigned int offset = sector % sect_by_block;
-
- /* in the 8 first extent */
- for (s = 0, i = 0; i < HFSP_EXT_NB; i++) {
- if ((block >= s) && (block < s + PED_BE32_TO_CPU (
- file->first[i].block_count))) {
- vol_block = (block - s)
- + PED_BE32_TO_CPU (file->first[i]
- .start_block);
- size = PED_BE32_TO_CPU (file->first[i].block_count)
- + s - block;
- goto plus_sector_found;
- }
- s += PED_BE32_TO_CPU (file->first[i].block_count);
- }
-
- /* in the 8 cached extent */
- if (file->start_cache && block >= file->start_cache)
- for (s = file->start_cache, i = 0; i < HFSP_EXT_NB; i++) {
- if ((block >= s) && (block < s + PED_BE32_TO_CPU (
- file->cache[i].block_count))) {
- vol_block = (block - s)
- + PED_BE32_TO_CPU (file->cache[i]
- .start_block);
- size = PED_BE32_TO_CPU (file->cache[i].block_count)
- + s - block;
- goto plus_sector_found;
- }
- s += PED_BE32_TO_CPU (file->cache[i].block_count);
- }
-
- /* update cache */
- if (!hfsplus_get_extent_containing (file, block, file->cache,
- &(file->start_cache))) {
- ped_exception_throw (
- PED_EXCEPTION_WARNING,
- PED_EXCEPTION_CANCEL,
- _("Could not update the extent cache for HFS+ file "
- "with CNID %X."),
- PED_BE32_TO_CPU(file->CNID));
- return ret; /* ret == {0,0} */
- }
-
- /* ret == {0,0} */
- PED_ASSERT(file->start_cache && block >= file->start_cache);
-
- for (s = file->start_cache, i = 0; i < HFSP_EXT_NB; i++) {
- if ((block >= s) && (block < s + PED_BE32_TO_CPU (
- file->cache[i].block_count))) {
- vol_block = (block - s)
- + PED_BE32_TO_CPU (file->cache[i]
- .start_block);
- size = PED_BE32_TO_CPU (file->cache[i].block_count)
- + s - block;
- goto plus_sector_found;
- }
- s += PED_BE32_TO_CPU (file->cache[i].block_count);
- }
-
- return ret;
-
-plus_sector_found:
- sect_size = (PedSector) size * sect_by_block - offset;
- ret.start_sector = vol_block * sect_by_block + offset;
- ret.sector_count = (sect_size < nb) ? sect_size : nb;
- return ret;
-}
-
-int
-hfsplus_file_read(HfsPPrivateFile* file, void *buf, PedSector sector,
- unsigned int nb)
-{
- HfsPPrivateExtent phy_area;
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- file->fs->type_specific;
- char *b = buf;
-
- if (sector+nb < sector /* detect overflow */
- || sector+nb > file->sect_nb) /* out of file */ {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Trying to read HFS+ file with CNID %X behind EOF."),
- PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
-
- while (nb) {
- phy_area = hfsplus_file_find_extent(file, sector, nb);
- if (phy_area.sector_count == 0) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Could not find sector %lli of HFS+ file "
- "with CNID %X."),
- sector, PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
- if (!ped_geometry_read(priv_data->plus_geom, b,
- phy_area.start_sector,
- phy_area.sector_count))
- return 0;
-
- nb -= phy_area.sector_count; /* < nb anyway ... */
- sector += phy_area.sector_count;
- b += phy_area.sector_count * PED_SECTOR_SIZE_DEFAULT;
- }
-
- return 1;
-}
-
-int
-hfsplus_file_write(HfsPPrivateFile* file, void *buf, PedSector sector,
- unsigned int nb)
-{
- HfsPPrivateExtent phy_area;
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- file->fs->type_specific;
- char *b = buf;
-
- if (sector+nb < sector /* detect overflow */
- || sector+nb > file->sect_nb) /* out of file */ {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Trying to write HFS+ file with CNID %X behind EOF."),
- PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
-
- while (nb) {
- phy_area = hfsplus_file_find_extent(file, sector, nb);
- if (phy_area.sector_count == 0) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Could not find sector %lli of HFS+ file "
- "with CNID %X."),
- sector, PED_BE32_TO_CPU(file->CNID));
- return 0;
- }
- if (!ped_geometry_write(priv_data->plus_geom, b,
- phy_area.start_sector,
- phy_area.sector_count))
- return 0;
-
- nb -= phy_area.sector_count; /* < nb anyway ... */
- sector += phy_area.sector_count;
- b += phy_area.sector_count * PED_SECTOR_SIZE_DEFAULT;
- }
-
- return 1;
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/file_plus.h b/libparted/fs/hfs/file_plus.h
deleted file mode 100644
index e2dcbd2..0000000
--- a/libparted/fs/hfs/file_plus.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _FILE_PLUS_H
-#define _FILE_PLUS_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-HfsPPrivateFile*
-hfsplus_file_open (PedFileSystem *fs, HfsPNodeID CNID,
- HfsPExtDataRec ext_desc, PedSector sect_nb);
-
-void
-hfsplus_file_close (HfsPPrivateFile* file);
-
-int
-hfsplus_file_read(HfsPPrivateFile* file, void *buf,
- PedSector sector, unsigned int nb);
-
-int
-hfsplus_file_write(HfsPPrivateFile* file, void *buf,
- PedSector sector, unsigned int nb);
-
-/* Read the nth sector of a file */
-/* return 0 on error */
-static __inline__ int
-hfsplus_file_read_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-{
- return hfsplus_file_read(file, buf, sector, 1);
-}
-
-/* Write the nth sector of a file */
-/* return 0 on error */
-static __inline__ int
-hfsplus_file_write_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-{
- return hfsplus_file_write(file, buf, sector, 1);
-}
-
-
-#endif /* _FILE_PLUS_H */
diff --git a/libparted/fs/hfs/hfs.c b/libparted/fs/hfs/hfs.c
index a2d4d07..275bc24 100644
--- a/libparted/fs/hfs/hfs.c
+++ b/libparted/fs/hfs/hfs.c
@@ -48,1179 +48,6 @@ unsigned hfsp_block_count;
#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: free(priv_data);
-ho_mdb: free(mdb);
-ho_fs: 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);
- free (priv_data->mdb);
- free (priv_data);
- ped_geometry_destroy (fs->geom);
- 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);
- 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);
-}
-
-/* ----- 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);
- free(priv_data->alloc_map);
- 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);
- free(priv_data->vh);
- free(priv_data);
- 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: free(priv_data->alloc_map);
-hpo_dm: 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: free(priv_data);
-hpo_vh: free(vh);
-hpo_fs: 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);
- 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;
-}
-
-#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);
-
- 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;
- }
-
- 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,
};
diff --git a/libparted/fs/hfs/journal.c b/libparted/fs/hfs/journal.c
deleted file mode 100644
index 6e5c267..0000000
--- a/libparted/fs/hfs/journal.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#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 "reloc_plus.h"
-
-#include "journal.h"
-
-static int hfsj_vh_replayed = 0;
-static int is_le = 0;
-
-static uint32_t
-hfsj_calc_checksum(uint8_t *ptr, int len)
-{
- int i;
- uint32_t cksum=0;
-
- for (i=0; i < len; i++, ptr++) {
- cksum = (cksum << 8) ^ (cksum + *ptr);
- }
-
- return (~cksum);
-}
-
-int
-hfsj_update_jib(PedFileSystem* fs, uint32_t block)
-{
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
-
- priv_data->vh->journal_info_block = PED_CPU_TO_BE32(block);
-
- if (!hfsplus_update_vh (fs))
- return 0;
-
- priv_data->jib_start_block = block;
- return 1;
-}
-
-int
-hfsj_update_jl(PedFileSystem* fs, uint32_t block)
-{
- uint8_t buf[PED_SECTOR_SIZE_DEFAULT];
- PedSector sector;
- uint64_t offset;
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
- HfsJJournalInfoBlock* jib;
- int binsect;
-
- binsect = HFS_32_TO_CPU(priv_data->vh->block_size, is_le) / PED_SECTOR_SIZE_DEFAULT;
- sector = (PedSector) priv_data->jib_start_block * binsect;
- if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
- return 0;
- jib = (HfsJJournalInfoBlock*) buf;
-
- offset = (uint64_t)block * PED_SECTOR_SIZE_DEFAULT * binsect;
- jib->offset = HFS_CPU_TO_64(offset, is_le);
-
- if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
- || !ped_geometry_sync(priv_data->plus_geom))
- return 0;
-
- priv_data->jl_start_block = block;
- return 1;
-}
-
-/* Return the sector in the journal that is after the area read */
-/* or 0 on error */
-static PedSector
-hfsj_journal_read(PedGeometry* geom, HfsJJournalHeader* jh,
- PedSector journ_sect, PedSector journ_length,
- PedSector read_sect, unsigned int nb_sect,
- void* buf)
-{
- int r;
-
- while (nb_sect--) {
- r = ped_geometry_read(geom, buf, journ_sect + read_sect, 1);
- if (!r) return 0;
-
- buf = ((uint8_t*)buf) + PED_SECTOR_SIZE_DEFAULT;
- read_sect++;
- if (read_sect == journ_length)
- read_sect = 1; /* skip journal header
- which is asserted to be
- 1 sector long */
- }
-
- return read_sect;
-}
-
-static int
-hfsj_replay_transaction(PedFileSystem* fs, HfsJJournalHeader* jh,
- PedSector jsector, PedSector jlength)
-{
- PedSector start, sector;
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
- HfsJBlockListHeader* blhdr;
- uint8_t* block;
- unsigned int blhdr_nbsect;
- int i, r;
- uint32_t cksum, size;
-
- blhdr_nbsect = HFS_32_TO_CPU(jh->blhdr_size, is_le) / PED_SECTOR_SIZE_DEFAULT;
- blhdr = (HfsJBlockListHeader*)
- ped_malloc (blhdr_nbsect * PED_SECTOR_SIZE_DEFAULT);
- if (!blhdr) return 0;
-
- start = HFS_64_TO_CPU(jh->start, is_le) / PED_SECTOR_SIZE_DEFAULT;
- do {
- start = hfsj_journal_read(priv_data->plus_geom, jh, jsector,
- jlength, start, blhdr_nbsect, blhdr);
- if (!start) goto err_replay;
-
- cksum = HFS_32_TO_CPU(blhdr->checksum, is_le);
- blhdr->checksum = 0;
- if (cksum!=hfsj_calc_checksum((uint8_t*)blhdr, sizeof(*blhdr))){
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Bad block list header checksum."));
- goto err_replay;
- }
- blhdr->checksum = HFS_CPU_TO_32(cksum, is_le);
-
- for (i=1; i < HFS_16_TO_CPU(blhdr->num_blocks, is_le); ++i) {
- size = HFS_32_TO_CPU(blhdr->binfo[i].bsize, is_le);
- sector = HFS_64_TO_CPU(blhdr->binfo[i].bnum, is_le);
- if (!size) continue;
- if (size % PED_SECTOR_SIZE_DEFAULT) {
- ped_exception_throw(
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Invalid size of a transaction "
- "block while replaying the journal "
- "(%i bytes)."),
- size);
- goto err_replay;
- }
- block = (uint8_t*) ped_malloc(size);
- if (!block) goto err_replay;
- start = hfsj_journal_read(priv_data->plus_geom, jh,
- jsector, jlength, start,
- size / PED_SECTOR_SIZE_DEFAULT,
- block);
- if (!start) {
- free (block);
- goto err_replay;
- }
- /* the sector stored in the journal seems to be
- relative to the begin of the block device which
- contains the hfs+ journaled volume */
- if (sector != ~0LL)
- r = ped_geometry_write (fs->geom, block, sector,
- size / PED_SECTOR_SIZE_DEFAULT);
- else
- r = 1;
- free (block);
- /* check if wrapper mdb or vh with no wrapper has
- changed */
- if ( (sector != ~0LL)
- && (2 >= sector)
- && (2 < sector + size / PED_SECTOR_SIZE_DEFAULT) )
- hfsj_vh_replayed = 1;
- /* check if vh of embedded hfs+ has changed */
- if ( (sector != ~0LL)
- && (priv_data->plus_geom != fs->geom)
- && (sector
- + fs->geom->start
- - priv_data->plus_geom->start <= 2)
- && (sector
- + size / PED_SECTOR_SIZE_DEFAULT
- + fs->geom->start
- - priv_data->plus_geom->start > 2) )
- hfsj_vh_replayed = 1;
- if (!r) goto err_replay;
- }
- } while (blhdr->binfo[0].next);
-
- jh->start = HFS_CPU_TO_64(start * PED_SECTOR_SIZE_DEFAULT, is_le);
-
- free (blhdr);
- return (ped_geometry_sync (fs->geom));
-
-err_replay:
- free (blhdr);
- return 0;
-}
-
-/* 0 => Failure, don't continue to open ! */
-/* 1 => Success, the journal has been completly replayed, or don't need to */
-int
-hfsj_replay_journal(PedFileSystem* fs)
-{
- uint8_t buf[PED_SECTOR_SIZE_DEFAULT];
- PedSector sector, length;
- HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
- fs->type_specific;
- HfsJJournalInfoBlock* jib;
- HfsJJournalHeader* jh;
- int binsect;
- uint32_t cksum;
-
- binsect = PED_BE32_TO_CPU(priv_data->vh->block_size) / PED_SECTOR_SIZE_DEFAULT;
- priv_data->jib_start_block =
- PED_BE32_TO_CPU(priv_data->vh->journal_info_block);
- sector = (PedSector) priv_data->jib_start_block * binsect;
- if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
- return 0;
- jib = (HfsJJournalInfoBlock*) buf;
-
- if ( (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
- && !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
- priv_data->jl_start_block = HFS_64_TO_CPU(jib->offset, is_le)
- / ( PED_SECTOR_SIZE_DEFAULT * binsect );
- }
-
- if (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_NEED_INIT))
- return 1;
-
- if ( !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
- || (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
- ped_exception_throw (
- PED_EXCEPTION_NO_FEATURE,
- PED_EXCEPTION_CANCEL,
- _("Journal stored outside of the volume are "
- "not supported. Try to desactivate the "
- "journal and run Parted again."));
- return 0;
- }
-
- if ( (PED_BE64_TO_CPU(jib->offset) % PED_SECTOR_SIZE_DEFAULT)
- || (PED_BE64_TO_CPU(jib->size) % PED_SECTOR_SIZE_DEFAULT) ) {
- ped_exception_throw (
- PED_EXCEPTION_NO_FEATURE,
- PED_EXCEPTION_CANCEL,
- _("Journal offset or size is not multiple of "
- "the sector size."));
- return 0;
- }
-
- sector = PED_BE64_TO_CPU(jib->offset) / PED_SECTOR_SIZE_DEFAULT;
- length = PED_BE64_TO_CPU(jib->size) / PED_SECTOR_SIZE_DEFAULT;
-
- jib = NULL;
- if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
- return 0;
- jh = (HfsJJournalHeader*) buf;
-
- if (jh->endian == PED_LE32_TO_CPU(HFSJ_ENDIAN_MAGIC))
- is_le = 1;
-
- if ( (jh->magic != HFS_32_TO_CPU(HFSJ_HEADER_MAGIC, is_le))
- || (jh->endian != HFS_32_TO_CPU(HFSJ_ENDIAN_MAGIC, is_le)) ) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Incorrect magic values in the journal header."));
- return 0;
- }
-
- if ( (HFS_64_TO_CPU(jh->size, is_le)%PED_SECTOR_SIZE_DEFAULT)
- || (HFS_64_TO_CPU(jh->size, is_le)/PED_SECTOR_SIZE_DEFAULT
- != (uint64_t)length) ) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Journal size mismatch between journal info block "
- "and journal header."));
- return 0;
- }
-
- if ( (HFS_64_TO_CPU(jh->start, is_le) % PED_SECTOR_SIZE_DEFAULT)
- || (HFS_64_TO_CPU(jh->end, is_le) % PED_SECTOR_SIZE_DEFAULT)
- || (HFS_32_TO_CPU(jh->blhdr_size, is_le) % PED_SECTOR_SIZE_DEFAULT)
- || (HFS_32_TO_CPU(jh->jhdr_size, is_le) % PED_SECTOR_SIZE_DEFAULT) ) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Some header fields are not multiple of the sector "
- "size."));
- return 0;
- }
-
- if (HFS_32_TO_CPU(jh->jhdr_size, is_le) != PED_SECTOR_SIZE_DEFAULT) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("The sector size stored in the journal is not 512 "
- "bytes. Parted only supports 512 bytes length "
- "sectors."));
- return 0;
- }
-
- cksum = HFS_32_TO_CPU(jh->checksum, is_le);
- jh->checksum = 0;
- if (cksum != hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh))) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Bad journal checksum."));
- return 0;
- }
- jh->checksum = HFS_CPU_TO_32(cksum, is_le);
-
- /* The 2 following test are in the XNU Darwin source code */
- /* so I assume they're needed */
- if (jh->start == jh->size)
- jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);
- if (jh->end == jh->size)
- jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);
-
- if (jh->start == jh->end)
- return 1;
-
- if (ped_exception_throw (
- PED_EXCEPTION_WARNING,
- PED_EXCEPTION_FIX | PED_EXCEPTION_CANCEL,
- _("The journal is not empty. Parted must replay the "
- "transactions before opening the file system. This will "
- "modify the file system."))
- != PED_EXCEPTION_FIX)
- return 0;
-
- while (jh->start != jh->end) {
- /* Replay one complete transaction */
- if (!hfsj_replay_transaction(fs, jh, sector, length))
- return 0;
-
- /* Recalculate cksum of the journal header */
- jh->checksum = 0; /* need to be 0 while calculating the cksum */
- cksum = hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh));
- jh->checksum = HFS_CPU_TO_32(cksum, is_le);
-
- /* Update the Journal Header */
- if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
- || !ped_geometry_sync(priv_data->plus_geom))
- return 0;
- }
-
- if (hfsj_vh_replayed) {
- /* probe could have reported incorrect info ! */
- /* is there a way to ask parted to quit ? */
- ped_exception_throw(
- PED_EXCEPTION_WARNING,
- PED_EXCEPTION_OK,
- _("The volume header or the master directory block has "
- "changed while replaying the journal. You should "
- "restart Parted."));
- return 0;
- }
-
- return 1;
-}
-
-#endif /* DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/journal.h b/libparted/fs/hfs/journal.h
deleted file mode 100644
index 4a40e02..0000000
--- a/libparted/fs/hfs/journal.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _JOURNAL_H
-#define _JOURNAL_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-int
-hfsj_replay_journal(PedFileSystem* fs);
-
-int
-hfsj_update_jib(PedFileSystem* fs, uint32_t block);
-
-int
-hfsj_update_jl(PedFileSystem* fs, uint32_t block);
-
-#define HFS_16_TO_CPU(x, is_little_endian) ((is_little_endian) ? (uint16_t)PED_LE16_TO_CPU(x) : (uint16_t)PED_BE16_TO_CPU(x))
-#define HFS_32_TO_CPU(x, is_little_endian) ((is_little_endian) ? (uint32_t)PED_LE32_TO_CPU(x) : (uint32_t)PED_BE32_TO_CPU(x))
-#define HFS_64_TO_CPU(x, is_little_endian) ((is_little_endian) ? (uint64_t)PED_LE64_TO_CPU(x) : (uint64_t)PED_BE64_TO_CPU(x))
-#define HFS_CPU_TO_16(x, is_little_endian) ((is_little_endian) ? (uint16_t)PED_CPU_TO_LE16(x) : (uint16_t)PED_CPU_TO_BE16(x))
-#define HFS_CPU_TO_32(x, is_little_endian) ((is_little_endian) ? (uint32_t)PED_CPU_TO_LE32(x) : (uint32_t)PED_CPU_TO_BE32(x))
-#define HFS_CPU_TO_64(x, is_little_endian) ((is_little_endian) ? (uint64_t)PED_CPU_TO_LE64(x) : (uint64_t)PED_CPU_TO_BE64(x))
-
-#endif /* _JOURNAL_H */
diff --git a/libparted/fs/hfs/reloc.c b/libparted/fs/hfs/reloc.c
deleted file mode 100644
index 81d1057..0000000
--- a/libparted/fs/hfs/reloc.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#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.h"
-#include "advfs.h"
-#include "cache.h"
-
-#include "reloc.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 */
-static int
-hfs_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
- unsigned int *ptr_to_fblock, unsigned int size)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- unsigned int i, ok = 0;
- unsigned int next_to_fblock;
- unsigned int start, stop;
-
- PED_ASSERT (hfs_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_BE16_TO_CPU(priv_data->mdb->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 */
- unsigned int j;
- unsigned int start_block =
- PED_BE16_TO_CPU (priv_data->mdb->start_block );
- unsigned int block_sz =
- (PED_BE32_TO_CPU (priv_data->mdb->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*/) {
- PedSector abs_sector;
- unsigned int ai;
-
- j = size - i; j = (j < hfs_block_count) ?
- j : hfs_block_count ;
-
- abs_sector = start_block
- + (PedSector) (*ptr_fblock + i) * block_sz;
- if (!ped_geometry_read (fs->geom, hfs_block, abs_sector,
- block_sz * j))
- return -1;
-
- abs_sector = start_block
- + (PedSector) (start + i) * block_sz;
- if (!ped_geometry_write (fs->geom,hfs_block,abs_sector,
- block_sz * j))
- return -1;
-
- for (ai = i+j; i < ai; i++) {
- /* free source block */
- CLR_BLOC_OCCUPATION(priv_data->alloc_map,
- *ptr_fblock + i);
-
- /* set dest block */
- SET_BLOC_OCCUPATION(priv_data->alloc_map,
- start + i);
- }
- }
- if (!ped_geometry_sync_fast (fs->geom))
- return -1;
-
- *ptr_fblock += size;
- *ptr_to_fblock = next_to_fblock;
- } else {
- if (*ptr_fblock != *ptr_to_fblock)
- /* not enough room, but try to continue */
- 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;
-}
-
-/* Update MDB */
-/* Return 0 if an error occurred */
-/* Return 1 if everything ok */
-int
-hfs_update_mdb (PedFileSystem *fs)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- uint8_t node[PED_SECTOR_SIZE_DEFAULT];
-
- if (!ped_geometry_read (fs->geom, node, 2, 1))
- return 0;
- memcpy (node, priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
- if ( !ped_geometry_write (fs->geom, node, 2, 1)
- || !ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1)
- || !ped_geometry_sync_fast (fs->geom))
- return 0;
- return 1;
-}
-
-/* Generic relocator */
-/* replace previous hfs_do_move_* */
-static int
-hfs_do_move (PedFileSystem* fs, unsigned int *ptr_src,
- unsigned int *ptr_dest, HfsCPrivateCache* cache,
- HfsCPrivateExtent* ref)
-{
- uint8_t node[PED_SECTOR_SIZE_DEFAULT];
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- HfsPrivateFile* file;
- HfsExtDescriptor* extent;
- HfsCPrivateExtent* move;
- int new_start;
-
- new_start = hfs_effect_move_extent (fs, ptr_src, ptr_dest,
- ref->ext_length);
- if (new_start == -1) return -1;
-
- if (ref->ext_start != (unsigned) new_start) {
- /* Load, modify & save */
- switch (ref->where) {
- /******** MDB *********/
- case CR_PRIM_CAT :
- priv_data->catalog_file
- ->first[ref->ref_index].start_block =
- PED_CPU_TO_BE16(new_start);
- goto CR_PRIM;
- case CR_PRIM_EXT :
- priv_data->extent_file
- ->first[ref->ref_index].start_block =
- PED_CPU_TO_BE16(new_start);
- CR_PRIM :
- extent = ( HfsExtDescriptor* )
- ( (uint8_t*)priv_data->mdb + ref->ref_offset );
- extent[ref->ref_index].start_block =
- PED_CPU_TO_BE16(new_start);
- if (!hfs_update_mdb(fs)) return -1;
- break;
-
- /********* BTREE *******/
- case CR_BTREE_EXT_CAT :
- if (priv_data->catalog_file
- ->cache[ref->ref_index].start_block
- == PED_CPU_TO_BE16(ref->ext_start))
- priv_data->catalog_file
- ->cache[ref->ref_index].start_block =
- PED_CPU_TO_BE16(new_start);
- case CR_BTREE_EXT_0 :
- file = priv_data->extent_file;
- goto CR_BTREE;
- case CR_BTREE_CAT :
- file = priv_data->catalog_file;
- CR_BTREE:
- PED_ASSERT(ref->sect_by_block == 1
- && ref->ref_offset < PED_SECTOR_SIZE_DEFAULT);
- if (!hfs_file_read_sector(file, node, ref->ref_block))
- return -1;
- extent = ( HfsExtDescriptor* ) (node + ref->ref_offset);
- extent[ref->ref_index].start_block =
- PED_CPU_TO_BE16(new_start);
- if (!hfs_file_write_sector(file, node, ref->ref_block)
- || !ped_geometry_sync_fast (fs->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;
- }
-
- /* Update the cache */
- move = hfsc_cache_move_extent(cache, ref->ext_start, new_start);
- if (!move) return -1; /* "cleanly" fail */
- PED_ASSERT(move == ref); /* generate a bug */
- }
-
- return new_start;
-}
-
-/* 0 error, 1 ok */
-static int
-hfs_save_allocation(PedFileSystem* fs)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- unsigned int map_sectors;
-
- map_sectors = ( PED_BE16_TO_CPU (priv_data->mdb->total_blocks)
- + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
- / (PED_SECTOR_SIZE_DEFAULT * 8);
- return ( ped_geometry_write (fs->geom, priv_data->alloc_map,
- PED_BE16_TO_CPU (priv_data->mdb->volume_bitmap_block),
- map_sectors) );
-}
-
-/* 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 */
-/* Generic search thanks to the file system cache */
-static int
-hfs_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;
-
- /* Reference search powered by the cache... */
- /* This is the optimisation secret :) */
- ref = hfsc_cache_search_extent(cache, *ptr_fblock);
- if (!ref) return 0; /* not found */
-
- old_start = *ptr_fblock;
- new_start = hfs_do_move(fs, ptr_fblock, ptr_to_fblock, cache, ref);
- if (new_start == (unsigned int) -1) return -1;
- if (new_start > old_start) { /* detect 2 pass reloc */
- new_start = hfs_do_move(fs,&new_start,ptr_to_fblock,cache,ref);
- if (new_start == (unsigned int) -1 || new_start > old_start)
- return -1;
- }
-
- /* allocation bitmap save is not atomic with data relocation */
- /* so we only do it a few times, and without syncing */
- /* The unmounted bit protect us anyway */
- hfs_save_allocation(fs);
- return 1;
-}
-
-static int
-hfs_cache_from_mdb(HfsCPrivateCache* cache, PedFileSystem* fs,
- PedTimer* timer)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- HfsExtDescriptor* extent;
- unsigned int j;
-
- extent = priv_data->mdb->extents_file_rec;
- for (j = 0; j < HFS_EXT_NB; ++j) {
- if (!extent[j].block_count) break;
- if (!hfsc_cache_add_extent(
- cache,
- PED_BE16_TO_CPU(extent[j].start_block),
- PED_BE16_TO_CPU(extent[j].block_count),
- 0, /* unused for mdb */
- ((uint8_t*)extent) - ((uint8_t*)priv_data->mdb),
- 1, /* load/save only 1 sector */
- CR_PRIM_EXT,
- j )
- )
- return 0;
- }
-
- extent = priv_data->mdb->catalog_file_rec;
- for (j = 0; j < HFS_EXT_NB; ++j) {
- if (!extent[j].block_count) break;
- if (!hfsc_cache_add_extent(
- cache,
- PED_BE16_TO_CPU(extent[j].start_block),
- PED_BE16_TO_CPU(extent[j].block_count),
- 0,
- ((uint8_t*)extent) - ((uint8_t*)priv_data->mdb),
- 1,
- CR_PRIM_CAT,
- j )
- )
- return 0;
- }
-
- return 1;
-}
-
-static int
-hfs_cache_from_catalog(HfsCPrivateCache* cache, PedFileSystem* fs,
- PedTimer* timer)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- uint8_t node[PED_SECTOR_SIZE_DEFAULT];
- HfsHeaderRecord* header;
- HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
- HfsCatalogKey* catalog_key;
- HfsCatalog* catalog_data;
- HfsExtDescriptor* extent;
- unsigned int leaf_node, record_number;
- unsigned int i, j;
-
- 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;
- }
-
- if (!hfs_file_read_sector (priv_data->catalog_file, node, 0))
- return 0;
- header = (HfsHeaderRecord*)(node + PED_BE16_TO_CPU(*((uint16_t*)
- (node+(PED_SECTOR_SIZE_DEFAULT-2)))));
-
- for (leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
- leaf_node;
- leaf_node = PED_BE32_TO_CPU (desc->next)) {
- if (!hfs_file_read_sector (priv_data->catalog_file,
- node, leaf_node))
- return 0;
- record_number = PED_BE16_TO_CPU (desc->rec_nb);
- for (i = 1; i <= record_number; ++i) {
- /* undocumented alignement */
- unsigned int skip;
- catalog_key = (HfsCatalogKey*) (node + PED_BE16_TO_CPU(
- *((uint16_t*)(node+(PED_SECTOR_SIZE_DEFAULT - 2*i)))));
- skip = (1 + catalog_key->key_length + 1) & ~1;
- catalog_data = (HfsCatalog*)( ((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
- >= PED_SECTOR_SIZE_DEFAULT
- - 2 * (signed)(record_number+1))) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("The file system contains errors."));
- return 0;
- }
-
- if (catalog_data->type != HFS_CAT_FILE) continue;
-
- extent = catalog_data->sel.file.extents_data;
- for (j = 0; j < HFS_EXT_NB; ++j) {
- if (!extent[j].block_count) break;
- if (!hfsc_cache_add_extent(
- cache,
- PED_BE16_TO_CPU(extent[j].start_block),
- PED_BE16_TO_CPU(extent[j].block_count),
- leaf_node,
- (uint8_t*)extent - node,
- 1, /* hfs => btree block = 512 b */
- CR_BTREE_CAT,
- j )
- )
- return 0;
- }
-
- extent = catalog_data->sel.file.extents_res;
- for (j = 0; j < HFS_EXT_NB; ++j) {
- if (!extent[j].block_count) break;
- if (!hfsc_cache_add_extent(
- cache,
- PED_BE16_TO_CPU(extent[j].start_block),
- PED_BE16_TO_CPU(extent[j].block_count),
- leaf_node,
- (uint8_t*)extent - node,
- 1, /* hfs => btree block = 512 b */
- CR_BTREE_CAT,
- j )
- )
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-static int
-hfs_cache_from_extent(HfsCPrivateCache* cache, PedFileSystem* fs,
- PedTimer* timer)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- uint8_t node[PED_SECTOR_SIZE_DEFAULT];
- HfsHeaderRecord* header;
- HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
- HfsExtentKey* extent_key;
- HfsExtDescriptor* extent;
- unsigned int leaf_node, record_number;
- unsigned int i, j;
-
- if (!priv_data->extent_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 (!hfs_file_read_sector (priv_data->extent_file, node, 0))
- return 0;
- header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
- (node+(PED_SECTOR_SIZE_DEFAULT-2))))));
-
- for (leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
- leaf_node;
- leaf_node = PED_BE32_TO_CPU (desc->next)) {
- if (!hfs_file_read_sector (priv_data->extent_file, node,
- leaf_node))
- return 0;
- record_number = PED_BE16_TO_CPU (desc->rec_nb);
- for (i = 1; i <= record_number; i++) {
- uint8_t where;
- extent_key = (HfsExtentKey*)
- (node + PED_BE16_TO_CPU(*((uint16_t *)
- (node+(PED_SECTOR_SIZE_DEFAULT - 2*i)))));
- /* size is cst */
- extent = (HfsExtDescriptor*)(((uint8_t*)extent_key)
- + sizeof (HfsExtentKey));
- /* check for obvious error in FS */
- if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
- || ((uint8_t*)extent - node
- >= PED_SECTOR_SIZE_DEFAULT
- - 2 * (signed)(record_number+1))) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("The file system contains errors."));
- return 0;
- }
-
- 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;
- default :
- where = CR_BTREE_EXT_0;
- break;
- }
-
- for (j = 0; j < HFS_EXT_NB; ++j) {
- if (!extent[j].block_count) break;
- if (!hfsc_cache_add_extent(
- cache,
- PED_BE16_TO_CPU(extent[j].start_block),
- PED_BE16_TO_CPU(extent[j].block_count),
- leaf_node,
- (uint8_t*)extent - node,
- 1, /* hfs => btree block = 512 b */
- where,
- j )
- )
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-/* This function cache every extents start and length stored in any
- fs structure into the adt defined in cache.[ch]
- Returns NULL on failure */
-static HfsCPrivateCache*
-hfs_cache_extents(PedFileSystem *fs, PedTimer* timer)
-{
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- HfsCPrivateCache* ret;
- unsigned int file_number, block_number;
-
- file_number = PED_BE32_TO_CPU(priv_data->mdb->file_count);
- block_number = PED_BE16_TO_CPU(priv_data->mdb->total_blocks);
- ret = hfsc_new_cache(block_number, file_number);
- if (!ret) return NULL;
-
- if (!hfs_cache_from_mdb(ret, fs, timer) ||
- !hfs_cache_from_catalog(ret, fs, timer) ||
- !hfs_cache_from_extent(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
-hfs_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
- PedTimer* timer, unsigned int to_free)
-{
- PedSector bytes_buff;
- HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
- fs->type_specific;
- HfsMasterDirectoryBlock* mdb = priv_data->mdb;
- HfsCPrivateCache* cache;
- unsigned int to_fblock = fblock;
- unsigned int start = fblock;
- unsigned int divisor = PED_BE16_TO_CPU (mdb->total_blocks)
- + 1 - start - to_free;
- int ret;
-
- PED_ASSERT (!hfs_block);
-
- cache = hfs_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->mdb->block_size)
- * (PedSector) BLOCK_MAX_BUFF;
- if (bytes_buff > BYTES_MAX_BUFF) {
- hfs_block_count = BYTES_MAX_BUFF
- / PED_BE32_TO_CPU (priv_data->mdb->block_size);
- if (!hfs_block_count)
- hfs_block_count = 1;
- bytes_buff = (PedSector) hfs_block_count
- * PED_BE32_TO_CPU (priv_data->mdb->block_size);
- } else
- hfs_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);
-
- hfs_block = (uint8_t*) ped_malloc (bytes_buff);
- if (!hfs_block)
- goto error_cache;
-
- if (!hfs_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 < PED_BE16_TO_CPU (mdb->total_blocks)) {
- if (TST_BLOC_OCCUPATION(priv_data->alloc_map,fblock)
- && (!hfs_is_bad_block (fs, fblock))) {
- if (!(ret = hfs_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);
- }
-
- free (hfs_block); hfs_block = NULL; hfs_block_count = 0;
- hfsc_delete_cache (cache);
- return 1;
-
-error_alloc:
- free (hfs_block); hfs_block = NULL; hfs_block_count = 0;
-error_cache:
- hfsc_delete_cache (cache);
- return 0;
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/reloc.h b/libparted/fs/hfs/reloc.h
deleted file mode 100644
index 536c071..0000000
--- a/libparted/fs/hfs/reloc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _RELOC_H
-#define _RELOC_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-int
-hfs_update_mdb (PedFileSystem *fs);
-
-int
-hfs_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
- PedTimer* timer, unsigned int to_free);
-
-#endif /* _RELOC_H */
diff --git a/libparted/fs/hfs/reloc_plus.c b/libparted/fs/hfs/reloc_plus.c
deleted file mode 100644
index 750927f..0000000
--- a/libparted/fs/hfs/reloc_plus.c
+++ /dev/null
@@ -1,942 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004-2005, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#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);
- 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;
-}
-
-/* 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);
- 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;
-}
-
-/* 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;
- 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);
-
- node = (uint8_t*) ped_malloc(bsize);
- if (!node) return 0;
- HfsPNodeDescriptor *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)) {
- 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."));
- 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 )
- ) {
- 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 )
- ) {
- free (node);
- return 0;
- }
- }
- }
- }
-
- 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;
- 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);
-
- node = (uint8_t*) ped_malloc (bsize);
- if (!node) return -1;
- HfsPNodeDescriptor *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)) {
- 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."));
- 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 )
- ) {
- free (node);
- return 0;
- }
- }
- }
- }
-
- 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;
- 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);
-
- node = (uint8_t*) ped_malloc(bsize);
- if (!node) return 0;
- HfsPNodeDescriptor *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)) {
- 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."));
- 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 )
- ) {
- 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 )
- ) {
- free(node);
- return 0;
- }
- }
- } else continue;
- }
- }
-
- 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);
-
- 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);
- }
-
- free (hfsp_block); hfsp_block = NULL; hfsp_block_count = 0;
- hfsc_delete_cache (cache);
- return 1;
-
-error_alloc:
- free (hfsp_block); hfsp_block = NULL; hfsp_block_count = 0;
-error_cache:
- hfsc_delete_cache (cache);
- return 0;
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/hfs/reloc_plus.h b/libparted/fs/hfs/reloc_plus.h
deleted file mode 100644
index 2b2e12c..0000000
--- a/libparted/fs/hfs/reloc_plus.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- libparted - a library for manipulating disk partitions
- Copyright (C) 2004, 2007, 2009-2011 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _RELOC_PLUS_H
-#define _RELOC_PLUS_H
-
-#include <parted/parted.h>
-#include <parted/endian.h>
-#include <parted/debug.h>
-
-#include "hfs.h"
-
-int
-hfsplus_update_vh (PedFileSystem *fs);
-
-int
-hfsplus_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
- PedTimer* timer, unsigned int to_free);
-
-
-#endif /* _RELOC_PLUS_H */