[parted] - Add some missing patches from master and the loop label fixes - tests: test loop labels (psusi) -

Brian C. Lane bcl at fedoraproject.org
Thu May 22 22:04:04 UTC 2014


commit 5dcb73843dcb14c71e5fedf396318c2822853dce
Author: Brian C. Lane <bcl at redhat.com>
Date:   Thu May 22 15:03:30 2014 -0700

    - Add some missing patches from master and the loop label fixes
    - tests: test loop labels (psusi)
    - libparted: don't trash filesystem when writing loop label (psusi)
    - libparted: give correct partition device name on loop labels (psusi)
    - partprobe: do not skip loop labels (psusi)
    - libparted: don't create partition on loop label (psusi)
    - libparted: fix loop labels to not vanish (psusi)
    - libparted: remove all old partitions, even if new label allows less (psusi)
    - libparted: remove old partitions *first* before adding new ones (psusi)
    - libparted: don't detect fat and ntfs boot sectors as dos MBR (psusi)
    - Fix filesystem detection on non 512 byte sectors (psusi)
    - tests: fix t2310-dos-extended-2-sector-min-offset.sh (psusi)
    - libparted: remove last_usable_if_grown (psusi)

 0101-libparted-remove-last_usable_if_grown.patch   |   28 +
 ...t2310-dos-extended-2-sector-min-offset.sh.patch |   45 +
 ...esystem-detection-on-non-512-byte-sectors.patch | 1329 ++++++++++++++++++++
 ...on-t-detect-fat-and-ntfs-boot-sectors-as-.patch |  107 ++
 ...emove-old-partitions-first-before-adding-.patch |  151 +++
 ...emove-all-old-partitions-even-if-new-labe.patch |   63 +
 0107-libparted-fix-loop-labels-to-not-vanish.patch |  143 +++
 ...rted-don-t-create-partition-on-loop-label.patch |   45 +
 0109-partprobe-do-not-skip-loop-labels.patch       |   44 +
 ...ive-correct-partition-device-name-on-loop.patch |   80 ++
 ...on-t-trash-filesystem-when-writing-loop-l.patch |   33 +
 0112-tests-test-loop-labels.patch                  |  137 ++
 parted.spec                                        |   29 +-
 13 files changed, 2233 insertions(+), 1 deletions(-)
