[parted-devel] HFS+ resize support for little-endian systems
Matthew Garrett
mjg59 at srcf.ucam.org
Sat Feb 24 17:36:32 CET 2007
Hi,
The included patch adds support for handling journals on HFS+
filesystems created on little-endian systems. I don't think I've broken
anything, but I have no big-endian systems here to test. I tried to
attach this to a trac report, but got a python traceback starting with a
permission denies error...
diff -ur libparted/fs/hfs.bak/journal.c libparted/fs/hfs/journal.c
--- libparted/fs/hfs.bak/journal.c 2006-05-25 18:28:58.000000000 +0100
+++ libparted/fs/hfs/journal.c 2007-02-12 19:15:04.000000000 +0000
@@ -81,14 +81,14 @@
HfsJJournalInfoBlock* jib;
int binsect;
- binsect = PED_BE32_TO_CPU(priv_data->vh->block_size) / PED_SECTOR_SIZE_DEFAULT;
+ binsect = HFS_32_TO_CPU(priv_data->vh->block_size) / 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 = PED_CPU_TO_BE64(offset);
+ jib->offset = HFS_CPU_TO_64(offset);
if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
|| !ped_geometry_sync(priv_data->plus_geom))
@@ -136,18 +136,18 @@
int i, r;
uint32_t cksum, size;
- blhdr_nbsect = PED_BE32_TO_CPU(jh->blhdr_size) / PED_SECTOR_SIZE_DEFAULT;
+ blhdr_nbsect = HFS_32_TO_CPU(jh->blhdr_size) / PED_SECTOR_SIZE_DEFAULT;
blhdr = (HfsJBlockListHeader*)
ped_malloc (blhdr_nbsect * PED_SECTOR_SIZE_DEFAULT);
if (!blhdr) return 0;
- start = PED_BE64_TO_CPU(jh->start) / PED_SECTOR_SIZE_DEFAULT;
+ start = HFS_64_TO_CPU(jh->start) / 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 = PED_BE32_TO_CPU(blhdr->checksum);
+ cksum = HFS_32_TO_CPU(blhdr->checksum);
blhdr->checksum = 0;
if (cksum!=hfsj_calc_checksum((uint8_t*)blhdr, sizeof(*blhdr))){
ped_exception_throw (
@@ -156,11 +156,11 @@
_("Bad block list header checksum."));
goto err_replay;
}
- blhdr->checksum = PED_CPU_TO_BE32(cksum);
+ blhdr->checksum = HFS_CPU_TO_32(cksum);
- for (i=1; i < PED_BE16_TO_CPU(blhdr->num_blocks); ++i) {
- size = PED_BE32_TO_CPU(blhdr->binfo[i].bsize);
- sector = PED_BE64_TO_CPU(blhdr->binfo[i].bnum);
+ for (i=1; i < HFS_16_TO_CPU(blhdr->num_blocks); ++i) {
+ size = HFS_32_TO_CPU(blhdr->binfo[i].bsize);
+ sector = HFS_64_TO_CPU(blhdr->binfo[i].bnum);
if (!size) continue;
if (size % PED_SECTOR_SIZE_DEFAULT) {
ped_exception_throw(
@@ -212,7 +212,7 @@
}
} while (blhdr->binfo[0].next);
- jh->start = PED_CPU_TO_BE64(start * PED_SECTOR_SIZE_DEFAULT);
+ jh->start = HFS_CPU_TO_64(start * PED_SECTOR_SIZE_DEFAULT);
ped_free (blhdr);
return (ped_geometry_sync (fs->geom));
@@ -246,7 +246,7 @@
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 = PED_BE64_TO_CPU(jib->offset)
+ priv_data->jl_start_block = HFS_64_TO_CPU(jib->offset)
/ ( PED_SECTOR_SIZE_DEFAULT * binsect );
}
@@ -282,17 +282,20 @@
return 0;
jh = (HfsJJournalHeader*) buf;
- if ( (jh->magic != PED_BE32_TO_CPU(HFSJ_HEADER_MAGIC))
- || (jh->endian != PED_BE32_TO_CPU(HFSJ_ENDIAN_MAGIC)) ) {
+ if (jh->endian == PED_LE32_TO_CPU(HFSJ_ENDIAN_MAGIC))
+ little_endian = 1;
+
+ if ( (jh->magic != HFS_32_TO_CPU(HFSJ_HEADER_MAGIC))
+ || (jh->endian != HFS_32_TO_CPU(HFSJ_ENDIAN_MAGIC)) ) {
ped_exception_throw (
PED_EXCEPTION_ERROR,
PED_EXCEPTION_CANCEL,
- _("Incorrect magic values in the journal header."));
+ _("Incorrect magic values in the journal header"));
return 0;
}
- if ( (PED_BE64_TO_CPU(jh->size)%PED_SECTOR_SIZE_DEFAULT)
- || (PED_BE64_TO_CPU(jh->size)/PED_SECTOR_SIZE_DEFAULT != (uint64_t)length) ) {
+ if ( (HFS_64_TO_CPU(jh->size)%PED_SECTOR_SIZE_DEFAULT)
+ || (HFS_64_TO_CPU(jh->size)/PED_SECTOR_SIZE_DEFAULT != (uint64_t)length) ) {
ped_exception_throw (
PED_EXCEPTION_ERROR,
PED_EXCEPTION_CANCEL,
@@ -301,10 +304,10 @@
return 0;
}
- if ( (PED_BE64_TO_CPU(jh->start) % PED_SECTOR_SIZE_DEFAULT)
- || (PED_BE64_TO_CPU(jh->end) % PED_SECTOR_SIZE_DEFAULT)
- || (PED_BE32_TO_CPU(jh->blhdr_size) % PED_SECTOR_SIZE_DEFAULT)
- || (PED_BE32_TO_CPU(jh->jhdr_size) % PED_SECTOR_SIZE_DEFAULT) ) {
+ if ( (HFS_64_TO_CPU(jh->start) % PED_SECTOR_SIZE_DEFAULT)
+ || (HFS_64_TO_CPU(jh->end) % PED_SECTOR_SIZE_DEFAULT)
+ || (HFS_32_TO_CPU(jh->blhdr_size) % PED_SECTOR_SIZE_DEFAULT)
+ || (HFS_32_TO_CPU(jh->jhdr_size) % PED_SECTOR_SIZE_DEFAULT) ) {
ped_exception_throw (
PED_EXCEPTION_ERROR,
PED_EXCEPTION_CANCEL,
@@ -313,7 +316,7 @@
return 0;
}
- if (PED_BE32_TO_CPU(jh->jhdr_size) != PED_SECTOR_SIZE_DEFAULT) {
+ if (HFS_32_TO_CPU(jh->jhdr_size) != PED_SECTOR_SIZE_DEFAULT) {
ped_exception_throw (
PED_EXCEPTION_ERROR,
PED_EXCEPTION_CANCEL,
@@ -323,7 +326,7 @@
return 0;
}
- cksum = PED_BE32_TO_CPU(jh->checksum);
+ cksum = HFS_32_TO_CPU(jh->checksum);
jh->checksum = 0;
if (cksum != hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh))) {
ped_exception_throw (
@@ -332,14 +335,14 @@
_("Bad journal checksum."));
return 0;
}
- jh->checksum = PED_CPU_TO_BE32(cksum);
+ jh->checksum = HFS_CPU_TO_32(cksum);
/* The 2 following test are in the XNU Darwin source code */
/* so I assume they're needed */
if (jh->start == jh->size)
- jh->start = PED_CPU_TO_BE64(PED_SECTOR_SIZE_DEFAULT);
+ jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT);
if (jh->end == jh->size)
- jh->start = PED_CPU_TO_BE64(PED_SECTOR_SIZE_DEFAULT);
+ jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT);
if (jh->start == jh->end)
return 1;
@@ -361,7 +364,7 @@
/* 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 = PED_CPU_TO_BE32(cksum);
+ jh->checksum = HFS_CPU_TO_32(cksum);
/* Update the Journal Header */
if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
Only in libparted/fs/hfs: journal.c~
diff -ur libparted/fs/hfs.bak/journal.h libparted/fs/hfs/journal.h
--- libparted/fs/hfs.bak/journal.h 2006-05-25 18:28:58.000000000 +0100
+++ libparted/fs/hfs/journal.h 2007-02-12 19:14:06.000000000 +0000
@@ -26,6 +26,8 @@
#include "hfs.h"
+static int little_endian = 0;
+
int
hfsj_replay_journal(PedFileSystem* fs);
@@ -35,4 +37,11 @@
int
hfsj_update_jl(PedFileSystem* fs, uint32_t block);
+#define HFS_16_TO_CPU(x) (little_endian ? (uint16_t)PED_LE16_TO_CPU(x) : (uint16_t)PED_BE16_TO_CPU(x))
+#define HFS_32_TO_CPU(x) (little_endian ? (uint32_t)PED_LE32_TO_CPU(x) : (uint32_t)PED_BE32_TO_CPU(x))
+#define HFS_64_TO_CPU(x) (little_endian ? (uint64_t)PED_LE64_TO_CPU(x) : (uint64_t)PED_BE64_TO_CPU(x))
+#define HFS_CPU_TO_16(x) (little_endian ? (uint16_t)PED_CPU_TO_LE16(x) : (uint16_t)PED_CPU_TO_BE16(x))
+#define HFS_CPU_TO_32(x) (little_endian ? (uint32_t)PED_CPU_TO_LE32(x) : (uint32_t)PED_CPU_TO_BE32(x))
+#define HFS_CPU_TO_64(x) (little_endian ? (uint64_t)PED_CPU_TO_LE64(x) : (uint64_t)PED_CPU_TO_BE64(x))
+
#endif /* _JOURNAL_H */
--
Matthew Garrett | mjg59 at srcf.ucam.org
More information about the parted-devel
mailing list