[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#380226: NTFS (partition) not recreated correctly after resize:incorrect start sector



On further thinking, I realise there are several problems with the
patch:
1. It tries to probe even if open_filesystem is false (already
identified).
2. It can return after maximize_extended_partition() without rolling
that change back.
3. It doesn't check whether the existing invalid filesystem geometry
returned by the probe is valid.

This should fix those problems by combining all the work that's
conditional on the open_filesystem flag:

diff -u parted_server.c~ parted_server.c
--- parted_server.c~	2007-01-11 13:57:27.000000000 +0000
+++ parted_server.c	2007-03-01 05:02:02.000000000 +0000
@@ -703,19 +703,74 @@
         if (old_start == start && old_end == end)
                 return true;
         if (open_filesystem) {
+                PedGeometry *fs_geom;
                 deactivate_exception_handler();
                 fs = ped_file_system_open(&(part->geom));
                 activate_exception_handler();
                 log("opened file system: %s", NULL != fs ? "yes" : "no");
-                if (NULL != fs && (fs->geom->start < (part->geom).start
-                                   || fs->geom->end > (part->geom).end)) {
-                        ped_file_system_close(fs);
-                        fs = NULL;
+                if (NULL != fs) {
+                        fs_geom = fs->geom;
+                } else {
+                        PedFileSystemType *fs_type;
+                        fs_type = ped_file_system_probe(&(part->geom));
+                        log("probed file system: %s",
+                            NULL != fs_type ? "yes" : "no");
+                        if (NULL != fs_type) {
+                                fs_geom = ped_file_system_probe_specific
+                                        (fs_type, &(part->geom));
+                        } else {
+                                fs_geom = NULL;
+                        }
+                }
+                if (NULL != fs_geom && (fs_geom->start < (part->geom).start
+                                        || fs_geom->end > (part->geom).end)) {
+                        /* Filesystem is already outside the partition
+                         * so assume it is broken and do not constrain
+                         * resizing.
+                         */
+                        if (NULL != fs) {
+                                ped_file_system_close(fs);
+                                fs = NULL;
+                        } else {
+                                ped_geometry_destroy(fs_geom);
+                        }
+                        fs_geom = NULL;
+                        constraint = ped_constraint_any(disk->dev);
+                } else if (NULL != fs) {
+                        constraint = ped_file_system_get_resize_constraint(fs);
+                } else if (NULL != fs_geom) {
+                        PedAlignment start_align;
+                        PedGeometry full_dev;
+                        /* We cannot resize or move the fs but we can
+                         * move the end of the partition so long as it
+                         * contains the whole fs.
+                         */
+                        if (ped_alignment_init(&start_align,
+                                               fs_geom->start, 0)
+                            && ped_geometry_init(&full_dev, disk->dev,
+                                                 0, disk->dev->length - 1)) {
+                                constraint = ped_constraint_new(
+                                        &start_align,
+                                        ped_alignment_any,
+                                        &full_dev, &full_dev,
+                                        fs_geom->length,
+                                        disk->dev->length);
+                        } else {
+                                constraint = NULL;
+                        }
+                        ped_geometry_destroy(fs_geom);
+                } else {
+                        constraint = NULL;
                 }
-                if (NULL == fs && NULL != ped_file_system_probe(&(part->geom)))
-                        return false;
         } else {
                 fs = NULL;
+                constraint = ped_constraint_any(disk->dev);
+        }
+        if (NULL == constraint) {
+                log("failed to get resize constraint");
+                if (NULL != fs)
+                        ped_file_system_close(fs);
+                return false;
         }
         log("try to check the file system for errors");
         if (NULL != fs && !timered_file_system_check(fs)) {
@@ -727,10 +782,6 @@
         log("successfully checked");
         if (part->type & PED_PARTITION_LOGICAL)
                 maximize_extended_partition(disk);
-        if (NULL != fs)
-                constraint = ped_file_system_get_resize_constraint(fs);
-        else
-                constraint = ped_constraint_any(disk->dev);
         if (!ped_disk_set_partition_geom(disk, part, constraint, start, end))
                 result = false;
         else if (NULL == fs)
-- END --

Ben.

-- 
Ben Hutchings
Quantity is no substitute for quality, but it's the only one we've got.

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: