Subject: [PATCH] Fix filesystem detection on non 512 byte sectors

From: Phillip Susi <[email-masked]>
Date: Sat, 29 Mar 2014 13:49:09 -0400

Enable probing for filesystems with non 512 byte sectors, and fix up each
filesystem to correctly handle that.  Remove unused field from the fs type
structure listing acceptable sector sizes.
---
 NEWS                                 |  2 ++
 include/parted/filesys.in.h          |  1 -
 libparted/filesys.c                  |  5 ----
 libparted/fs/amiga/affs.c            | 22 ++--------------
 libparted/fs/amiga/apfs.c            |  6 ++---
 libparted/fs/amiga/asfs.c            |  3 ++-
 libparted/fs/btrfs/btrfs.c           |  1 -
 libparted/fs/ext2/interface.c        | 18 ++++---------
 libparted/fs/fat/bootsector.c        | 50 +++++-------------------------------
 libparted/fs/fat/bootsector.h        |  3 +--
 libparted/fs/fat/fat.c               | 12 ++++-----
 libparted/fs/fat/fat.h               |  4 +--
 libparted/fs/hfs/hfs.c               |  7 -----
 libparted/fs/hfs/probe.c             | 13 ++++++----
 libparted/fs/jfs/jfs.c               | 29 ++++++++-------------
 libparted/fs/linux_swap/linux_swap.c | 41 ++++++-----------------------
 libparted/fs/nilfs2/nilfs2.c         | 36 ++++++++++----------------
 libparted/fs/ntfs/ntfs.c             | 13 ++++------
 libparted/fs/r/fat/bootsector.c      | 32 +++++++++++++----------
 libparted/fs/r/fat/bootsector.h      |  8 +++---
 libparted/fs/r/fat/fat.c             | 29 +++++++++++----------
 libparted/fs/r/fat/fat.h             |  4 +--
 libparted/fs/r/fat/resize.c          |  4 +--
 libparted/fs/r/fat/table.c           |  4 +--
 libparted/fs/reiserfs/reiserfs.c     | 23 +++++++----------
 libparted/fs/ufs/ufs.c               | 27 ++++++++++---------
 libparted/fs/xfs/xfs.c               | 26 ++++++++-----------
 27 files changed, 148 insertions(+), 275 deletions(-)

diff --git a/NEWS b/NEWS
index cdd406e..523fd9e 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ GNU parted NEWS                                    -*- outline -*-
 
 ** Bug Fixes
 
+  Fix filesystem detection on non 512 byte sector sizes
+
   Fix several bugs with loop labels ( whole disk filesystems )
 
   Fix linux partition sync code to flush partitions > 16
