1. Leslie P. Polzer
  2. fdisk

Commits

Milko Krachounov  committed 00f1987

Implement nicer partition choosing for resize. Fix partition resizing, but we still have problems with moving and copying. Fix some other bugs. (fdisk@sv.gnu.org/fdisk--main--0--patch-45)
fdisk@sv.gnu.org/fdisk--main--0--patch-45
Keywords:

  • Participants
  • Parent commits 62dfe9e
  • Branches default

Comments (0)

Files changed (6)

File src/cfdisk.c

View file
 			if (!constraint || constraint->min_size == constraint->max_size) {
 				warning_waitkey(_("We can't resize this filesystem type"));
 				ped_file_system_close (fs);
+				if (constraint) ped_constraint_destroy(constraint);
 				return 0;
 			}
 			ped_file_system_close (fs);
 	pos.start.sector = (*part)->geom.start;
 	pos.end.sector = (*part)->geom.end;
 
-	if ((*part)->prev && (*part)->prev->type & PED_PARTITION_FREESPACE)
-		first = (*part)->prev->geom.start;
+	PedPartition *temp;
+	/* We want to look for free space fo the same type */
+	PedPartitionType desired = PED_PARTITION_FREESPACE |
+	                           ((*part)->type & PED_PARTITION_LOGICAL);
+	
+	temp = part_list_prev(*part,PED_PARTITION_METADATA);
+
+	if (temp && (temp->type & desired))
+		first = temp->geom.start;
 	else (*part)->geom.start;
 
-	if ((*part)->next && (*part)->next->type & PED_PARTITION_FREESPACE)
-		last = (*part)->next->geom.end;
+	temp = part_list_next(*part,PED_PARTITION_METADATA);
+	
+	if (temp && (temp->type & desired))
+		last = temp->geom.end;
 	else (*part)->geom.end;
 
 	if(!query_part_position(_("Where to place the resized partition"),

File src/common.c

View file
 			   the sector with the range so that the sector is equal
 			   to the desired result */
 			if (where == 'b') {
-				
+				/* As the start is not equal to the end of
+				   the partition, we will add some fuzz */
+				/* FIXME */
+				pos->start.range = ped_geometry_new(dev,
+							first, 64LL);
+
 				pos->start.sector = first;
 				/* Desired: end = first+length-1LL */
 				pos->end.sector = length;
 				move_sector(dev,&(pos->end),first-1LL);
 			}
 			else if (where == 'e') {
+				/* If the end has changed, we will add some fuzz */
+				if (pos->end.sector != last)
+					pos->end.range = ped_geometry_new(dev,
+							last-63LL, 64LL);
+
 				pos->end.sector = last;
 				/* Desired: start = last-length+1LL */ 
 				pos->start.sector = length;
 				pos->end.range = range;
 				move_sector(dev, (&pos->end),
 				            pos->start.sector-1LL);
+
 			}
 		}
 	}
         return 0;
 }
 
+/* TODO: This might be ok without commiting */
 int
 perform_rescue (PedDisk* disk, PedSector start, PedSector end, UIOpts opts)
 {
 	struct DOSGeomList *next;
 };
 
-int
+static int
 _fix_order_add_part (PedDisk *disk, struct DOSGeomList *data) {
 	int success;
 	PedConstraint *constraint;
 		get_part_type = uiquery->getparttype;
 }
 
+
+PedPartition *
+part_list_prev (PedPartition *part, PedPartitionType skip)
+{
+	if (!part)
+		return NULL;
+	do {
+		part = part->prev;
+	} while (part && (part->type & skip));
+	return part;
+}
+
+PedPartition *
+part_list_next (PedPartition *part, PedPartitionType skip)
+{
+	if (!part)
+		return NULL;
+	do {
+		part = part->next;
+	} while (part && (part->type & skip));
+	return part;
+}

File src/common.h

View file
                         int mkfs);
 extern int get_part_flag (const char* prompt, PedPartition*, PedPartitionFlag*);
 
+extern PedPartition* part_list_prev (PedPartition*, PedPartitionType skip);
+extern PedPartition* part_list_next (PedPartition*, PedPartitionType skip);
 
 #endif

File src/fdisk.c

View file
         fdisk_command_print_help (cmd); 
 }
 
