Curtis Gedak wrote:
> The script t3000-resize-fat.sh generates the same results for when I
> use parted-1.9.0.
>
> After some testing, it appears that parted does not like to resize
> FAT32 file systems if they are smaller than 256MB.
>
> By making the below posted changes to the script I was able to create
> a FAT32 file system of about 256 MB in size (aligned to a cylinder),
> and then successfully grow it by about 8MB (one cylinder).
>
> Hope this helps :-)
> Curtis Gedak

Hmm...
I tried what you suggested, but it still doesn't work with 1.9.
[however, I did track down one bug: two changes that recently
 moved from next to master modified FAT file system handling,
 and one introduced a bug.  I expect to revert them soon.]

Are you sure that your final resize succeeded?
If so, please show the actual commands you used
as well as before and after results of running this:

    parted -s $dev u s p

(I tried with 1.9 built from source, and the 1.8.8 from Fedora 11 as
well as the one from debian unstable -- all with this same result)
Here are the commands I used:

    dev=/dev/sde
    parted -s $dev mklabel gpt
    parted -s $dev mkpart primary fat32 63s 530144s

    # if needed, wait for the partition device (e.g., /dev/sdd1) to appear
    mkfs.vfat -F 32 ${dev}1
    parted -s $dev resize 1 63s 546147s

That final parted invocation always fails with this:

    No Implementation: GNU Parted cannot resize this partition to this size.
    We're working on it!

BTW, David Cantrell mentioned that HFS and HFS+ resize support
is in a similar position, so parted will have to retain it, too.

  http://bugzilla.redhat.com/523954#c3

For reference, here are the patches I'm looking at, now:

Add the test:
  [1/4] tests: attempt to resize a FAT file system
your changes:
  [2/4] tests: make t3000-resize-fat.sh pass
revert the fat FS changes:
  [3/4] Revert "Fix compile failures."
  [4/4] Revert "Add fat support for sector_size > 512."


>From a1aa3112c0ff99269f3d9f37ac8bdcbbb7c1630a Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email protected]>
Date: Sat, 19 Sep 2009 08:22:20 +0200
Subject: [PATCH 1/4] tests: attempt to resize a FAT file system

* tests/t3000-resize-fat.sh: New file.
---
 tests/t3000-resize-fat.sh |   66 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100755 tests/t3000-resize-fat.sh

diff --git a/tests/t3000-resize-fat.sh b/tests/t3000-resize-fat.sh
new file mode 100755
index 0000000..496e15f
--- /dev/null
+++ b/tests/t3000-resize-fat.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+# Copyright (C) 2009 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/>.
+
+test_description='exercise the resize sub-command'
+
+: ${srcdir=.}
+. $srcdir/test-lib.sh
+
+require_512_byte_sector_size_
+dev=$DEVICE_TO_ERASE
+
+N=62M
+
+test_expect_success \
+    'create a partition table' \
+    'parted -s $dev mklabel gpt > out 2>&1'
+test_expect_success 'expect no output' 'compare out /dev/null'
+
+test_expect_success \
+    'create an empty FAT partition' \
+    'parted -s $dev mkpart primary fat32 50s 70000s > out 2>&1'
+test_expect_success 'expect no output' 'compare out /dev/null'
+
+test_expect_success \
+    'print partition table' \
+    'parted -m -s $dev u b p > out 2>&1'
+
+# FIXME: check expected output
+
+# There's a race condition here: on udev-based systems, the partition#1
+# device, ${dev}1 (i.e., /dev/sde1) is not created immediately, and
+# without some delay, this mount command would fail.  Using a flash card
+# as $dev, the loop below typically iterates 7-20 times.
+test_expect_success \
+    'wait for new partition device to appear' \
+    'i=0; while :; do
+            test -e "${dev}1" && break; test $i = 90 && break;
+           i=$(expr $i + 1); done; test $i != 90'
+
+test_expect_success \
+    'create the file system' \
+    'mkfs.vfat -F 32 ${dev}1'
+
+test_expect_success \
+    'resize that file system' \
+    'parted -s $dev resize 1 50s 71000s'
+
+test_expect_success \
+    'print partition table' \
+    'parted -m -s $dev u b p'
+
+test_done
--
1.6.5.rc2.177.ga9dd6