---
diff --git a/0101-libparted-remove-last_usable_if_grown.patch b/0101-libparted-remove-last_usable_if_grown.patch
new file mode 100644
index 0000000..28dce16
--- /dev/null
+++ b/0101-libparted-remove-last_usable_if_grown.patch
@@ -0,0 +1,28 @@
+From 6aa11c2e96499a4a620b54433fd064961d1cbf66 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 18 Apr 2014 11:01:03 -0400
+Subject: [PATCH 101/103] libparted: remove last_usable_if_grown
+
+Commit 3398e82a: "libparted: Use common function to calculate PTE sectors"
+removed usage of the last_usable_if_grown variable, resulting in an error
+because it is now unused but still defined.
+---
+ libparted/labels/gpt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
+index e1113ac..b7291a8 100644
+--- a/libparted/labels/gpt.c
++++ b/libparted/labels/gpt.c
+@@ -723,7 +723,7 @@ _parse_header (PedDisk *disk, const GuidPartitionTableHeader_t *gpt,
+   GPTDiskData *gpt_disk_data = disk->disk_specific;
+   PedSector first_usable;
+   PedSector last_usable;
+-  PedSector last_usable_if_grown, last_usable_min_default;
++  PedSector last_usable_if_grown;
+   static int asked_already;
+ 
+ #ifndef DISCOVER_ONLY
+-- 
+1.9.0
+
diff --git a/0102-tests-fix-t2310-dos-extended-2-sector-min-offset.sh.patch b/0102-tests-fix-t2310-dos-extended-2-sector-min-offset.sh.patch
new file mode 100644
index 0000000..03728e7
--- /dev/null
+++ b/0102-tests-fix-t2310-dos-extended-2-sector-min-offset.sh.patch
@@ -0,0 +1,45 @@
+From d68ca7fe15915849629c85f5a5476b2173b3af2c Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Sat, 29 Mar 2014 16:29:06 -0400
+Subject: [PATCH 102/103] tests: fix t2310-dos-extended-2-sector-min-offset.sh
+
+This test was ignoring the requested sector size and always using
+512 bytes per sector.  Fix it to use the requested sector size.
+---
+ tests/t2310-dos-extended-2-sector-min-offset.sh | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/tests/t2310-dos-extended-2-sector-min-offset.sh b/tests/t2310-dos-extended-2-sector-min-offset.sh
+index f74cba5..53843ab 100644
+--- a/tests/t2310-dos-extended-2-sector-min-offset.sh
++++ b/tests/t2310-dos-extended-2-sector-min-offset.sh
+@@ -23,7 +23,8 @@ require_root_
+ require_scsi_debug_module_
+ 
+ # create memory-backed device
+-scsi_debug_setup_ dev_size_mb=1 > dev-name ||
++ss=$sector_size_
++scsi_debug_setup_ sector_size=$ss dev_size_mb=1 > dev-name ||
+   skip_ 'failed to create scsi_debug device'
+ scsi_dev=$(cat dev-name)
+ p1=${scsi_dev}1
+@@ -31,15 +32,11 @@ p5=${scsi_dev}5
+ 
+ cat <<EOF > exp || framework_failure
+ BYT;
+-$scsi_dev:2048s:scsi:512:512:msdos:Linux scsi_debug:;
++$scsi_dev:$((2048*512/$ss))s:scsi:$ss:$ss:msdos:Linux scsi_debug:;
+ 1:64s:128s:65s:::lba;
+ 5:65s:128s:64s:::;
+ EOF
+ 
+-cat <<EOF > err.exp || framework_failure
+-Error: Partition(s) 5 on $scsi_dev have been written, but we have been unable to inform the kernel of the change, probably because it/they are in use.  As a result, the old partition(s) will remain in use.  You should reboot now before making further changes.
+-EOF
+-
+ # Create a DOS label with an extended partition starting at sector 64.
+ parted -s $scsi_dev mklabel msdos || fail=1
+ parted --align=min -s $scsi_dev mkpart extended 64s 128s> out 2>&1 || fail=1
+-- 
+1.9.0
+
diff --git a/0103-Fix-filesystem-detection-on-non-512-byte-sectors.patch b/0103-Fix-filesystem-detection-on-non-512-byte-sectors.patch
new file mode 100644
index 0000000..ae16c59
--- /dev/null
+++ b/0103-Fix-filesystem-detection-on-non-512-byte-sectors.patch
@@ -0,0 +1,1329 @@
+From dab3a267bebcff3308b69f0d1bdaf44b6547d3cb Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Mon, 17 Mar 2014 22:07:55 -0400
+Subject: [PATCH 103/103] Fix filesystem detection on non 512 byte sectors
+
+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 9ef8bf4..ae65106 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 linux partition sync code to flush partitions > 16
+ 
+   Do not reject a FAT boot sector as invalid because it has no
+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 05d7f36..3ba2683 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"
+ 
+ static 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.9.0
+
diff --git a/0104-libparted-don-t-detect-fat-and-ntfs-boot-sectors-as-.patch b/0104-libparted-don-t-detect-fat-and-ntfs-boot-sectors-as-.patch
new file mode 100644
index 0000000..9c0200d
--- /dev/null
+++ b/0104-libparted-don-t-detect-fat-and-ntfs-boot-sectors-as-.patch
@@ -0,0 +1,107 @@
+From 9f4d2b7c87f99f1dec592111a6a6d267949a2c33 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:43 -0400
+Subject: [PATCH 200/208] libparted: don't detect fat and ntfs boot sectors as
+ dos MBR
+
+fat and ntfs boot sectors are very similar to an MBR so if you had one of
+these filesystems on an unpartitioned disk, parted detected them as a dos
+partition table.  Have the dos label code call the fat and ntfs filesystem
+probes and if they recognize the sector ( their tests are more stringent )
+then don't claim it as a dos label.
+---
+ NEWS                     |  3 +++
+ libparted/fs/ntfs/ntfs.c |  2 +-
+ libparted/labels/dos.c   | 29 +++++++++++++++++++++++++++++
+ 3 files changed, 33 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index ae65106..0c3bad5 100644
+--- a/NEWS
++++ b/NEWS
+@@ -25,6 +25,9 @@ GNU parted NEWS                                    -*- outline -*-
+ 
+   Fix filesystem detection on non 512 byte sector sizes
+ 
++  libparted: fat and ntfs boot sectors were misdetected as dos
++  partition tables instead of being treated as a loop label.
++
+   Fix linux partition sync code to flush partitions > 16
+ 
+   Do not reject a FAT boot sector as invalid because it has no
+diff --git a/libparted/fs/ntfs/ntfs.c b/libparted/fs/ntfs/ntfs.c
+index 3ba2683..4c154fd 100644
+--- a/libparted/fs/ntfs/ntfs.c
++++ b/libparted/fs/ntfs/ntfs.c
+@@ -32,7 +32,7 @@
+ 
+ #define NTFS_SIGNATURE	"NTFS"
+ 
+-static PedGeometry*
++PedGeometry*
+ ntfs_probe (PedGeometry* geom)
+ {
+ 	char	*buf = alloca (geom->dev->sector_size);
+diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c
+index eff1c03..295fcf3 100644
+--- a/libparted/labels/dos.c
++++ b/libparted/labels/dos.c
+@@ -235,12 +235,23 @@ maybe_FAT (unsigned char const *s)
+   return true;
+ }
+ 
++PedGeometry*
++fat_probe_fat16 (PedGeometry* geom);
++
++PedGeometry*
++fat_probe_fat32 (PedGeometry* geom);
++
++PedGeometry*
++ntfs_probe (PedGeometry* geom);
++
+ static int
+ msdos_probe (const PedDevice *dev)
+ {
+ 	PedDiskType*	disk_type;
+ 	DosRawTable*	part_table;
+ 	int		i;
++	PedGeometry *geom = NULL;
++	PedGeometry *fsgeom = NULL;
+ 
+ 	PED_ASSERT (dev != NULL);
+ 
+@@ -257,6 +268,20 @@ msdos_probe (const PedDevice *dev)
+ 	if (PED_LE16_TO_CPU (part_table->magic) != MSDOS_MAGIC)
+ 		goto probe_fail;
+ 
++	geom = ped_geometry_new (dev, 0, dev->length);
++	PED_ASSERT (geom);
++	fsgeom = fat_probe_fat16 (geom);
++	if (fsgeom)
++		goto probe_fail; /* fat fs looks like dos mbr */
++	fsgeom = fat_probe_fat32 (geom);
++	if (fsgeom)
++		goto probe_fail; /* fat fs looks like dos mbr */
++	fsgeom = ntfs_probe (geom);
++	if (fsgeom)
++		goto probe_fail; /* ntfs fs looks like dos mbr */
++	ped_geometry_destroy (geom);
++	geom = NULL;
++
+ 	/* If this is a FAT fs, fail here.  Checking for the FAT signature
+ 	 * has some false positives; instead, do what the Linux kernel does
+ 	 * and ensure that each partition has a boot indicator that is
+@@ -303,6 +328,10 @@ msdos_probe (const PedDevice *dev)
+ 	return 1;
+ 
+  probe_fail:
++	if (geom)
++		ped_geometry_destroy (geom);
++	if (fsgeom)
++		ped_geometry_destroy (fsgeom);
+ 	free (label);
+ 	return 0;
+ }
+-- 
+1.9.0
+
diff --git a/0105-libparted-remove-old-partitions-first-before-adding-.patch b/0105-libparted-remove-old-partitions-first-before-adding-.patch
new file mode 100644
index 0000000..5912982
--- /dev/null
+++ b/0105-libparted-remove-old-partitions-first-before-adding-.patch
@@ -0,0 +1,151 @@
+From 36f74e81b1da1ecadc071b3bd2f3a13db0161897 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:44 -0400
+Subject: [PATCH 201/208] libparted: remove old partitions *first* before
+ adding new ones
+
+"libparted: avoid disturbing partitions" put the remove of the old
+partition in second pass.  If you simultaneously removed partitions 1
+and 2, and created a new partition #1 that overlapped the previous second
+partition, the sync would fail because it would try to create the new,
+larger partition #1 before removing the old partition #2.
+---
+ libparted/arch/linux.c                  | 43 ++++++++++++++--------------
+ tests/Makefile.am                       |  1 +
+ tests/t1104-remove-and-add-partition.sh | 50 +++++++++++++++++++++++++++++++++
+ 3 files changed, 72 insertions(+), 22 deletions(-)
+ create mode 100644 tests/t1104-remove-and-add-partition.sh
+
+diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
+index 71f5034..ced06a3 100644
+--- a/libparted/arch/linux.c
++++ b/libparted/arch/linux.c
+@@ -2855,23 +2855,8 @@ _disk_sync_part_table (PedDisk* disk)
+                             && start == part->geom.start
+                             && length == part->geom.length)
+                         {
+-                                ok[i - 1] = 1;
+-                                continue;
+-                        }
+-                }
+-	}
+-        for (i = 1; i <= lpn; i++) {
+-                PedPartition *part = ped_disk_get_partition (disk, i);
+-                if (part) {
+-                        unsigned long long length;
+-                        unsigned long long start;
+-                        /* get start and length of existing partition */
+-                        if (get_partition_start_and_length(part,
+-                                                            &start, &length)
+-                            && start == part->geom.start
+-                            && length == part->geom.length) {
+-                                ok[i - 1] = 1;
+                                 /* partition is unchanged, so nothing to do */
++                                ok[i - 1] = 1;
+                                 continue;
+                         }
+                 }
+@@ -2890,12 +2875,26 @@ _disk_sync_part_table (PedDisk* disk)
+                 } while (n_sleep--);
+                 if (!ok[i - 1] && errnums[i - 1] == ENXIO)
+                         ok[i - 1] = 1; /* it already doesn't exist */
+-                if (part && ok[i - 1]) {
+-                        /* add the (possibly modified or new) partition */
+-                        if (!add_partition (disk, part)) {
+-                                ok[i - 1] = 0;
+-                                errnums[i - 1] = errno;
+-                        }
++	}
++        for (i = 1; i <= lpn; i++) {
++                PedPartition *part = ped_disk_get_partition (disk, i);
++                if (!part)
++                        continue;
++                unsigned long long length;
++                unsigned long long start;
++                /* get start and length of existing partition */
++                if (get_partition_start_and_length(part,
++                                                   &start, &length)
++                    && start == part->geom.start
++                    && length == part->geom.length) {
++                        ok[i - 1] = 1;
++                        /* partition is unchanged, so nothing to do */
++                        continue;
++                }
++                /* add the (possibly modified or new) partition */
++                if (!add_partition (disk, part)) {
++                        ok[i - 1] = 0;
++                        errnums[i - 1] = errno;
+                 }
+         }
+ 
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 9100a81..e064b8f 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -40,6 +40,7 @@ TESTS = \
+   t0501-duplicate.sh \
+   t1100-busy-label.sh \
+   t1101-busy-partition.sh \
++  t1104-remove-and-add-partition.sh \
+   t1700-probe-fs.sh \
+   t2200-dos-label-recog.sh \
+   t2201-pc98-label-recog.sh \
+diff --git a/tests/t1104-remove-and-add-partition.sh b/tests/t1104-remove-and-add-partition.sh
+new file mode 100644
+index 0000000..61cc392
+--- /dev/null
++++ b/tests/t1104-remove-and-add-partition.sh
+@@ -0,0 +1,50 @@
++#!/bin/sh
++# make sure that removing a higher numbered partition and adding a lower
++# one using that space at the same time works
++
++# Copyright (C) 2014 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/>.
++
++. "${srcdir=.}/init.sh"; path_prepend_ ../parted
++path_prepend_ ../partprobe
++require_root_
++ss=$sector_size_
++
++d1= f1=
++cleanup_fn_()
++{
++  test -n "$d1" && losetup -d "$d1"
++  rm -f "$f1"
++}
++
++f1=$(pwd)/1; d1=$(loop_setup_ "$f1") \
++  || skip_ "is this partition mounted with 'nodev'?"
++
++require_partitionable_loop_device_ $d1
++
++# create one big partition
++parted -s $d1 mklabel msdos mkpart primary ext2 1m 10m || fail=1
++
++# save this table
++dd if=$d1 of=saved count=1 || fail=1
++
++# create two small partitions
++parted -s $d1 mklabel msdos mkpart primary ext2 1m 5m mkpart primary ext2 5m 10m || fail=1
++
++# restore first table and make sure partprobe works
++dd if=saved of=$d1 || fail=1
++partprobe $d1 || fail=1
++
++Exit $fail
+-- 
+1.9.0
+
diff --git a/0106-libparted-remove-all-old-partitions-even-if-new-labe.patch b/0106-libparted-remove-all-old-partitions-even-if-new-labe.patch
new file mode 100644
index 0000000..525c18a
--- /dev/null
+++ b/0106-libparted-remove-all-old-partitions-even-if-new-labe.patch
@@ -0,0 +1,63 @@
+From dc291e101cf20c6493c262124debab92427c83d9 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:45 -0400
+Subject: [PATCH 202/208] libparted: remove all old partitions, even if new
+ label allows less
+
+We were limiting partition sync operations to the lesser number allowed
+by the device, or the label.  This meant that when creating a new label
+over an old label that had more partitions than the new one allows, the
+higher partitions would not be removed.  Use the greater of the two values
+for the remove pass, and the lesser for the add.
+---
+ NEWS                   |  3 +++
+ libparted/arch/linux.c | 11 +++++++++--
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 0c3bad5..a81c049 100644
+--- a/NEWS
++++ b/NEWS
+@@ -25,6 +25,9 @@ GNU parted NEWS                                    -*- outline -*-
+ 
+   Fix filesystem detection on non 512 byte sector sizes
+ 
++  libparted: remove all old partitions, even if new label does not allow
++  as many.
++
+   libparted: fat and ntfs boot sectors were misdetected as dos
+   partition tables instead of being treated as a loop label.
+ 
+diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
+index ced06a3..4cbe49b 100644
+--- a/libparted/arch/linux.c
++++ b/libparted/arch/linux.c
+@@ -2823,9 +2823,10 @@ _disk_sync_part_table (PedDisk* disk)
+                 get_partition_start_and_length = _kernel_get_partition_start_and_length;
+         }
+ 
+-        /* lpn = largest partition number. */
++        /* lpn = largest partition number.
++         * for remove pass, use greater of device or label limit */
+         if (ped_disk_get_max_supported_partition_count(disk, &lpn))
+-                lpn = PED_MIN(lpn, part_range);
++                lpn = PED_MAX(lpn, part_range);
+         else
+                 lpn = part_range;
+ 
+@@ -2876,6 +2877,12 @@ _disk_sync_part_table (PedDisk* disk)
+                 if (!ok[i - 1] && errnums[i - 1] == ENXIO)
+                         ok[i - 1] = 1; /* it already doesn't exist */
+ 	}
++        /* lpn = largest partition number.
++         * for add pass, use lesser of device or label limit */
++        if (ped_disk_get_max_supported_partition_count(disk, &lpn))
++                lpn = PED_MIN(lpn, part_range);
++        else
++                lpn = part_range;
+         for (i = 1; i <= lpn; i++) {
+                 PedPartition *part = ped_disk_get_partition (disk, i);
+                 if (!part)
+-- 
+1.9.0
+
diff --git a/0107-libparted-fix-loop-labels-to-not-vanish.patch b/0107-libparted-fix-loop-labels-to-not-vanish.patch
new file mode 100644
index 0000000..da9e892
--- /dev/null
+++ b/0107-libparted-fix-loop-labels-to-not-vanish.patch
@@ -0,0 +1,143 @@
+From 1707f92e281f226463c39941471e04c55078615b Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:46 -0400
+Subject: [PATCH 203/208] libparted: fix loop labels to not vanish
+
+The loop label type was using the existence of a partition as a proxy for
+a filesystem being detected, and loop_write() would try to write a loop
+signature if there was no filesystem, and erase it if there was.  Because
+of this, creating a partition without writing a filesystem to it caused
+loop_write to erase the loop label.
+
+There seems to be no reason to bother erasing the loop label if it is still
+present along with a filesystem signature, so don't bother with this, and
+actually check to see if a filesystem is detected in the partition rather
+than using the existence of a partition to decide if writing the loop
+signature is needed.  Finally, since there is no way to preserve the
+existence of a partition with no filesystem in it, have loop_read() always
+create a partition, even if no filesystem is detected.
+---
+ NEWS                    |  6 ++++++
+ libparted/labels/loop.c | 53 ++++++++++++++++++++++---------------------------
+ 2 files changed, 30 insertions(+), 29 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index a81c049..3154ef5 100644
+--- a/NEWS
++++ b/NEWS
+@@ -25,6 +25,9 @@ GNU parted NEWS                                    -*- outline -*-
+ 
+   Fix filesystem detection on non 512 byte sector sizes
+ 
++  libparted: fix loop labels to not vanish if you don't create
++  a filesystem, and to not return an error syncing when you do.
++
+   libparted: remove all old partitions, even if new label does not allow
+   as many.
+ 
+@@ -105,6 +108,9 @@ GNU parted NEWS                                    -*- outline -*-
+ 
+ ** Changes in behavior
+ 
++  When creating a loop label, it automatically comes with a partition
++  using the whole disk.
++
+   parted -l no longer lists device-mapper devices other than
+   dmraid whole disks.
+ 
+diff --git a/libparted/labels/loop.c b/libparted/labels/loop.c
+index ea8f007..8ebb1f4 100644
+--- a/libparted/labels/loop.c
++++ b/libparted/labels/loop.c
+@@ -80,7 +80,23 @@ loop_alloc (const PedDevice* dev)
+ 
+ 	if (dev->length < 256)
+ 		return NULL;
+-	return _ped_disk_alloc ((PedDevice*)dev, &loop_disk_type);
++	PedDisk *disk = _ped_disk_alloc ((PedDevice*)dev, &loop_disk_type);
++	PED_ASSERT (disk != NULL);
++	PedGeometry *geom = ped_geometry_new (dev, 0, dev->length);
++	PED_ASSERT (geom != NULL);
++	PedPartition *part = ped_partition_new (disk, PED_PARTITION_NORMAL,
++						NULL, geom->start, geom->end);
++	PED_ASSERT (part != NULL);
++	ped_geometry_destroy (geom);
++	PedConstraint *constraint_any = ped_constraint_any (dev);
++	if (!ped_disk_add_partition (disk, part, constraint_any))
++		goto error;
++	ped_constraint_destroy (constraint_any);
++	return disk;
++ error:
++	ped_constraint_destroy (constraint_any);
++	ped_disk_destroy (disk);
++	return NULL;
+ }
+ 
+ static PedDisk*
+@@ -118,18 +134,12 @@ loop_read (PedDisk* disk)
+ 
+         int found_sig = !strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE));
+         free (buf);
+-
+-        if (found_sig) {
+-		ped_constraint_destroy (constraint_any);
+-		return 1;
+-        }
+-
+ 	geom = ped_geometry_new (dev, 0, dev->length);
+ 	if (!geom)
+ 		goto error;
+ 
+ 	fs_type = ped_file_system_probe (geom);
+-	if (!fs_type)
++	if (!fs_type && !found_sig)
+ 		goto error_free_geom;
+ 
+ 	part = ped_partition_new (disk, PED_PARTITION_NORMAL,
+@@ -137,7 +147,6 @@ loop_read (PedDisk* disk)
+ 	ped_geometry_destroy (geom);
+ 	if (!part)
+ 		goto error;
+-	part->fs_type = fs_type;
+ 
+ 	if (!ped_disk_add_partition (disk, part, constraint_any))
+ 		goto error;
+@@ -156,29 +165,15 @@ static int
+ loop_write (const PedDisk* disk)
+ {
+ 	size_t buflen = disk->dev->sector_size;
+-	char *buf = ped_malloc (buflen);
+-	if (buf == NULL)
+-		return 0;
+-
+-	if (ped_disk_get_partition (disk, 1)) {
+-		if (!ped_device_read (disk->dev, buf, 0, 1)) {
+-			free (buf);
+-			return 0;
+-		}
+-		if (strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE)) != 0) {
+-			free (buf);
+-			return 1;
+-                }
+-		memset (buf, 0, strlen (LOOP_SIGNATURE));
+-		return ped_device_write (disk->dev, buf, 0, 1);
+-	}
+-
++	char *buf = alloca (buflen);
++	PedPartition *part = ped_disk_get_partition (disk, 1);
++	/* if there is already a filesystem on the disk, we don't need to write the signature */
++	if (part && part->fs_type)
++		return 1;
+ 	memset (buf, 0, buflen);
+ 	strcpy (buf, LOOP_SIGNATURE);
+ 
+-        int write_ok = ped_device_write (disk->dev, buf, 0, 1);
+-        free (buf);
+-	return write_ok;
++        return ped_device_write (disk->dev, buf, 0, 1);
+ }
+ #endif /* !DISCOVER_ONLY */
+ 
+-- 
+1.9.0
+
diff --git a/0108-libparted-don-t-create-partition-on-loop-label.patch b/0108-libparted-don-t-create-partition-on-loop-label.patch
new file mode 100644
index 0000000..27a2325
--- /dev/null
+++ b/0108-libparted-don-t-create-partition-on-loop-label.patch
@@ -0,0 +1,45 @@
+From a00b5dd9e33241904b01f7b375da57ccd6e777b5 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:47 -0400
+Subject: [PATCH 204/208] libparted: don't create partition on loop label
+
+The loop label represents an unpartitioned disk, but creates
+a dummy partition to represent the whole disk.  This dummy partition
+was actually being loaded into the kernel.  Don't do that.
+---
+ NEWS                   | 4 ++++
+ libparted/arch/linux.c | 3 +++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 3154ef5..77cffea 100644
+--- a/NEWS
++++ b/NEWS
+@@ -25,6 +25,10 @@ GNU parted NEWS                                    -*- outline -*-
+ 
+   Fix filesystem detection on non 512 byte sector sizes
+ 
++  libparted: The loop label represents an unpartitioned disk, but creates
++  a dummy partition to represent the whole disk.  This dummy partition
++  was actually being loaded into the kernel.  Don't do that.
++
+   libparted: fix loop labels to not vanish if you don't create
+   a filesystem, and to not return an error syncing when you do.
+ 
+diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
+index 4cbe49b..9ae6d64 100644
+--- a/libparted/arch/linux.c
++++ b/libparted/arch/linux.c
+@@ -2883,6 +2883,9 @@ _disk_sync_part_table (PedDisk* disk)
+                 lpn = PED_MIN(lpn, part_range);
+         else
+                 lpn = part_range;
++        /* don't actually add partitions for loop */
++        if (strcmp (disk->type->name, "loop") == 0)
++                lpn = 0;
+         for (i = 1; i <= lpn; i++) {
+                 PedPartition *part = ped_disk_get_partition (disk, i);
+                 if (!part)
+-- 
+1.9.0
+
diff --git a/0109-partprobe-do-not-skip-loop-labels.patch b/0109-partprobe-do-not-skip-loop-labels.patch
new file mode 100644
index 0000000..a1374e8
--- /dev/null
+++ b/0109-partprobe-do-not-skip-loop-labels.patch
@@ -0,0 +1,44 @@
+From 7127a356f205af5ca97370fe6b3674f55c5ec700 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:48 -0400
+Subject: [PATCH 205/208] partprobe: do not skip loop labels
+
+Partprobe was not syncing loop labels.  This resulted it failing to remove
+existing partitions when switching to a loop label.
+---
+ NEWS                  | 3 +++
+ partprobe/partprobe.c | 4 +---
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 77cffea..d79292f 100644
+--- a/NEWS
++++ b/NEWS
+@@ -25,6 +25,9 @@ GNU parted NEWS                                    -*- outline -*-
+ 
+   Fix filesystem detection on non 512 byte sector sizes
+ 
++  partprobe: when called on a disk that has become a loop label,
++  remove any partitions left over from a previous label.
++
+   libparted: The loop label represents an unpartitioned disk, but creates
+   a dummy partition to represent the whole disk.  This dummy partition
+   was actually being loaded into the kernel.  Don't do that.
+diff --git a/partprobe/partprobe.c b/partprobe/partprobe.c
+index 4da4fb7..8b744b5 100644
+--- a/partprobe/partprobe.c
++++ b/partprobe/partprobe.c
+@@ -106,9 +106,7 @@ process_dev (PedDevice* dev)
+ 	PedDisk*	disk;
+ 
+ 	disk_type = ped_disk_probe (dev);
+-	if (disk_type && !strcmp (disk_type->name, "loop"))
+-		return 1;
+-	else if (!disk_type) {
++	if (!disk_type) {
+ 		/* Partition table not found, so create dummy,
+ 		   empty one */
+ 		disk_type = ped_disk_type_get("msdos");
+-- 
+1.9.0
+
diff --git a/0110-libparted-give-correct-partition-device-name-on-loop.patch b/0110-libparted-give-correct-partition-device-name-on-loop.patch
new file mode 100644
index 0000000..e9f132e
--- /dev/null
+++ b/0110-libparted-give-correct-partition-device-name-on-loop.patch
@@ -0,0 +1,80 @@
+From 998e09d5698777cfbb9b7aacc9059209c7816d60 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:49 -0400
+Subject: [PATCH 206/208] libparted: give correct partition device name on loop
+ labels
+
+ped_partition_get_path() was returning "/dev/foo1" instead of
+"/dev/foo" on loop labels.  This caused gparted to run tools like mkfs on
+a device node that did not actually exist.
+---
+ NEWS                   |  3 +++
+ libparted/arch/linux.c | 10 ++++++++--
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index d79292f..0a04942 100644
+--- a/NEWS
++++ b/NEWS
+@@ -25,6 +25,9 @@ GNU parted NEWS                                    -*- outline -*-
+ 
+   Fix filesystem detection on non 512 byte sector sizes
+ 
++  libparted: ped_partition_get_path() was returning "/dev/foo1" instead
++  of "/dev/foo" for loop labels.
++
+   partprobe: when called on a disk that has become a loop label,
+   remove any partitions left over from a previous label.
+ 
+diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
+index 9ae6d64..f2e2abc 100644
+--- a/libparted/arch/linux.c
++++ b/libparted/arch/linux.c
+@@ -48,6 +48,7 @@
+ #include "../architecture.h"
+ #include "dirname.h"
+ #include "xstrtol.h"
++#include "xalloc.h"
+ 
+ #if ENABLE_NLS
+ #  include <libintl.h>
+@@ -2356,6 +2357,9 @@ _device_get_part_path (PedDevice const *dev, int num)
+ static char*
+ linux_partition_get_path (const PedPartition* part)
+ {
++        /* loop label means use the whole disk */
++        if (strcmp (part->disk->type->name, "loop") == 0)
++                return xstrdup (part->disk->dev->path);
+         return _device_get_part_path (part->disk->dev, part->num);
+ }
+ 
+@@ -2424,6 +2428,8 @@ linux_partition_is_busy (const PedPartition* part)
+ 
+         PED_ASSERT (part != NULL);
+ 
++        if (strcmp (part->disk->type->name, "loop") == 0)
++                return linux_is_busy (part->disk->dev);
+         if (_partition_is_mounted (part))
+                 return 1;
+         if (part->type == PED_PARTITION_EXTENDED) {
+@@ -2546,7 +2552,7 @@ _sysfs_ull_entry_from_part(PedPartition const* part, const char *entry,
+                            unsigned long long *val)
+ {
+         char path[128];
+-        char *part_name = linux_partition_get_path(part);
++        char *part_name = _device_get_part_path (part->disk->dev, part->num);
+         if (!part_name)
+                 return false;
+ 
+@@ -2581,7 +2587,7 @@ _kernel_get_partition_start_and_length(PedPartition const *part,
+         PED_ASSERT(start);
+         PED_ASSERT(length);
+ 
+-        char *dev_name = linux_partition_get_path (part);
++        char *dev_name = _device_get_part_path (part->disk->dev, part->num);
+         if (!dev_name)
+                 return false;
+ 
+-- 
+1.9.0
+
diff --git a/0111-libparted-don-t-trash-filesystem-when-writing-loop-l.patch b/0111-libparted-don-t-trash-filesystem-when-writing-loop-l.patch
new file mode 100644
index 0000000..93d3ca5
--- /dev/null
+++ b/0111-libparted-don-t-trash-filesystem-when-writing-loop-l.patch
@@ -0,0 +1,33 @@
+From b83ac74a8b87a770bdd78c7c23731bcc252393e4 Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:50 -0400
+Subject: [PATCH 207/208] libparted: don't trash filesystem when writing loop
+ label
+
+If you deleted the fake partition on a loop label, loop_write() would write
+the loop signature to the device, zeroing out all other bytes in the first
+sector.  When the disk contained an ext[234] filesystem and was using 2k
+sectors, this would trash the super block residing in the 1-2kb part of the
+sector causing the disk to become unrecognized.  Instead, read the existing
+sector and only modify the first few bytes that contain the loop label.
+---
+ libparted/labels/loop.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libparted/labels/loop.c b/libparted/labels/loop.c
+index 8ebb1f4..98f9f23 100644
+--- a/libparted/labels/loop.c
++++ b/libparted/labels/loop.c
+@@ -170,7 +170,8 @@ loop_write (const PedDisk* disk)
+ 	/* if there is already a filesystem on the disk, we don't need to write the signature */
+ 	if (part && part->fs_type)
+ 		return 1;
+-	memset (buf, 0, buflen);
++	if (!ped_device_read (disk->dev, buf, 0, 1))
++		return 0;
+ 	strcpy (buf, LOOP_SIGNATURE);
+ 
+         return ped_device_write (disk->dev, buf, 0, 1);
+-- 
+1.9.0
+
diff --git a/0112-tests-test-loop-labels.patch b/0112-tests-test-loop-labels.patch
new file mode 100644
index 0000000..659fe3b
--- /dev/null
+++ b/0112-tests-test-loop-labels.patch
@@ -0,0 +1,137 @@
+From bd4574d9b49ec3e2d73c59dcab7c5f22c2e85c4a Mon Sep 17 00:00:00 2001
+From: Phillip Susi <psusi at ubuntu.com>
+Date: Fri, 2 May 2014 21:50:51 -0400
+Subject: [PATCH 208/208] tests: test loop labels
+
+Verify previous fixes to loop labels.
+---
+ tests/Makefile.am         |   1 +
+ tests/t1102-loop-label.sh | 104 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 105 insertions(+)
+ create mode 100644 tests/t1102-loop-label.sh
+
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index e064b8f..26226cf 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -40,6 +40,7 @@ TESTS = \
+   t0501-duplicate.sh \
+   t1100-busy-label.sh \
+   t1101-busy-partition.sh \
++  t1102-loop-label.sh \
+   t1104-remove-and-add-partition.sh \
+   t1700-probe-fs.sh \
+   t2200-dos-label-recog.sh \
+diff --git a/tests/t1102-loop-label.sh b/tests/t1102-loop-label.sh
+new file mode 100644
+index 0000000..f5701a3
+--- /dev/null
++++ b/tests/t1102-loop-label.sh
+@@ -0,0 +1,104 @@
++#!/bin/sh
++# make sure that loop labels work correctly
++# create an actual partition
++
++# Copyright (C) 2013 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/>.
++
++. "${srcdir=.}/init.sh"; path_prepend_ ../parted
++path_prepend_ ../partprobe
++require_root_
++require_scsi_debug_module_
++ss=$sector_size_
++
++scsi_debug_setup_ sector_size=$ss dev_size_mb=90 > dev-name ||
++  skip_ 'failed to create scsi_debug device'
++dev=$(cat dev-name)
++
++mke2fs -F $dev
++parted -s "$dev" print > out 2>&1 || fail=1
++cat <<EOF > exp
++Model: Linux scsi_debug (scsi)
++Disk DEVICE: 94.4MB
++Sector size (logical/physical): ${ss}B/${ss}B
++Partition Table: loop
++Disk Flags: 
++
++Number  Start  End     Size    File system  Flags
++ 1      0.00B  94.4MB  94.4MB  ext2
++
++EOF
++mv out o2 && sed -e "s,$dev,DEVICE,;" o2 > out
++
++compare exp out || fail=1
++parted -s $dev rm 1 || fail=1
++if [ -e ${dev}1 ]; then
++    echo "Partition should not exist on loop device"
++    fail=1
++fi
++partprobe $dev || fail=1
++if [ -e ${dev}1 ]; then
++    echo "Partition should not exist on loop device"
++    fail=1
++fi
++
++mount_point="`pwd`/mnt"
++
++# Be sure to unmount upon interrupt, failure, etc.
++cleanup_fn_() { umount "$mount_point" > /dev/null 2>&1; }
++
++# create mount point dir. and mount the just-created partition on it
++mkdir $mount_point || fail=1
++mount -t ext2 "${dev}" $mount_point || fail=1
++
++# now that a partition is mounted, mklabel attempt must fail
++parted -s "$dev" mklabel msdos > out 2>&1; test $? = 1 || fail=1
++
++# create expected output file
++echo "Error: Partition(s) on $dev are being used." > exp
++compare exp out || fail=1
++
++# make sure partition busy check works ( mklabel checks whole disk )
++parted -s "$dev" rm 1 > out 2>&1; test $? = 1 || fail=1
++# create expected output file
++echo "Error: Partition $dev is being used. You must unmount it before you modify \
++it with Parted." > exp
++compare exp out || fail=1
++
++umount "$mount_point"
++
++# make sure partprobe cleans up stale partition devices
++parted -s $dev mklabel msdos mkpart primary ext2 0% 100% || fail=1
++if [ ! -e ${dev}1 ]; then
++    echo "Partition doesn't exist on loop device"
++    fail=1
++fi
++
++mke2fs -F $dev
++partprobe $dev || fail=1
++if [ -e ${dev}1 ]; then
++    echo "Partition should not exist on loop device"
++    fail=1
++fi
++
++# make sure new loop label removes old partitions > 1
++parted -s $dev mklabel msdos mkpart primary ext2 0% 50% mkpart primary ext2 50% 100% || fail=1
++parted -s $dev mklabel loop || fail=1
++if [ -e ${dev}2 ]; then
++    echo "Partition 2 not removed"
++    fail=1
++fi
++
++Exit $fail
+-- 
+1.9.0
+
diff --git a/parted.spec b/parted.spec
index 0489124..ab4cf08 100644
--- a/parted.spec
+++ b/parted.spec
@@ -4,7 +4,7 @@
 Summary: The GNU disk partition manipulation program
 Name:    parted
 Version: 3.1
-Release: 23%{?dist}
+Release: 24%{?dist}
 License: GPLv3+
 Group:   Applications/System
 URL:     http://www.gnu.org/software/parted
@@ -123,6 +123,18 @@ Patch0097: 0097-libparted-Fix-part-dupe-with-empty-name.patch
 Patch0098: 0098-tests-check-name-when-duplicating.patch
 Patch0099: 0099-tests-Add-ntfs-vfat-hfsplus-to-t1700-probe-test.patch
 Patch0100: 0100-GPT-strings-are-UCS-2LE-not-UTF-16.patch
+Patch0101: 0101-libparted-remove-last_usable_if_grown.patch
+Patch0102: 0102-tests-fix-t2310-dos-extended-2-sector-min-offset.sh.patch
+Patch0103: 0103-Fix-filesystem-detection-on-non-512-byte-sectors.patch
+Patch0200: 0104-libparted-don-t-detect-fat-and-ntfs-boot-sectors-as-.patch
+Patch0201: 0105-libparted-remove-old-partitions-first-before-adding-.patch
+Patch0202: 0106-libparted-remove-all-old-partitions-even-if-new-labe.patch
+Patch0203: 0107-libparted-fix-loop-labels-to-not-vanish.patch
+Patch0204: 0108-libparted-don-t-create-partition-on-loop-label.patch
+Patch0205: 0109-partprobe-do-not-skip-loop-labels.patch
+Patch0206: 0110-libparted-give-correct-partition-device-name-on-loop.patch
+Patch0207: 0111-libparted-don-t-trash-filesystem-when-writing-loop-l.patch
+Patch0208: 0112-tests-test-loop-labels.patch
 
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: e2fsprogs-devel
@@ -261,6 +273,21 @@ fi
 
 
 %changelog
+* Thu May 22 2014 Brian C. Lane <bcl at redhat.com> 3.1-24
+- Add some missing patches from master and the loop label fixes
+- tests: test loop labels (psusi)
+- libparted: don't trash filesystem when writing loop label (psusi)
+- libparted: give correct partition device name on loop labels (psusi)
+- partprobe: do not skip loop labels (psusi)
+- libparted: don't create partition on loop label (psusi)
+- libparted: fix loop labels to not vanish (psusi)
+- libparted: remove all old partitions, even if new label allows less (psusi)
+- libparted: remove old partitions *first* before adding new ones (psusi)
+- libparted: don't detect fat and ntfs boot sectors as dos MBR (psusi)
+- Fix filesystem detection on non 512 byte sectors (psusi)
+- tests: fix t2310-dos-extended-2-sector-min-offset.sh (psusi)
+- libparted: remove last_usable_if_grown (psusi)
+
 * Fri May 16 2014 Brian C. Lane <bcl at redhat.com> 3.1-23
 - Fix partition naming patch for big endian systems.
 


More information about the scm-commits mailing list