+
+static int
+_disk_reread(PedDisk **disk) {
+	
+	PedDevice *dev = (*disk)->dev;
+
+	ped_disk_destroy(*disk);
+
+	*disk = ped_disk_new(dev);
+	uiquery.need_commit = 0;
+
+}
+
 static int
 do_check (PedDisk** disk)
 {
 	pos.end.sector = 0LL;
 	pos.start.range = NULL;
 	pos.end.range = NULL;
-	return perform_move (*disk, NULL, &pos, UI_CUSTOM_VALUES|UI_WARN_COMMIT);
+	if(!perform_move (*disk, NULL, &pos, UI_CUSTOM_VALUES|UI_WARN_COMMIT)) {
+		ped_exception_throw(PED_EXCEPTION_ERROR,
+		                    PED_EXCEPTION_CANCEL,
+		         _("Partition move failed"));
+		if (uiquery.need_commit)
+				_disk_reread(disk);
+		return 0;
+	}
+	return 1;
 }
 
 static int
 	
 		if (!ped_partition_is_active (part))
 	       		continue;
-
-		printf ("%s%d ", (*disk)->dev->path, part->num);
+	
+		/* If the last character is a digit, we add 'p' after the devname */
+		i = strlen((*disk)->dev->path) - 1;	
+		printf (isdigit((*disk)->dev->path[i]) ? 
+		        "%sp%d" :"%s%d ", (*disk)->dev->path, part->num);
 
 		if (ped_partition_get_flag(part,PED_PARTITION_BOOT))
 			printf("  *  ");
 static int
 do_resize (PedDisk** disk)
 {
+	Option query_opts[] = {
+		{ 's', _("don't move the beginning of the partition") },
+		{ 'b', _("place it at the beginning of the free space before it") },
+		{ 'e', _("place it at the end") },
+		{ 'c', _("select custom start and end") },
+		{ '\0', NULL }
+		
+	};
 	PartPos pos;
-	pos.start.sector = 0LL;
-	pos.end.sector = 0LL;
-	pos.start.range = NULL;
-	pos.end.range = NULL;
-	return perform_resize (*disk, NULL, &pos, UI_WARN_COMMIT | UI_CUSTOM_VALUES);
+	PedPartition *part = NULL, *temp;
+	PedSector first,last;
+	PedConstraint *constraint = NULL;
+	PedPartitionType desired;
+	UIOpts ui_opts = UI_WARN_COMMIT;
+
+	if (!get_partition (_("Partition"), *disk, &part))
+                	return 0;
+
+	/* TODO: Almost shared between fdisk and cfdisk, move to common */
+	if (part->fs_type) {
+		if (!part->fs_type->ops->resize) {
+			ped_exception_throw(PED_EXCEPTION_ERROR,
+			                    PED_EXCEPTION_CANCEL,
+			                    _("You can't resize this filesystem type."));
+			return 0;
+		}
+		else {
+			PedFileSystem *fs = ped_file_system_open(&part->geom);
+			constraint = ped_file_system_get_resize_constraint(fs);
+			if (!constraint || constraint->min_size == constraint->max_size)
+			{
+				ped_exception_throw(PED_EXCEPTION_ERROR,
+				                    PED_EXCEPTION_CANCEL,
+				       _("We can't resize this filesystem type"));
+				if (constraint) ped_constraint_destroy(constraint);
+				if (fs) ped_file_system_close (fs);
+				return 0;
+			}
+			if (fs) ped_file_system_close (fs);
+		}
+	}
+	else if (part->type != PED_PARTITION_EXTENDED) {
+		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+		                    _("No filesystem detected on the partition."));
+		return 0; 
+	}
+	pos.start.sector = part->geom.start;
+	pos.end.sector = part->geom.end;
+
+	desired = PED_PARTITION_FREESPACE |
+	                           (part->type & PED_PARTITION_LOGICAL);
+	
+	temp = part_list_prev(part,PED_PARTITION_METADATA);
+
+	if (temp && (temp->type & desired))
+		first = temp->geom.start;
+	else part->geom.start;
+
+	temp = part_list_next(part,PED_PARTITION_METADATA);
+	
+	if (temp && (temp->type & desired))
+		last = temp->geom.end;
+	else part->geom.end;
+
+	if(!query_part_position(_("Place for the resized partition"),
+	                        query_opts,&pos,first,last,(*disk)->dev,
+	                        constraint,&ui_opts)) {
+		if (constraint) ped_constraint_destroy (constraint);
+		return 0;
+	}
+	if (!perform_resize (*disk, part, &pos, ui_opts)) {
+		ped_exception_throw(PED_EXCEPTION_ERROR,
+		                    PED_EXCEPTION_CANCEL,
+		         _("Resize of the partition failed"));
+		if (!(ui_opts & UI_NO_FS_RESIZE) && uiquery.need_commit)
+				_disk_reread(disk);
+		return 0;
+	}
+	return 1;
 #if 0
 	PedPartition		*part = NULL;
 	PedFileSystem		*fs;
 static int
 do_unit (PedDisk** disk)
 {
+
 	if (cylinder_unit) {
 		printf ("%s\n", _("Changing display/entry units to sectors"));
 		ped_unit_set_default(PED_UNIT_SECTOR);
 static int
 do_copy(PedDisk** disk)
 {
-	return perform_cp (*disk, NULL, UI_WARN_COMMIT);
+	if (!perform_cp (*disk, NULL, UI_WARN_COMMIT)) {
+		ped_exception_throw(PED_EXCEPTION_ERROR,
+		                    PED_EXCEPTION_CANCEL,
+		         _("Partition copy failed"));
+		if (uiquery.need_commit)
+				_disk_reread(disk);
+		return 0;
+	}
+	return 1;
 }
 
 
 		str_list_create_unique ("v", _("v"), NULL),
 		do_move,
 		str_list_create (
-_(" v   move a partition."),
+_(" v   move a partition"),
 NULL), 
 		str_list_create (_(number_msg), _(start_end_msg), NULL), 1));
 	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("c", _("c"), NULL),
 		do_rescue,
 		str_list_create (
-_(" c   rescue a lost partition."),
+_(" c   rescue a lost partition"),
 NULL),
 		str_list_create (_(start_end_msg), NULL), 1));
 
 		str_list_create_unique ("z", _("z"), NULL),
 		do_resize,
 		str_list_create (
-_(" z   resize a partition and its file system."),
+_(" z   resize a partition and its file system"),
 NULL), NULL, 1));
 
 	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("h", _("h"), NULL),
 		do_check,
 		str_list_create (
-_(" h   check the consistency of a partition."),
+_(" h   check the consistency of a partition"),
 NULL), NULL, 1));
 
 	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("o", _("o"), NULL),