>From 3168100b013b99757755a549f4ac1190eed9ec50 Mon Sep 17 00:00:00 2001
From: Curtis Gedak <[email protected]>
Date: Thu, 24 Sep 2009 22:56:40 +0200
Subject: [PATCH 2/4] tests: make t3000-resize-fat.sh pass

* tests/t3000-resize-fat.sh: Adjust starting partition offset
to be on a cylinder boundary, and increase the partition size
to be larger than 256 MiB.  When resizing, choose the new size
to be exactly one cylinder (8MiB) larger than the original.
---
 tests/t3000-resize-fat.sh |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/t3000-resize-fat.sh b/tests/t3000-resize-fat.sh
index 496e15f..df8ae43 100755
--- a/tests/t3000-resize-fat.sh
+++ b/tests/t3000-resize-fat.sh
@@ -31,8 +31,8 @@ test_expect_success \
 test_expect_success 'expect no output' 'compare out /dev/null'

 test_expect_success \
-    'create an empty FAT partition' \
-    'parted -s $dev mkpart primary fat32 50s 70000s > out 2>&1'
+    'create an empty FAT partition, cylinder aligned and of size > 256 MB' \
+    'parted -s $dev mkpart primary fat32 63s 530144s > out 2>&1'
 test_expect_success 'expect no output' 'compare out /dev/null'

 test_expect_success \
@@ -56,8 +56,8 @@ test_expect_success \
     'mkfs.vfat -F 32 ${dev}1'

 test_expect_success \
-    'resize that file system' \
-    'parted -s $dev resize 1 50s 71000s'
+    'resize that file system to be one cylinder (8MiB) larger' \
+    'parted -s $dev resize 1 63s 546147s'

 test_expect_success \
     'print partition table' \
--
1.6.5.rc2.177.ga9dd6


>From 80957c0c282278c71648d97288482928412b5a30 Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email protected]>
Date: Fri, 25 Sep 2009 08:53:18 +0200
Subject: [PATCH 3/4] Revert "Fix compile failures."

This reverts commit 7603e404ee60f2f892be380a23c390f4638f451f.
---
 libparted/fs/fat/fat.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libparted/fs/fat/fat.c b/libparted/fs/fat/fat.c
index 59c8ef6..94b3981 100644
--- a/libparted/fs/fat/fat.c
+++ b/libparted/fs/fat/fat.c
@@ -114,7 +114,7 @@ fat_set_frag_sectors (PedFileSystem* fs, PedSector 
frag_sectors)
    storage.  If the read fails, free the memory and return zero without
    modifying *BUF.  Otherwise, set *BUF to the new buffer and return 1.  */
 static int
