Anonymous avatar Anonymous 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:

Comments (0)

Files changed (6)

 			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"),
 			   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;
+}
                         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
         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);
 	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)
 {
 #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 ();
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.