diff --git a/include/parted/filesys.in.h b/include/parted/filesys.in.h
index d9f626b..b42d7c9 100644
--- a/include/parted/filesys.in.h
+++ b/include/parted/filesys.in.h
@@ -46,7 +46,6 @@ struct _PedFileSystemOps {
 struct _PedFileSystemType {
 	PedFileSystemType*	next;
 	const char* const	name;		/**< name of the file system type */
-        const int*              block_sizes;
 	PedFileSystemOps* const	ops;
 };
 
diff --git a/libparted/filesys.c b/libparted/filesys.c
index 1870808..1bfe32d 100644
--- a/libparted/filesys.c
+++ b/libparted/filesys.c
@@ -198,11 +198,6 @@ ped_file_system_probe_specific (
 	PED_ASSERT (fs_type->ops->probe != NULL);
 	PED_ASSERT (geom != NULL);
 
-        /* Fail all fs-specific probe-related tests when sector size
-           is not the default.  */
-	if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
-		return 0;
-
 	if (!ped_device_open (geom->dev))
 		return 0;
 	result = fs_type->ops->probe (geom);
diff --git a/libparted/fs/amiga/affs.c b/libparted/fs/amiga/affs.c
index 6b7624d..a97cc54 100644
--- a/libparted/fs/amiga/affs.c
+++ b/libparted/fs/amiga/affs.c
@@ -55,7 +55,8 @@ _generic_affs_probe (PedGeometry* geom, uint32_t kind)
 
 	PED_ASSERT (geom != NULL);
 	PED_ASSERT (geom->dev != NULL);
-
+	if (geom->dev->sector_size != 512)
+		return NULL;
 	/* Finds the blocksize, prealloc and reserved values of the partition block */
 	if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
 		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
@@ -216,97 +217,78 @@ static PedFileSystemOps _amufs5_ops = {
 	probe:		_amufs5_probe,
 };
 
-#define AFFS_BLOCK_SIZES        ((int[5]){512, 1024, 2048, 4096, 0})
-#define AMUFS_BLOCK_SIZES       ((int[2]){512, 0})
-
-
 PedFileSystemType _affs0_type = {
        next:		 NULL,
        ops:		 &_affs0_ops,
        name:		 "affs0",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _affs1_type = {
        next:		 NULL,
        ops:		 &_affs1_ops,
        name:		 "affs1",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _affs2_type = {
        next:		 NULL,
        ops:		 &_affs2_ops,
        name:		 "affs2",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _affs3_type = {
        next:		 NULL,
        ops:		 &_affs3_ops,
        name:		 "affs3",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _affs4_type = {
        next:		 NULL,
        ops:		 &_affs4_ops,
        name:		 "affs4",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _affs5_type = {
        next:		 NULL,
        ops:		 &_affs5_ops,
        name:		 "affs5",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _affs6_type = {
        next:		 NULL,
        ops:		 &_affs6_ops,
        name:		 "affs6",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _affs7_type = {
        next:		 NULL,
        ops:		 &_affs7_ops,
        name:		 "affs7",
-       block_sizes:      AFFS_BLOCK_SIZES
 };
 PedFileSystemType _amufs_type = {
        next:		 NULL,
        ops:		 &_amufs_ops,
        name:		 "amufs",
-       block_sizes:      AMUFS_BLOCK_SIZES
 };
 PedFileSystemType _amufs0_type = {
        next:		 NULL,
        ops:		 &_amufs0_ops,
        name:		 "amufs0",
-       block_sizes:      AMUFS_BLOCK_SIZES
 };
 PedFileSystemType _amufs1_type = {
        next:		 NULL,
        ops:		 &_amufs1_ops,
        name:		 "amufs1",
-       block_sizes:      AMUFS_BLOCK_SIZES
 };
 PedFileSystemType _amufs2_type = {
        next:		 NULL,
        ops:		 &_amufs2_ops,
        name:		 "amufs2",
-       block_sizes:      AMUFS_BLOCK_SIZES
 };
 PedFileSystemType _amufs3_type = {
        next:		 NULL,
        ops:		 &_amufs3_ops,
        name:		 "amufs3",
-       block_sizes:      AMUFS_BLOCK_SIZES
 };
 PedFileSystemType _amufs4_type = {
        next:		 NULL,
        ops:		 &_amufs4_ops,
        name:		 "amufs4",
-       block_sizes:      AMUFS_BLOCK_SIZES
 };
 PedFileSystemType _amufs5_type = {
        next:		 NULL,
        ops:		 &_amufs5_ops,
        name:		 "amufs5",
-       block_sizes:      AMUFS_BLOCK_SIZES
 };
diff --git a/libparted/fs/amiga/apfs.c b/libparted/fs/amiga/apfs.c
index 9f9e6e0..2d2cbe1 100644
--- a/libparted/fs/amiga/apfs.c
+++ b/libparted/fs/amiga/apfs.c
@@ -48,6 +48,8 @@ _generic_apfs_probe (PedGeometry* geom, uint32_t kind)
 
 	PED_ASSERT (geom != NULL);
 	PED_ASSERT (geom->dev != NULL);
+	if (geom->dev->sector_size != 512)
+		return NULL;
 
 	/* Finds the blocksize and reserved values of the partition block */
 	if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
@@ -113,17 +115,13 @@ static PedFileSystemOps _apfs2_ops = {
 	probe:		_apfs2_probe,
 };
 
-#define APFS_BLOCK_SIZES ((int[2]){512, 0})
-
 PedFileSystemType _apfs1_type = {
        next:		 NULL,
        ops:		 &_apfs1_ops,
        name:		 "apfs1",
-       block_sizes:      APFS_BLOCK_SIZES
 };
 PedFileSystemType _apfs2_type = {
        next:		 NULL,
        ops:		 &_apfs2_ops,
        name:		 "apfs2",
-       block_sizes:      APFS_BLOCK_SIZES
 };
diff --git a/libparted/fs/amiga/asfs.c b/libparted/fs/amiga/asfs.c
index f7b4ed0..5824881 100644
--- a/libparted/fs/amiga/asfs.c
+++ b/libparted/fs/amiga/asfs.c
@@ -62,6 +62,8 @@ _asfs_probe (PedGeometry* geom)
 
 	PED_ASSERT (geom != NULL);
 	PED_ASSERT (geom->dev != NULL);
+	if (geom->dev->sector_size != 512)
+		return NULL;
 
 	/* Finds the blocksize of the partition block */
 	if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
@@ -124,5 +126,4 @@ PedFileSystemType _asfs_type = {
        next:		 NULL,
        ops:		 &_asfs_ops,
        name:		 "asfs",
-       block_sizes:      ((int[2]){512, 0})
 };
diff --git a/libparted/fs/btrfs/btrfs.c b/libparted/fs/btrfs/btrfs.c
index e5abed6..8d76f6f 100644
--- a/libparted/fs/btrfs/btrfs.c
+++ b/libparted/fs/btrfs/btrfs.c
@@ -62,7 +62,6 @@ static PedFileSystemType btrfs_type = {
         next:   NULL,
         ops:    &btrfs_ops,
         name:   "btrfs",
-        block_sizes: ((int[2]){512, 0})
 };
 
 void
diff --git a/libparted/fs/ext2/interface.c b/libparted/fs/ext2/interface.c
index 97220b7..ecafb62 100644
--- a/libparted/fs/ext2/interface.c
+++ b/libparted/fs/ext2/interface.c
@@ -33,10 +33,12 @@ struct ext2_dev_handle* ext2_make_dev_handle_from_parted_geometry(PedGeometry* g
 static PedGeometry*
 _ext2_generic_probe (PedGeometry* geom, int expect_ext_ver)
 {
-	void *sb_v;
-	if (!ped_geometry_read_alloc(geom, &sb_v, 2, 2))
+	const int sectors = (4096 + geom->dev->sector_size - 1) /
+			     geom->dev->sector_size;
+	char *sb_v = alloca (sectors * geom->dev->sector_size);
+	if (!ped_geometry_read(geom, sb_v, 0, sectors))
 		return NULL;
-	struct ext2_super_block *sb = sb_v;
+	struct ext2_super_block *sb = (struct ext2_super_block *)(sb_v + 1024);
 
 	if (EXT2_SUPER_MAGIC(*sb) == EXT2_SUPER_MAGIC_CONST) {
 		PedSector block_size = 1 << (EXT2_SUPER_LOG_BLOCK_SIZE(*sb) + 1);
@@ -66,8 +68,6 @@ _ext2_generic_probe (PedGeometry* geom, int expect_ext_ver)
 			if (is_ext4)
 				is_ext3 = 0;
 		}
-		free (sb);
-
 		if (expect_ext_ver == 2 && (is_ext3 || is_ext4))
 			return NULL;
 		if (expect_ext_ver == 3 && !is_ext3)
@@ -94,9 +94,6 @@ _ext2_generic_probe (PedGeometry* geom, int expect_ext_ver)
 						 block_count * block_size);
 		}
 	}
-        else {
-		free (sb);
-        }
 
 	return NULL;
 }
@@ -131,27 +128,22 @@ static PedFileSystemOps _ext4_ops = {
 	probe:		_ext4_probe,
 };
 
-#define EXT23_BLOCK_SIZES ((int[6]){512, 1024, 2048, 4096, 8192, 0})
-
 static PedFileSystemType _ext2_type = {
        next:		 NULL,
        ops:		 &_ext2_ops,
        name:		 "ext2",
-       block_sizes:      EXT23_BLOCK_SIZES
 };
 
 static PedFileSystemType _ext3_type = {
        next:		 NULL,
        ops:		 &_ext3_ops,
        name:		 "ext3",
-       block_sizes:      EXT23_BLOCK_SIZES
 };
 
 static PedFileSystemType _ext4_type = {
        next:		 NULL,
        ops:		 &_ext4_ops,
        name:		 "ext4",
-       block_sizes:      EXT23_BLOCK_SIZES
 };
 
 void ped_file_system_ext2_init ()
diff --git a/libparted/fs/fat/bootsector.c b/libparted/fs/fat/bootsector.c
index dacc79c..95a8412 100644
--- a/libparted/fs/fat/bootsector.c
+++ b/libparted/fs/fat/bootsector.c
@@ -36,13 +36,14 @@
  * fat_boot_sector_probe_type() to work (or possibly crash on a divide-by-zero)
  */
 int
-fat_boot_sector_read (FatBootSector* bs, const PedGeometry *geom)
+fat_boot_sector_read (FatBootSector** bsp, const PedGeometry *geom)
 {
-	PED_ASSERT (bs != NULL);
+	PED_ASSERT (bsp != NULL);
 	PED_ASSERT (geom != NULL);
 
-	if (!ped_geometry_read (geom, bs, 0, 1))
+	if (!ped_geometry_read_alloc (geom, (void **)bsp, 0, 1))
 		return 0;
+	FatBootSector *bs = *bsp;
 
 	if (PED_LE16_TO_CPU (bs->boot_sign) != 0xAA55) {
 		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
@@ -142,18 +143,6 @@ fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs)
 
 	PED_ASSERT (bs != NULL);
 
-	if (PED_LE16_TO_CPU (bs->sector_size) != 512) {
-		if (ped_exception_throw (
-			PED_EXCEPTION_BUG,
-			PED_EXCEPTION_IGNORE_CANCEL,
-			_("This file system has a logical sector size of %d.  "
-			"GNU Parted is known not to work properly with sector "
-			"sizes other than 512 bytes."),
-			(int) PED_LE16_TO_CPU (bs->sector_size))
-				!= PED_EXCEPTION_IGNORE)
-			return 0;
-	}
-
 	fs_info->logical_sector_size = PED_LE16_TO_CPU (bs->sector_size) / 512;
 
 	fs_info->sectors_per_track = PED_LE16_TO_CPU (bs->secs_track);
@@ -252,10 +241,10 @@ fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs)
 		fs_info->serial_number
 			= PED_LE32_TO_CPU (bs->u.fat32.serial_number);
 		fs_info->info_sector_offset
-		    = PED_LE16_TO_CPU (fs_info->boot_sector.u.fat32.info_sector)
+		    = PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.info_sector)
 			  * fs_info->logical_sector_size;
 		fs_info->boot_sector_backup_offset
-		  = PED_LE16_TO_CPU (fs_info->boot_sector.u.fat32.backup_sector)
+		  = PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.backup_sector)
 			  * fs_info->logical_sector_size;
 		fs_info->root_cluster
 			= PED_LE32_TO_CPU (bs->u.fat32.root_dir_cluster);
@@ -280,30 +269,3 @@ fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs)
 		= fs_info->cluster_size / sizeof (FatDirEntry);
 	return 1;
 }
-
-#ifndef DISCOVER_ONLY
-
-int
-fat_info_sector_read (FatInfoSector* is, const PedFileSystem* fs)
-{
-	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
-	int		status;
-
-	PED_ASSERT (is != NULL);
-
-	if (!ped_geometry_read (fs->geom, is, fs_info->info_sector_offset, 1))
-		return 0;
-
-	if (PED_LE32_TO_CPU (is->signature_2) != FAT32_INFO_MAGIC2) {
-		status = ped_exception_throw (PED_EXCEPTION_WARNING,
-				PED_EXCEPTION_IGNORE_CANCEL,
-				_("The information sector has the wrong "
-				"signature (%x).  Select cancel for now, "
-				"and send in a bug report.  If you're "
-				"desperate, it's probably safe to ignore."),
-				PED_LE32_TO_CPU (is->signature_2));
-		if (status == PED_EXCEPTION_CANCEL) return 0;
-	}
-	return 1;
-}
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/fat/bootsector.h b/libparted/fs/fat/bootsector.h
index 3f84742..449427a 100644
--- a/libparted/fs/fat/bootsector.h
+++ b/libparted/fs/fat/bootsector.h
@@ -116,11 +116,10 @@ struct __attribute__ ((packed)) _FatInfoSector {
         uint16_t	signature_3;	/* should be 0xaa55 */
 };
 
-int fat_boot_sector_read (FatBootSector* bs, const PedGeometry* geom);
+int fat_boot_sector_read (FatBootSector** bs, const PedGeometry* geom);
 FatType fat_boot_sector_probe_type (const FatBootSector* bs,
 				    const PedGeometry* geom);
 int fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs);
 
-int fat_info_sector_read (FatInfoSector* is, const PedFileSystem* fs);
 
 #endif /* PED_FAT_BOOTSECTOR_H */
diff --git a/libparted/fs/fat/fat.c b/libparted/fs/fat/fat.c
index 95cbc8d..5a409b2 100644
--- a/libparted/fs/fat/fat.c
+++ b/libparted/fs/fat/fat.c
@@ -34,7 +34,9 @@ fat_alloc (const PedGeometry* geom)
 	fs->type_specific = (FatSpecific*) ped_malloc (sizeof (FatSpecific));
 	if (!fs->type_specific)
 		goto error_free_fs;
-
+	FatSpecific* fs_info = (FatSpecific*) fs->type_specific;
+	fs_info->boot_sector = NULL;
+	fs_info->info_sector = NULL;
 	fs->geom = ped_geometry_duplicate (geom);
 	if (!fs->geom)
 		goto error_free_type_specific;
@@ -53,6 +55,8 @@ error:
 void
 fat_free (PedFileSystem* fs)
 {
+	FatSpecific* fs_info = (FatSpecific*) fs->type_specific;
+	free (fs_info->boot_sector);
 	ped_geometry_destroy (fs->geom);
 	free (fs->type_specific);
 	free (fs);
@@ -72,7 +76,7 @@ fat_probe (PedGeometry* geom, FatType* fat_type)
 
 	if (!fat_boot_sector_read (&fs_info->boot_sector, geom))
 		goto error_free_fs;
-	if (!fat_boot_sector_analyse (&fs_info->boot_sector, fs))
+	if (!fat_boot_sector_analyse (fs_info->boot_sector, fs))
 		goto error_free_fs;
 
 	*fat_type = fs_info->fat_type;
@@ -124,20 +128,16 @@ static PedFileSystemOps fat32_ops = {
 	probe:		fat_probe_fat32,
 };
 
-#define FAT_BLOCK_SIZES ((int[2]){512, 0})
-
 PedFileSystemType fat16_type = {
 	next:	        NULL,
 	ops:	        &fat16_ops,
 	name:	        "fat16",
-        block_sizes:    FAT_BLOCK_SIZES
 };
 
 PedFileSystemType fat32_type = {
 	next:	        NULL,
 	ops:	        &fat32_ops,
 	name:	        "fat32",
-        block_sizes:    FAT_BLOCK_SIZES
 };
 
 void
diff --git a/libparted/fs/fat/fat.h b/libparted/fs/fat/fat.h
index 437a020..2265871 100644
--- a/libparted/fs/fat/fat.h
+++ b/libparted/fs/fat/fat.h
@@ -84,8 +84,8 @@ struct __attribute__ ((packed)) _FatDirEntry {
 };
 
 struct _FatSpecific {
-	FatBootSector	boot_sector;    /* structure of boot sector */
-	FatInfoSector	info_sector;    /* fat32-only information sector */
+	FatBootSector	*boot_sector;    /* structure of boot sector */
+	FatInfoSector	*info_sector;    /* fat32-only information sector */
 
 	int		logical_sector_size;	/* illogical sector size :-) */
 	PedSector	sector_count;
diff --git a/libparted/fs/hfs/hfs.c b/libparted/fs/hfs/hfs.c
index 40c8173..e5396b2 100644
--- a/libparted/fs/hfs/hfs.c
+++ b/libparted/fs/hfs/hfs.c
@@ -44,10 +44,6 @@ uint8_t* hfsp_block = NULL;
 unsigned hfs_block_count;
 unsigned hfsp_block_count;
 
-#define HFS_BLOCK_SIZES       ((int[2]){512, 0})
-#define HFSP_BLOCK_SIZES       ((int[2]){512, 0})
-#define HFSX_BLOCK_SIZES       ((int[2]){512, 0})
-
 static PedFileSystemOps hfs_ops = {
 	probe:		hfs_probe,
 };
@@ -65,21 +61,18 @@ static PedFileSystemType hfs_type = {
 	next:	NULL,
 	ops:	&hfs_ops,
 	name:	"hfs",
-	block_sizes: HFS_BLOCK_SIZES
 };
 
 static PedFileSystemType hfsplus_type = {
 	next:	NULL,
 	ops:	&hfsplus_ops,
 	name:	"hfs+",
-	block_sizes: HFSP_BLOCK_SIZES
 };
 
 static PedFileSystemType hfsx_type = {
 	next:	NULL,
 	ops:	&hfsx_ops,
 	name:	"hfsx",
-	block_sizes: HFSX_BLOCK_SIZES
 };
 
 void
diff --git a/libparted/fs/hfs/probe.c b/libparted/fs/hfs/probe.c
index ad79a64..c4dca5e 100644
--- a/libparted/fs/hfs/probe.c
+++ b/libparted/fs/hfs/probe.c
@@ -62,7 +62,6 @@ it is in fact a wrapper to an HFS+ volume */
 PedGeometry*
 hfs_and_wrapper_probe (PedGeometry* geom)
 {
-	uint8_t		buf[PED_SECTOR_SIZE_DEFAULT];
 	HfsMasterDirectoryBlock	*mdb;
 	PedGeometry*	geom_ret;
 	PedSector	search, max;
@@ -70,18 +69,22 @@ hfs_and_wrapper_probe (PedGeometry* geom)
 	PED_ASSERT (geom != NULL);
 	PED_ASSERT (hfsc_can_use_geom (geom));
 
-	mdb = (HfsMasterDirectoryBlock *) buf;
+	const int	sectors = ((3 * 512) + geom->dev->sector_size - 1) /
+				   geom->dev->sector_size;
+	char *		buf = alloca (sectors * geom->dev->sector_size);
+
+	mdb = (HfsMasterDirectoryBlock *)(buf+1024);
 
 	/* is 5 an intelligent value ? */
 	if ((geom->length < 5)
-	    || (!ped_geometry_read (geom, buf, 2, 1))
+	    || (!ped_geometry_read (geom, buf, 0, sectors))
 	    || (mdb->signature != PED_CPU_TO_BE16 (HFS_SIGNATURE)) )
 		return NULL;
 
 	search = ((PedSector) PED_BE16_TO_CPU (mdb->start_block)
 		  + ((PedSector) PED_BE16_TO_CPU (mdb->total_blocks)
-		     * (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE_DEFAULT )));
-	max = search + (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE_DEFAULT);
+		     * (PED_BE32_TO_CPU (mdb->block_size) / geom->dev->sector_size)));
+	max = search + (PED_BE32_TO_CPU (mdb->block_size) / geom->dev->sector_size);
 	if ((search < 0)
 	    || !(geom_ret = ped_geometry_new (geom->dev, geom->start, search + 2)))
 		return NULL;
diff --git a/libparted/fs/jfs/jfs.c b/libparted/fs/jfs/jfs.c
index 803c241..c271285 100644
--- a/libparted/fs/jfs/jfs.c
+++ b/libparted/fs/jfs/jfs.c
@@ -25,7 +25,7 @@
 #include "jfs_types.h"
 #include "jfs_superblock.h"
 
-#define JFS_SUPER_SECTOR 64
+#define JFS_SUPER_OFFSET 32768
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -34,31 +34,23 @@
 #  define _(String) (String)
 #endif /* ENABLE_NLS */
 
-#define JFS_BLOCK_SIZES		((int[2]){512, 0})
-
 static PedGeometry*
 jfs_probe (PedGeometry* geom)
 {
-	union {
-		struct superblock	sb;
-		char			bytes[512];
-	} buf;
-
-        /* FIXME: for now, don't even try to deal with larger sector size.  */
-	if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
-		return NULL;
+	struct superblock *sb = (struct superblock *)alloca (geom->dev->sector_size);
 
-	if (geom->length < JFS_SUPER_SECTOR + 1)
+	if (geom->length * geom->dev->sector_size < JFS_SUPER_OFFSET)
 		return NULL;
-	if (!ped_geometry_read (geom, &buf, JFS_SUPER_SECTOR, 1))
+	if (!ped_geometry_read (geom, sb, JFS_SUPER_OFFSET / geom->dev->sector_size, 1))
 		return NULL;
 
-	if (strncmp (buf.sb.s_magic, JFS_MAGIC, 4) == 0) {
-		PedSector block_size = PED_LE32_TO_CPU (buf.sb.s_pbsize) / 512;
-		PedSector block_count = PED_LE64_TO_CPU (buf.sb.s_size);
-
+	if (strncmp (sb->s_magic, JFS_MAGIC, 4) == 0) {
+		PedSector block_size = PED_LE32_TO_CPU (sb->s_pbsize);
+		PedSector block_count = PED_LE64_TO_CPU (sb->s_size);
+		/* apparently jfs is retarded and always claims 512 byte
+		   sectors, with the block count as a multiple of that */
 		return ped_geometry_new (geom->dev, geom->start,
-					 block_size * block_count);
+					 block_size * block_count / geom->dev->sector_size);
 	} else {
 		return NULL;
 	}
@@ -72,7 +64,6 @@ static PedFileSystemType jfs_type = {
 	next:	NULL,
 	ops:	&jfs_ops,
 	name:	"jfs",
-	block_sizes: JFS_BLOCK_SIZES
 };
 
 void
diff --git a/libparted/fs/linux_swap/linux_swap.c b/libparted/fs/linux_swap/linux_swap.c
index bbc034d..0621fa0 100644
--- a/libparted/fs/linux_swap/linux_swap.c
+++ b/libparted/fs/linux_swap/linux_swap.c
@@ -86,11 +86,6 @@ _generic_swap_probe (PedGeometry* geom, int kind)
 	PedGeometry*	probed_geom;
 	PedSector	length;
 
-        /* Fail the swap-file-system-recognizing test when sector size
-           is not the default.  */
-	if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
-		return NULL;
-
         switch (kind) {
         /* Check for old style swap partitions. */
                 case 0:
@@ -132,30 +127,18 @@ error:

 static int
-swap_init (PedFileSystem* fs, int fresh)
+swap_init (PedFileSystem* fs)
 {
 	SwapSpecific*	fs_info = SWAP_SPECIFIC (fs);
 
-	fs_info->page_sectors = getpagesize () / 512;
+	fs_info->page_sectors = getpagesize () / fs->geom->dev->sector_size;
 	fs_info->page_count = fs->geom->length / fs_info->page_sectors;
 	fs_info->version = 1;
 	fs_info->max_bad_pages = (getpagesize()
 					- sizeof (SwapNewHeader)) / 4;
 
-	if (fresh) {
-		uuid_t uuid_dat;
-
-		memset (fs_info->header, 0, getpagesize());
-
-		/* version is always 1 here */
-		uuid_generate (uuid_dat);
-		memcpy (fs_info->header->new.sws_uuid, uuid_dat,
-			sizeof (fs_info->header->new.sws_uuid));
-                return 1;
-        }
-	else
-                return ped_geometry_read (fs->geom, fs_info->header,
-                                          0, fs_info->page_sectors);
+	return ped_geometry_read (fs->geom, fs_info->header,
+				  0, fs_info->page_sectors);
 }

@@ -174,7 +157,7 @@ swap_alloc (PedGeometry* geom)
 		goto error_free_fs;
 
 	fs_info = SWAP_SPECIFIC (fs);
-	fs_info->header = ped_malloc (getpagesize());
+	fs_info->header = ped_malloc (PED_MAX(getpagesize(), geom->dev->sector_size));
 	if (!fs_info->header)
 		goto error_free_type_specific;
 
@@ -225,7 +208,7 @@ _swap_v0_open (PedGeometry* geom)
 	fs = swap_alloc (geom);
 	if (!fs)
 		goto error;
-	swap_init (fs, 0);
+	swap_init (fs);
 
 	fs_info = SWAP_SPECIFIC (fs);
 	if (!ped_geometry_read (fs->geom, fs_info->header, 0,
@@ -267,12 +250,7 @@ _swap_v1_open (PedGeometry* geom)
 	fs = swap_alloc (geom);
 	if (!fs)
 		goto error;
-/* 	swap_init (fs, 0); */
-
-/* 	fs_info = SWAP_SPECIFIC (fs); */
-/* 	if (!ped_geometry_read (fs->geom, fs_info->header, 0, */
-/* 				fs_info->page_sectors)) */
-        if (!swap_init(fs, 0))
+        if (!swap_init(fs))
 		goto error_free_fs;
 
         fs_info = SWAP_SPECIFIC (fs);
@@ -311,7 +289,7 @@ _swap_swsusp_open (PedGeometry* geom)
 	if (!fs)
 		goto error;
         fs->type = &_swap_swsusp_type;
-	swap_init (fs, 0);
+	swap_init (fs);
 
 	fs_info = SWAP_SPECIFIC (fs);
 	if (!ped_geometry_read (fs->geom, fs_info->header, 0,
@@ -378,21 +356,18 @@ static PedFileSystemType _swap_v0_type = {
 	next:	NULL,
 	ops:	&_swap_v0_ops,
 	name:	"linux-swap(v0)",
-	block_sizes: LINUXSWAP_BLOCK_SIZES
 };
 
 static PedFileSystemType _swap_v1_type = {
 	next:	NULL,
 	ops:	&_swap_v1_ops,
 	name:	"linux-swap(v1)",
-	block_sizes: LINUXSWAP_BLOCK_SIZES
 };
 
 static PedFileSystemType _swap_swsusp_type = {
         next:   NULL,
 	ops:    &_swap_swsusp_ops,
 	name:   "swsusp",
-        block_sizes: LINUXSWAP_BLOCK_SIZES
 };
 
 void
diff --git a/libparted/fs/nilfs2/nilfs2.c b/libparted/fs/nilfs2/nilfs2.c
index bb0a84e..0ec5867 100644
--- a/libparted/fs/nilfs2/nilfs2.c
+++ b/libparted/fs/nilfs2/nilfs2.c
@@ -103,38 +103,31 @@ is_valid_nilfs_sb(struct nilfs2_super_block *sb)
 PedGeometry*
 nilfs2_probe (PedGeometry* geom)
 {
-	void *sb_v;
-	void *sb2_v;
 	struct nilfs2_super_block *sb = NULL;
 	struct nilfs2_super_block *sb2 = NULL;
-	PedSector length = geom->length;
+	PedSector length = geom->length * (geom->dev->sector_size / 512);
 
-	/* ignore if sector size is not 512bytes for now  */
-	if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
-		return NULL;
-
-	PedSector sb2off = NILFS_SB2_OFFSET(length);
+	PedSector sb2off = NILFS_SB2_OFFSET(length) / (geom->dev->sector_size / 512);
 	if (sb2off <= 2)
 		return NULL;
+	const int sectors = (4096 + geom->dev->sector_size - 1) /
+			     geom->dev->sector_size;
+	char *buf = alloca (sectors * geom->dev->sector_size);
+	void *buff2 = alloca (geom->dev->sector_size);
 
-	if (ped_geometry_read_alloc(geom, &sb_v, 2, 1))
-		sb = sb_v;
-
-	if (ped_geometry_read_alloc(geom, &sb2_v, sb2off, 1))
-		sb2 = sb2_v;
+	if (ped_geometry_read(geom, buf, 0, sectors))
+		sb = (struct nilfs2_super_block *)(buf+1024);
+	if (ped_geometry_read(geom, buff2, sb2off, 1))
+		sb2 = buff2;
 
 	if ((!sb || !is_valid_nilfs_sb(sb)) &&
-	    (!sb2 || !is_valid_nilfs_sb(sb2)) ) {
-		free(sb);
-		free(sb2);
+	    (!sb2 || !is_valid_nilfs_sb(sb2)) )
 		return NULL;
-	}
 
 	/* reserve 4k bytes for secondary superblock */
-	length = sb2off + 8;
+	length = sb2off + ((4096 + geom->dev->sector_size - 1) /
+			   geom->dev->sector_size);
 
-	free(sb);
-	free(sb2);
 	return ped_geometry_new(geom->dev, geom->start, length);
 }
 
@@ -142,13 +135,10 @@ static PedFileSystemOps nilfs2_ops = {
 	probe:			nilfs2_probe,
 };
 
-#define NILFS2_BLOCK_SIZES ((int[5]){1024, 2048, 4096, 8192, 0})
-
 static PedFileSystemType nilfs2_type = {
 	next:   NULL,
 	ops:    &nilfs2_ops,
 	name:   "nilfs2",
-	block_sizes: NILFS2_BLOCK_SIZES
 };
 
 void
diff --git a/libparted/fs/ntfs/ntfs.c b/libparted/fs/ntfs/ntfs.c
index 19e990a..4c154fd 100644
--- a/libparted/fs/ntfs/ntfs.c
+++ b/libparted/fs/ntfs/ntfs.c
@@ -30,24 +30,22 @@
 
 #include <unistd.h>
 
-#define NTFS_BLOCK_SIZES       ((int[2]){512, 0})
-
 #define NTFS_SIGNATURE	"NTFS"
 
 PedGeometry*
 ntfs_probe (PedGeometry* geom)
 {
-	char	buf[512];
+	char	*buf = alloca (geom->dev->sector_size);
+	PedGeometry *newg = NULL;
 
-	if (!ped_geometry_read (geom, buf, 0, 1))
+	if (!ped_geometry_read(geom, buf, 0, 1))
 		return 0;
 
 	if (strncmp (NTFS_SIGNATURE, buf + 3, strlen (NTFS_SIGNATURE)) == 0)
-		return ped_geometry_new (geom->dev, geom->start,
+		newg = ped_geometry_new (geom->dev, geom->start,
 					 PED_LE64_TO_CPU (*(uint64_t*)
 						 	  (buf + 0x28)));
-	else
-		return NULL;
+	return newg;
 }
 
 static PedFileSystemOps ntfs_ops = {
@@ -58,7 +56,6 @@ static PedFileSystemType ntfs_type = {
 	next:	NULL,
 	ops:	&ntfs_ops,
 	name:	"ntfs",
-	block_sizes: NTFS_BLOCK_SIZES
 };
 
 void
diff --git a/libparted/fs/r/fat/bootsector.c b/libparted/fs/r/fat/bootsector.c
index 3aff1d7..fcb9782 100644
--- a/libparted/fs/r/fat/bootsector.c
+++ b/libparted/fs/r/fat/bootsector.c
@@ -36,14 +36,14 @@
  * fat_boot_sector_probe_type() to work (or possibly crash on a divide-by-zero)
  */
 int
-fat_boot_sector_read (FatBootSector* bs, const PedGeometry *geom)
+fat_boot_sector_read (FatBootSector** bsp, const PedGeometry *geom)
 {
-	PED_ASSERT (bs != NULL);
+	PED_ASSERT (bsp != NULL);
 	PED_ASSERT (geom != NULL);
 
-	if (!ped_geometry_read (geom, bs, 0, 1))
+	if (!ped_geometry_read_alloc (geom, (void **)bsp, 0, 1))
 		return 0;
-
+	FatBootSector *bs = *bsp;
 	if (PED_LE16_TO_CPU (bs->boot_sign) != 0xAA55) {
 		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
 			_("File system has an invalid signature for a FAT "
@@ -250,10 +250,10 @@ fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs)
 		fs_info->serial_number
 			= PED_LE32_TO_CPU (bs->u.fat32.serial_number);
 		fs_info->info_sector_offset
-		    = PED_LE16_TO_CPU (fs_info->boot_sector.u.fat32.info_sector)
+		    = PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.info_sector)
 			  * fs_info->logical_sector_size;
 		fs_info->boot_sector_backup_offset
-		  = PED_LE16_TO_CPU (fs_info->boot_sector.u.fat32.backup_sector)
+		  = PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.backup_sector)
 			  * fs_info->logical_sector_size;
 		fs_info->root_cluster
 			= PED_LE32_TO_CPU (bs->u.fat32.root_dir_cluster);
@@ -292,11 +292,13 @@ fat_boot_sector_set_boot_code (FatBootSector* bs)
 }
 
 int
-fat_boot_sector_generate (FatBootSector* bs, const PedFileSystem* fs)
+fat_boot_sector_generate (FatBootSector** bsp, const PedFileSystem* fs)
 {
 	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
 
-	PED_ASSERT (bs != NULL);
+	PED_ASSERT (bsp != NULL);
+	*bsp = ped_malloc (fs->geom->dev->sector_size);
+	FatBootSector *bs = *bsp;
 
 	memcpy (bs->system_id, "MSWIN4.1", 8);
 	bs->sector_size = PED_CPU_TO_LE16 (fs_info->logical_sector_size * 512);
@@ -388,16 +390,16 @@ fat_boot_sector_write (const FatBootSector* bs, PedFileSystem* fs)
 }
 
 int
-fat_info_sector_read (FatInfoSector* is, const PedFileSystem* fs)
+fat_info_sector_read (FatInfoSector** isp, const PedFileSystem* fs)
 {
 	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
 	int		status;
 
-	PED_ASSERT (is != NULL);
+	PED_ASSERT (isp != NULL);
 
-	if (!ped_geometry_read (fs->geom, is, fs_info->info_sector_offset, 1))
+	if (!ped_geometry_read_alloc (fs->geom, (void **)isp, fs_info->info_sector_offset, 1))
 		return 0;
-
+	FatInfoSector *is = *isp;
 	if (PED_LE32_TO_CPU (is->signature_2) != FAT32_INFO_MAGIC2) {
 		status = ped_exception_throw (PED_EXCEPTION_WARNING,
 				PED_EXCEPTION_IGNORE_CANCEL,
@@ -412,11 +414,13 @@ fat_info_sector_read (FatInfoSector* is, const PedFileSystem* fs)
 }
 
 int
-fat_info_sector_generate (FatInfoSector* is, const PedFileSystem* fs)
+fat_info_sector_generate (FatInfoSector** isp, const PedFileSystem* fs)
 {
 	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
 
-	PED_ASSERT (is != NULL);
+	PED_ASSERT (isp != NULL);
+	*isp = ped_malloc (fs->geom->dev->sector_size);
+	FatInfoSector *is = *isp;
 
 	fat_table_count_stats (fs_info->fat);
 
diff --git a/libparted/fs/r/fat/bootsector.h b/libparted/fs/r/fat/bootsector.h
index ec367c3..6e8b9ce 100644
--- a/libparted/fs/r/fat/bootsector.h
+++ b/libparted/fs/r/fat/bootsector.h
@@ -116,16 +116,16 @@ struct __attribute__ ((packed)) _FatInfoSector {
         uint16_t	signature_3;	/* should be 0xaa55 */
 };
 
-int fat_boot_sector_read (FatBootSector* bs, const PedGeometry* geom);
+int fat_boot_sector_read (FatBootSector** bs, const PedGeometry* geom);
 FatType fat_boot_sector_probe_type (const FatBootSector* bs,
 				    const PedGeometry* geom);
 int fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs);
 int fat_boot_sector_set_boot_code (FatBootSector* bs);
-int fat_boot_sector_generate (FatBootSector* bs, const PedFileSystem* fs);
+int fat_boot_sector_generate (FatBootSector** bs, const PedFileSystem* fs);
 int fat_boot_sector_write (const FatBootSector* bs, PedFileSystem* fs);
 
-int fat_info_sector_read (FatInfoSector* is, const PedFileSystem* fs);
-int fat_info_sector_generate (FatInfoSector* is, const PedFileSystem* fs);
+int fat_info_sector_read (FatInfoSector** is, const PedFileSystem* fs);
+int fat_info_sector_generate (FatInfoSector** is, const PedFileSystem* fs);
 int fat_info_sector_write (const FatInfoSector* is, PedFileSystem* fs);
 
 #endif /* PED_FAT_BOOTSECTOR_H */
diff --git a/libparted/fs/r/fat/fat.c b/libparted/fs/r/fat/fat.c
index c8e4552..fdc1ecc 100644
--- a/libparted/fs/r/fat/fat.c
+++ b/libparted/fs/r/fat/fat.c
@@ -112,19 +112,22 @@ fat_set_frag_sectors (PedFileSystem* fs, PedSector frag_sectors)
 int
 fat_clobber (PedGeometry* geom)
 {
-	FatBootSector		boot_sector;
+	FatBootSector *boot_sector;
+	int ok;
 
 	if (!fat_boot_sector_read (&boot_sector, geom))
 		return 1;
 
-	boot_sector.system_id[0] = 0;
-	boot_sector.boot_sign = 0;
-	if (boot_sector.u.fat16.fat_name[0] == 'F')
-		boot_sector.u.fat16.fat_name[0] = 0;
-	if (boot_sector.u.fat32.fat_name[0] == 'F')
-		boot_sector.u.fat32.fat_name[0] = 0;
+	boot_sector->system_id[0] = 0;
+	boot_sector->boot_sign = 0;
+	if (boot_sector->u.fat16.fat_name[0] == 'F')
+		boot_sector->u.fat16.fat_name[0] = 0;
+	if (boot_sector->u.fat32.fat_name[0] == 'F')
+		boot_sector->u.fat32.fat_name[0] = 0;
 
-        return ped_geometry_write (geom, &boot_sector, 0, 1);
+        ok = ped_geometry_write (geom, boot_sector, 0, 1);
+	free (boot_sector);
+	return ok;
 }
 
 static int
@@ -163,7 +166,7 @@ fat_open (PedGeometry* geom)
 
 	if (!fat_boot_sector_read (&fs_info->boot_sector, geom))
 		goto error_free_fs;
-	if (!fat_boot_sector_analyse (&fs_info->boot_sector, fs))
+	if (!fat_boot_sector_analyse (fs_info->boot_sector, fs))
 		goto error_free_fs;
 	fs->type = (fs_info->fat_type == FAT_TYPE_FAT16)
 				? &fat16_type
@@ -303,16 +306,16 @@ fat_create (PedGeometry* geom, FatType fat_type, PedTimer* timer)
 
 	fs_info->serial_number = generate_random_uint32 ();
 
-	if (!fat_boot_sector_set_boot_code (&fs_info->boot_sector))
+	if (!fat_boot_sector_set_boot_code (fs_info->boot_sector))
 		goto error_free_buffers;
 	if (!fat_boot_sector_generate (&fs_info->boot_sector, fs))
 		goto error_free_buffers;
-	if (!fat_boot_sector_write (&fs_info->boot_sector, fs))
+	if (!fat_boot_sector_write (fs_info->boot_sector, fs))
 		goto error_free_buffers;
 	if (fs_info->fat_type == FAT_TYPE_FAT32) {
 		if (!fat_info_sector_generate (&fs_info->info_sector, fs))
 			goto error_free_buffers;
-		if (!fat_info_sector_write (&fs_info->info_sector, fs))
+		if (!fat_info_sector_write (fs_info->info_sector, fs))
 			goto error_free_buffers;
 	}
 
@@ -469,7 +472,7 @@ fat_check (PedFileSystem* fs, PedTimer* timer)
 
 	if (fs_info->fat_type == FAT_TYPE_FAT32) {
 		info_free_clusters
-			= PED_LE32_TO_CPU (fs_info->info_sector.free_clusters);
+			= PED_LE32_TO_CPU (fs_info->info_sector->free_clusters);
 		if (info_free_clusters != (FatCluster) -1
 		    && info_free_clusters != fs_info->fat->free_cluster_count) {
 			if (ped_exception_throw (PED_EXCEPTION_WARNING,
diff --git a/libparted/fs/r/fat/fat.h b/libparted/fs/r/fat/fat.h
index d2ac2aa..943c5e5 100644
--- a/libparted/fs/r/fat/fat.h
+++ b/libparted/fs/r/fat/fat.h
@@ -77,8 +77,8 @@ struct __attribute__ ((packed)) _FatDirEntry {
 };
 
 struct _FatSpecific {
-	FatBootSector	boot_sector;    /* structure of boot sector */
-	FatInfoSector	info_sector;    /* fat32-only information sector */
+	FatBootSector	*boot_sector;    /* structure of boot sector */
+	FatInfoSector	*info_sector;    /* fat32-only information sector */
 
 	int		logical_sector_size;	/* illogical sector size :-) */
 	PedSector	sector_count;
diff --git a/libparted/fs/r/fat/resize.c b/libparted/fs/r/fat/resize.c
index 2b68a8b..f3439ac 100644
--- a/libparted/fs/r/fat/resize.c
+++ b/libparted/fs/r/fat/resize.c
@@ -857,10 +857,10 @@ fat_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
 
 	_copy_hidden_sectors (ctx);
 	fat_boot_sector_generate (&new_fs_info->boot_sector, new_fs);
-	fat_boot_sector_write (&new_fs_info->boot_sector, new_fs);
+	fat_boot_sector_write (new_fs_info->boot_sector, new_fs);
 	if (new_fs_info->fat_type == FAT_TYPE_FAT32) {
 		fat_info_sector_generate (&new_fs_info->info_sector, new_fs);
-		fat_info_sector_write (&new_fs_info->info_sector, new_fs);
+		fat_info_sector_write (new_fs_info->info_sector, new_fs);
 	}
 
 	if (!resize_context_assimilate (ctx))
diff --git a/libparted/fs/r/fat/table.c b/libparted/fs/r/fat/table.c
index 974dea8..62bc3b3 100644
--- a/libparted/fs/r/fat/table.c
+++ b/libparted/fs/r/fat/table.c
@@ -129,7 +129,7 @@ fat_table_read (FatTable* ft, const PedFileSystem* fs, int table_num)
 				fs_info->fat_sectors))
 		return 0;
 
-        if ( *((unsigned char*) ft->table) != fs_info->boot_sector.media) {
+        if ( *((unsigned char*) ft->table) != fs_info->boot_sector->media) {
 		if (ped_exception_throw (
 			PED_EXCEPTION_ERROR,
 			PED_EXCEPTION_IGNORE_CANCEL,
@@ -137,7 +137,7 @@ fat_table_read (FatTable* ft, const PedFileSystem* fs, int table_num)
 			  "media %x.  You should probably run scandisk."),
 			(int) table_num + 1,
 			(int) *((unsigned char*) ft->table),
-			(int) fs_info->boot_sector.media)
+			(int) fs_info->boot_sector->media)
 				!= PED_EXCEPTION_IGNORE)
 			return 0;
         }
diff --git a/libparted/fs/reiserfs/reiserfs.c b/libparted/fs/reiserfs/reiserfs.c
index 21d4272..838b2fb 100644
--- a/libparted/fs/reiserfs/reiserfs.c
+++ b/libparted/fs/reiserfs/reiserfs.c
@@ -46,8 +46,6 @@
 
 #include "reiserfs.h"
 
-#define REISERFS_BLOCK_SIZES       ((int[2]){512, 0})
-
 static PedSector reiserfs_super_offset[] = { 128, 16, -1 };
 static PedFileSystemType* reiserfs_type;
 
@@ -57,29 +55,29 @@ static PedFileSystemType* reiserfs_type;
 static PedGeometry *reiserfs_probe(PedGeometry *geom)
 {
 	int i;
-	reiserfs_super_block_t sb;
 
 	PED_ASSERT(geom != NULL);
+	reiserfs_super_block_t *sb =
+		(reiserfs_super_block_t *)alloca (geom->dev->sector_size);
 
 	for (i = 0; reiserfs_super_offset[i] != -1; i++) {
 		if (reiserfs_super_offset[i] >= geom->length)
 			continue;
-		if (!ped_geometry_read (geom, &sb, reiserfs_super_offset[i], 1))
+		if (!ped_geometry_read (geom, sb, reiserfs_super_offset[i], 1))
 			continue;
 
-		if (strncmp(REISERFS_SIGNATURE, sb.s_magic,
+		if (strncmp(REISERFS_SIGNATURE, sb->s_magic,
 		            strlen(REISERFS_SIGNATURE)) == 0
-		    || strncmp(REISER2FS_SIGNATURE, sb.s_magic,
+		    || strncmp(REISER2FS_SIGNATURE, sb->s_magic,
 			       strlen(REISER2FS_SIGNATURE)) == 0
-		    || strncmp(REISER3FS_SIGNATURE, sb.s_magic,
+		    || strncmp(REISER3FS_SIGNATURE, sb->s_magic,
 			       strlen(REISER3FS_SIGNATURE)) == 0) {
 			PedSector block_size;
 			PedSector block_count;
 
-			block_size = PED_LE16_TO_CPU(sb.s_blocksize)
-					/ PED_SECTOR_SIZE_DEFAULT;
-			block_count = PED_LE32_TO_CPU(sb.s_block_count);
-
+			block_size = PED_LE16_TO_CPU(sb->s_blocksize)
+					/ geom->dev->sector_size;
+			block_count = PED_LE32_TO_CPU(sb->s_block_count);
 			return ped_geometry_new(geom->dev, geom->start,
 						block_size * block_count);
 		}
@@ -88,8 +86,6 @@ static PedGeometry *reiserfs_probe(PedGeometry *geom)
 }

-#define REISER_BLOCK_SIZES ((int[]){512, 1024, 2048, 4096, 8192, 0})
-
 static PedFileSystemOps reiserfs_simple_ops = {
 	probe:		reiserfs_probe,
 };
@@ -98,7 +94,6 @@ static PedFileSystemType reiserfs_simple_type = {
 	next:	        NULL,
 	ops:	        &reiserfs_simple_ops,
 	name:	        "reiserfs",
-        block_sizes:    REISER_BLOCK_SIZES
 };
 
 void ped_file_system_reiserfs_init()
diff --git a/libparted/fs/ufs/ufs.c b/libparted/fs/ufs/ufs.c
index b668d7b..a75c082 100644
--- a/libparted/fs/ufs/ufs.c
+++ b/libparted/fs/ufs/ufs.c
@@ -34,10 +34,6 @@
 #include <unistd.h>
 #include <string.h>
 
-#define SUN_UFS_BLOCK_SIZES       ((int[2]){512, 0})
-#define HP_UFS_BLOCK_SIZES        ((int[2]){512, 0})
-
-
 /* taken from ufs_fs.h in Linux */
 #define	UFS_MAXNAMLEN 255
 #define UFS_MAXMNTLEN 512
@@ -178,24 +174,26 @@ struct ufs_super_block {
 static PedGeometry*
 ufs_probe_sun (PedGeometry* geom)
 {
-	int8_t buf[512 * 3];
+	const int	sectors = ((3 * 512) + geom->dev->sector_size - 1) /
+				   geom->dev->sector_size;
+	char *		buf = alloca (sectors * geom->dev->sector_size);
 	struct ufs_super_block *sb;
 
 	if (geom->length < 5)
 		return 0;
-	if (!ped_geometry_read (geom, buf, 16, 3))
+	if (!ped_geometry_read (geom, buf, 16 * 512 / geom->dev->sector_size, sectors))
 		return 0;
 
 	sb = (struct ufs_super_block *)buf;
 
 	if (PED_BE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
-		PedSector block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
+		PedSector block_size = PED_BE32_TO_CPU(sb->fs_bsize) / geom->dev->sector_size;
 		PedSector block_count = PED_BE32_TO_CPU(sb->fs_size);
 		return ped_geometry_new (geom->dev, geom->start,
 					 block_size * block_count);
 	}
 	if (PED_LE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
-		PedSector block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
+		PedSector block_size = PED_LE32_TO_CPU(sb->fs_bsize) / geom->dev->sector_size;
 		PedSector block_count = PED_LE32_TO_CPU(sb->fs_size);
 		return ped_geometry_new (geom->dev, geom->start,
 					 block_size * block_count);
@@ -206,14 +204,17 @@ ufs_probe_sun (PedGeometry* geom)
 static PedGeometry*
 ufs_probe_hp (PedGeometry* geom)
 {
-	int8_t buf[1536];
 	struct ufs_super_block *sb;
 	PedSector block_size;
 	PedSector block_count;
 
 	if (geom->length < 5)
 		return 0;
-	if (!ped_geometry_read (geom, buf, 16, 3))
+	const int	sectors = ((3 * 512) + geom->dev->sector_size - 1) /
+				   geom->dev->sector_size;
+	char *		buf = alloca (sectors * geom->dev->sector_size);
+
+	if (!ped_geometry_read (geom, buf, 16 * 512 / geom->dev->sector_size, sectors))
 		return 0;
 
 	sb = (struct ufs_super_block *)buf;
@@ -223,7 +224,7 @@ ufs_probe_hp (PedGeometry* geom)
 		case UFS_MAGIC_LFN:
 		case UFS_MAGIC_FEA:
 		case UFS_MAGIC_4GB:
-			block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
+			block_size = PED_BE32_TO_CPU(sb->fs_bsize) / geom->dev->sector_size;
 			block_count = PED_BE32_TO_CPU(sb->fs_size);
 			return ped_geometry_new (geom->dev, geom->start,
 						 block_size * block_count);
@@ -234,7 +235,7 @@ ufs_probe_hp (PedGeometry* geom)
 		case UFS_MAGIC_LFN:
 		case UFS_MAGIC_FEA:
 		case UFS_MAGIC_4GB:
-			block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
+			block_size = PED_LE32_TO_CPU(sb->fs_bsize) / geom->dev->sector_size;
 			block_count = PED_LE32_TO_CPU(sb->fs_size);
 			return ped_geometry_new (geom->dev, geom->start,
 						 block_size * block_count);
@@ -254,14 +255,12 @@ static PedFileSystemType ufs_type_sun = {
 	next:	NULL,
 	ops:	&ufs_ops_sun,
 	name:	"sun-ufs",
-	block_sizes: SUN_UFS_BLOCK_SIZES
 };
 
 static PedFileSystemType ufs_type_hp = {
 	next:   NULL,
 	ops:    &ufs_ops_hp,
 	name:   "hp-ufs",
-	block_sizes: HP_UFS_BLOCK_SIZES
 };
 
 void
diff --git a/libparted/fs/xfs/xfs.c b/libparted/fs/xfs/xfs.c
index 0062604..d4144f8 100644
--- a/libparted/fs/xfs/xfs.c
+++ b/libparted/fs/xfs/xfs.c
@@ -33,39 +33,34 @@
 #include "xfs_types.h"
 #include "xfs_sb.h"
 
-#define XFS_BLOCK_SIZES		((int[2]){512, 0})
-
 static PedGeometry*
 xfs_probe (PedGeometry* geom)
 {
 	PedSector	block_size;
 	PedSector	block_count;
-	union {
-		struct xfs_sb	sb;
-		char		bytes [512];
-	} buf;
+	struct xfs_sb	*sb = (struct xfs_sb *)alloca (geom->dev->sector_size);
 
 	if (geom->length < XFS_SB_DADDR + 1)
 		return NULL;
-	if (!ped_geometry_read (geom, &buf, XFS_SB_DADDR, 1))
+	if (!ped_geometry_read (geom, sb, XFS_SB_DADDR, 1))
 		return NULL;
 
-	if (PED_LE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
-		block_size = PED_LE32_TO_CPU (buf.sb.sb_blocksize) / 512;
-		block_count = PED_LE64_TO_CPU (buf.sb.sb_dblocks);
+	if (PED_LE32_TO_CPU (sb->sb_magicnum) == XFS_SB_MAGIC) {
+		block_size = PED_LE32_TO_CPU (sb->sb_blocksize) / geom->dev->sector_size;
+		block_count = PED_LE64_TO_CPU (sb->sb_dblocks);
 
 		return ped_geometry_new (geom->dev, geom->start,
 					 block_size * block_count);
 	}
 
-	if (PED_BE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
-		block_size = PED_BE32_TO_CPU (buf.sb.sb_blocksize) / 512;
-		block_count = PED_BE64_TO_CPU (buf.sb.sb_dblocks);
+	if (PED_BE32_TO_CPU (sb->sb_magicnum) == XFS_SB_MAGIC) {
+		block_size = PED_BE32_TO_CPU (sb->sb_blocksize) / geom->dev->sector_size;
+		block_count = PED_BE64_TO_CPU (sb->sb_dblocks);
 
-		return ped_geometry_new (geom->dev, geom->start,
+		geom = ped_geometry_new (geom->dev, geom->start,
 					 block_size * block_count);
+		return geom;
 	}
-
 	return NULL;
 }
 
@@ -77,7 +72,6 @@ static PedFileSystemType xfs_type = {
 	next:	NULL,
 	ops:	&xfs_ops,
 	name:	"xfs",
-	block_sizes: XFS_BLOCK_SIZES
 };
 
 void
-- 
1.8.3.2