-		do_resize,
+		do_copy,
 		str_list_create (
-_(" o   copy the partition over another partition."),
+_(" o   copy the partition over another partition"),
 NULL), NULL, 1));
 
 
 		str_list_create (
 _(" m   print this menu"),
 NULL), NULL, 1));
-
+ }
 	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("p", _("p"), NULL),
 		do_print,
 		str_list_create (
 _(" q   quit without saving changes"),
 NULL), NULL, 1));
-  }
+  
 
         fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("r", _("r"), NULL),
 		NULL,
 		str_list_create (
-_(" r   return to the main menu."),
+_(" r   return to the main menu"),
 NULL), NULL, 1));
 
-  if (fdisk_compatibility_mode)
+
         fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("w", _("w"), NULL),
 		do_commit,
 	uiquery.getdisktype = NULL;
 	uiquery.getfstype = NULL;
 	/* TODO: Will we use this? */
-	uiquery.getpartpos = NULL;
+	uiquery.getpartpos = fdisk_get_partpos;
 	uiquery.need_commit = 0;
 	uiquery.timer = ped_timer_new (_timer_handler, &timer_context);
 	set_uicalls(&uiquery);

File src/ui.c

View file
 	return valid;
 }
 
-/* Struct for a single option, Linux fdisk-style */
-struct _Option {
-	int option;
-	char *description;
-};
-typedef struct _Option Option;
 
 int
 fdisk_command_line_get_option (const char* head, const Option* opts)
 } 
 
 int
+fdisk_get_partpos (const char* prompt, const void* context, const char *possibilities)
+{
+	
+	const Option *orig_opts = (Option *) context;
+	Option opts[5];
+	int i,j;
+	for (i=0, j=0; orig_opts[i].option && j < 5; i++) {
+		if (strchr(possibilities,orig_opts[i].option)) {
+			opts[j].option = orig_opts[i].option;
+			opts[j].description = orig_opts[i].description;
+			j++;
+		}
+	}
+	opts[j].option = 0;
+	
+	return fdisk_command_line_get_option(prompt, opts);
+}
+int
 fdisk_command_line_get_part_type (const char* prompt, const PedDisk *disk,
                                   PedPartitionType *type)
 {

File src/ui.h

View file
 #include "strlist.h"
 #include "ui.h"
 #include "command.h"
+
+
+/* Struct for a single option, Linux fdisk-style */
+struct _Option {
+	int option;
+	char *description;
+};
+typedef struct _Option Option;
+
 extern char*	fdisk_prog_name;
 extern int	fdisk_opt_script_mode;
 extern char* interface_name;
 extern int fdisk_command_line_get_part_type (const char* prompt, const PedDisk* disk,
 				      PedPartitionType* type);
 extern char* fdisk_command_line_peek_word ();
+extern int fdisk_command_line_get_option (const char* head, const Option* opts);
+extern int fdisk_get_partpos (const char* prompt, const void* context, 
+                              const char *possibilities);
 /*extern int fdisk_command_line_get_sector (const char* prompt, PedDevice* dev, PedSector* value,
 					  PedGeometry** range);*/
 extern int fdisk_init_ui ();