-read_sector (const PedDevice *dev, PedSector sector_num, void **buf)
+read_sector (const PedDevice *dev, PedSector sector_num, char **buf)
 {
        char *b = ped_malloc (dev->sector_size);
        PED_ASSERT (b != NULL, return 0);
@@ -134,7 +134,7 @@ static int
 fat_boot_sector_read_2 (FatBootSector* fbs, char **sector_buf,
                         const PedGeometry *geom)
 {
-       void *buf;
+       char *buf;
        *sector_buf = NULL;
        if (!read_sector (geom->dev, 0, &buf))
                return 0;
--
1.6.5.rc2.177.ga9dd6


>From e3f76e1624a38319993688601d7444e82403ad82 Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email protected]>
Date: Fri, 25 Sep 2009 08:53:30 +0200
Subject: [PATCH 4/4] Revert "Add fat support for sector_size > 512."

This reverts commit 14395c356664a3b88f3929a6a3ad69bca374f70d.
---
 libparted/fs/fat/bootsector.c |   56 ++++++++++++++-------------------------
 libparted/fs/fat/fat.c        |   58 +++-------------------------------------
 libparted/fs/fat/fat.h        |    2 -
 3 files changed, 25 insertions(+), 91 deletions(-)

diff --git a/libparted/fs/fat/bootsector.c b/libparted/fs/fat/bootsector.c
index cab83be..c8e67b8 100644
--- a/libparted/fs/fat/bootsector.c
+++ b/libparted/fs/fat/bootsector.c
@@ -27,10 +27,21 @@
 #include <fcntl.h>
 #include <errno.h>

+/* Reads in the boot sector (superblock), and does a minimum of sanity
+ * checking.  The goals are:
+ *     - to detect fat file systems, even if they are damaged [i.e. not
+ * return an error / throw an exception]
+ *     - to fail detection if there's not enough information for
+ * fat_boot_sector_probe_type() to work (or possibly crash on a divide-by-zero)
+ */
 int
-fat_boot_sector_is_sane (const FatBootSector* bs)
+fat_boot_sector_read (FatBootSector* bs, const PedGeometry *geom)
 {
        PED_ASSERT (bs != NULL, return 0);
+       PED_ASSERT (geom != NULL, return 0);
+
+       if (!ped_geometry_read (geom, bs, 0, 1))
+               return 0;

        if (PED_LE16_TO_CPU (bs->boot_sign) != 0xAA55) {
                ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
@@ -77,25 +88,6 @@ fat_boot_sector_is_sane (const FatBootSector* bs)
        return 1;
 }

-/* Reads in the boot sector (superblock), and does a minimum of sanity
- * checking.  The goals are:
- *     - to detect fat file systems, even if they are damaged [i.e. not
- * return an error / throw an exception]
- *     - to fail detection if there's not enough information for
- * 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)
-{
-       PED_ASSERT (bs != NULL, return 0);
-       PED_ASSERT (geom != NULL, return 0);
-
-       if (!ped_geometry_read (geom, bs, 0, 1))
-               return 0;
-
-       return fat_boot_sector_is_sane (bs);
-}
-
 /*
     Don't trust the FAT12, FAT16 or FAT32 label string.
  */
@@ -391,22 +383,14 @@ fat_boot_sector_write (const FatBootSector* bs, 
PedFileSystem* fs)

        PED_ASSERT (bs != NULL, return 0);

-       /* Allocate a sector-sized buffer and copy bs into it
-          at the beginning.  Fill any remainder with zeros.  */
-       size_t buf_len = fs->geom->dev->sector_size;
-       char *buf = ped_malloc (buf_len);
-       memcpy (buf, bs, sizeof *bs);
-       memset (buf + sizeof *bs, 0, buf_len - sizeof *bs);
-
-       int write_ok
-         = (ped_geometry_write (fs->geom, buf, 0, 1)
-            && (fs_info->fat_type != FAT_TYPE_FAT32
-                || ped_geometry_write (fs->geom, buf,
-                                       fs_info->boot_sector_backup_offset, 
1)));
-       free (buf);
-       if (write_ok)
-               ped_geometry_sync (fs->geom);
-       return write_ok;
+       if (!ped_geometry_write (fs->geom, bs, 0, 1))
+               return 0;
+       if (fs_info->fat_type == FAT_TYPE_FAT32) {
+               if (!ped_geometry_write (fs->geom, bs,
+                                        fs_info->boot_sector_backup_offset, 1))
+                       return 0;
+       }
+       return ped_geometry_sync (fs->geom);
 }

 int
diff --git a/libparted/fs/fat/fat.c b/libparted/fs/fat/fat.c
index 94b3981..ada2d62 100644
--- a/libparted/fs/fat/fat.c
+++ b/libparted/fs/fat/fat.c
@@ -109,45 +109,6 @@ fat_set_frag_sectors (PedFileSystem* fs, PedSector 
frag_sectors)
        return 1;
 }

-/* FIXME: factor out this function: copied from dos.c
-   Read sector, SECTOR_NUM (which has length DEV->sector_size) into malloc'd
-   storage.  If the read fails, free the memory and return zero without
-   modifying *BUF.  Otherwise, set *BUF to the new buffer and return 1.  */
-static int
-read_sector (const PedDevice *dev, PedSector sector_num, char **buf)
-{
-       char *b = ped_malloc (dev->sector_size);
-       PED_ASSERT (b != NULL, return 0);
-       if (!ped_device_read (dev, b, sector_num, 1)) {
-               free (b);
-               return 0;
-       }
-       *buf = b;
-       return 1;
-}
-
-/* Just like fat_boot_sector_read, but works with sector_size > 512.
-   Upon success, set *SECTOR_BUF to the malloc'd sector_size-byte buffer,
-   and copy the first bytes of that buffer into FBS.  Upon success,
-   the caller must free *SECTOR_BUF.  */
-static int
-fat_boot_sector_read_2 (FatBootSector* fbs, char **sector_buf,
-                        const PedGeometry *geom)
-{
-       char *buf;
-       *sector_buf = NULL;
-       if (!read_sector (geom->dev, 0, &buf))
-               return 0;
-       if (!fat_boot_sector_is_sane (buf)) {
-               free (buf);
-               return 0;
-       }
-       *sector_buf = buf;
-       if (fbs)
-               memcpy (fbs, buf, sizeof *fbs);
-       return 1;
-}
-
 PedGeometry*
 fat_probe (PedGeometry* geom, FatType* fat_type)
 {
@@ -160,8 +121,7 @@ fat_probe (PedGeometry* geom, FatType* fat_type)
                goto error;
        fs_info = (FatSpecific*) fs->type_specific;

-       char *s0;
-       if (!fat_boot_sector_read_2 (&fs_info->boot_sector, &s0, 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))
                goto error_free_fs;
@@ -171,12 +131,10 @@ fat_probe (PedGeometry* geom, FatType* fat_type)
                                   fs_info->sector_count);

        fat_free (fs);
-       free (s0);
        return result;

 error_free_fs:
        fat_free (fs);
-       free (s0);
 error:
        return NULL;
 }
@@ -215,9 +173,7 @@ fat_clobber (PedGeometry* geom)
 {
        FatBootSector           boot_sector;

-       // FIXME: remove this comment: ARGH: clobbers stack when sector_size > 
512
-       char *s0;
-       if (!fat_boot_sector_read_2 (&boot_sector, &s0, geom))
+       if (!fat_boot_sector_read (&boot_sector, geom))
                return 1;

        boot_sector.system_id[0] = 0;
@@ -227,9 +183,7 @@ fat_clobber (PedGeometry* geom)
        if (boot_sector.u.fat32.fat_name[0] == 'F')
                boot_sector.u.fat32.fat_name[0] = 0;

-       int write_ok = ped_geometry_write (geom, s0, 0, 1);
-       free (s0);
-       return write_ok;
+        return ped_geometry_write (geom, &boot_sector, 0, 1);
 }

 static int
@@ -266,8 +220,7 @@ fat_open (PedGeometry* geom)
                goto error;
        fs_info = (FatSpecific*) fs->type_specific;

-       char *s0;
-       if (!fat_boot_sector_read_2 (&fs_info->boot_sector, &s0, 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))
                goto error_free_fs;
@@ -286,7 +239,6 @@ fat_open (PedGeometry* geom)
        if (!fat_collect_cluster_info (fs))
                goto error_free_buffers;

-       free (s0);
        return fs;

 error_free_buffers:
@@ -294,7 +246,6 @@ error_free_buffers:
 error_free_fat_table:
        fat_table_destroy (fs_info->fat);
 error_free_fs:
-       free (s0);
        fat_free (fs);
 error:
        return NULL;
@@ -936,3 +887,4 @@ ped_file_system_fat_done ()
        ped_file_system_type_unregister (&fat16_type);
        ped_file_system_type_unregister (&fat32_type);
 }
+
diff --git a/libparted/fs/fat/fat.h b/libparted/fs/fat/fat.h
index 1be2979..d749bc8 100644
--- a/libparted/fs/fat/fat.h
+++ b/libparted/fs/fat/fat.h
@@ -155,6 +155,4 @@ extern int fat_resize (PedFileSystem* fs, PedGeometry* 
geom, PedTimer* timer);

 extern int fat_set_frag_sectors (PedFileSystem* fs, PedSector frag_sectors);

-extern int fat_boot_sector_is_sane (const FatBootSector* bs);
-
 #endif /* FAT_H_INCLUDED */
--
1.6.5.rc2.177.ga9dd6

_______________________________________________
parted-devel mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/parted-devel

Reply via email to