Anonymous avatar Anonymous committed 85c17e5

Implement setting of sector size, number of cylinders, sectors and heads, and moving the beginning of the partition. (fdisk@sv.gnu.org/fdisk--main--0--patch-51)
fdisk@sv.gnu.org/fdisk--main--0--patch-51
Keywords:

Comments (0)

Files changed (6)

 .B -t, --list-partition-types
 displays a list of supported partition types and features.
 .PP
-The options -b, -C, -H and -S, taking one argument, are ignored for Linux fdisk compatibility. 
+The following options are available only to lfdisk.
+.TP
+.B -b, --sector-size=\fISIZE\fP
+Specify the sector size of the disk. Valid values are 512, 1024 and 2048. Should be used only on older kernels, which don't guess the correct sector size.
+.TP
+.B -C, --cylinders=\fICYLINDERS\fP
+Specify the number of cylinders of the disk. Currently does nothing, it is left for Linux fdisk compatibility.
+.TP
+.B -H, --heads=\fIHEADS\fP
+Specify the number of heads of the disk. Reasonable values are 255 or 16.
+.TP
+.B -S, --sectors=\fISECTORS\fP
+Specify the number of sectors per track. A reasonable value is 63.
 .SH BUGS
 Before editing a BSD disklabel, the partition with the disklabel should already exist on the disk and be detected by the OS. If you have created a BSD-type partition, you need to write the changes to the disk. If fdisk fails to notify the OS about the changes in partition table, you need to restart your computer. As fdisk tries to guess the device holding the BSD disklabel, it might fail to edit it at all, even if the OS has detected it. In this case you are adviced to simply open the device with fdisk directly. It is possible that it doesn't work on some operating systems.
 .PP
 @item @b{@minus{}t, @minus{}@minus{}list-partition-types}
 Displays a list of supported partition types and features.
 
-For compatibility with Linux fdisk, GNU fdisk also silently ignores options 
-@b{-b}, @b{-C}, @b{-H} and @b{-S}, all taking one parameter.
+@end table
+
+The following options are available only in lfdisk, for Linux fdisk compatibility.
+
+@table @code
+@item @b{@minus{}b, @minus{}@minus{}sector-size=}@i{SIZE}
+Specify the sector size of the disk. Valid values are 512, 1024 and
+2048. Should be used only on older kernels, which don't  guess  the
+correct sector size.
+
+
+@item @b{@minus{}C, @minus{}@minus{}cylinders=}@i{CYLINDERS}
+Specify  the  number of cylinders of the disk. Currently does nothing, it is left
+for Linux fdisk compatibility
+
+@item @b{@minus{}H, @minus{}@minus{}heads=}@i{HEADS}
+Specify the number of heads of the disk. Reasonable values are  255
+or 16.
+
+@item @b{@minus{}S, @minus{}@minus{}sectors=}@i{SECTORS}
+Specify  the number of sectors per track. A reasonable value is 63.
 
 @end table
 
+
 @node Commands and usage
 
 @section Commands and usage
 useful, when for example on an DOS partition table, the partitions have
 a wrong order and you want to order them in order they are placed on
 the disk.
+@item @b{b}
+Moves the beginning of the data in the partition. Asks for a new start
+of the partition and then changes the partition geometry.
+
+@item @b{c}
+Changes the number of the cylinders of the disk. 
+
+@item @b{h}
+Changes the number of the heads of the disk.
+
+@item @b{s}
+Changes the number of the sectors per track of the disk. 
 @end table
 
 
 	
 	
 
-	/* We save the primary partitions */
+	/* We save the partitions */
 	for (walk = ped_disk_next_partition(disk,NULL); walk;
 	     walk = ped_disk_next_partition(disk,walk)) {
 		if (walk->type & DO_NOT_SAVE)
 	{"interactive",	0, NULL, 'i'},
 	{"script",	0, NULL, 'p'},
 	{"sector-units",0, NULL, 'u'},
+	{"sector-size", 1, NULL, 'b'},
+	{"cylinders",	1, NULL, 'C'},
+	{"heads",	1, NULL, 'H'},
+	{"sectors",	1, NULL, 'S'},
 	{"list-partition-types", 0, NULL, 't'},
 	{"version",	0, NULL, 'v'},
 	{NULL,		0, NULL, 0}
 	{"gnu-fdisk",   N_("disable Linux fdisk compatibility mode")},
 	{"interactive",	N_("where necessary, prompts for user intervention")},
 	{"script",	N_("never prompts for user intervention")},
-	{"sector-units",N_("use sectors instead of cylinder as a default unit.")},
+	{"sector-units",N_("use sectors instead of cylinder as a default unit")},
+	{"sector-size", N_("specify the sector size in bytes")},
+	{"cylinders",	N_("specify the number of cylinders, actually does nothing")},
+	{"heads",	N_("in lfdisk, specify the number of heads of the disk")},
+	{"sectors",	N_("in lfdisk, specify the number of sectors per track")},
 	{"list-partition-types", N_("displays a list of supported partition types")},
 	{"version",	N_("displays the version")},
 	{NULL,		NULL}
 int fdisk_compatibility_mode = 0;
 int fdisk_opt_script_mode;
 int fdisk_list_table = 0;
+/* Used for -s option, NULL when there was no -s option */
 const char *fdisk_part_size = NULL;
 
+PedSector user_cyls = 0, user_sectors = 0, user_heads = 0, user_sectsize = 0;
+
 static char* number_msg = N_(
 "NUMBER is the partition number used by Linux.  On MS-DOS disk labels, the "
 "primary partitions number from 1 to 4, logical partitions from 5 onwards.\n");
 }
 
 static int
+do_dvh_mklabel (PedDisk** disk)
+{
+	PedDevice               *dev = (*disk)->dev; /* Save the address of dev, 
+							because we are going to 
+							destroy disk. */ 
+	const PedDiskType*	type = ped_disk_type_get ("dvh");
+
+	return perform_mklabel(dev,disk,type);
+}
+
+static int
 do_mklabel (PedDisk** disk)
 {
 	PedDevice               *dev = (*disk)->dev; /* Save the address of dev, 
 	PedSector		blocks;			
 	PedSector		sects_nbytes;
 
-	chs          = &((*disk)->dev)->hw_geom;
+	chs          = &((*disk)->dev)->bios_geom;
 	heads        = chs->heads;
 	sectors      = chs->sectors;
 	cylinders    = chs->cylinders;
 }
 
 static void
-print_partitio_size(PedDisk *disk)
+print_partition_size(PedDisk *disk)
 {
 	int t = atoi(fdisk_part_size);
 	PedPartition *part = ped_disk_get_partition(disk,t);
 		PedSector		heads;
 		PedSector		total_cyl;
 	
-		chs          = &(disk->dev)->hw_geom;
+		chs          = &(disk->dev)->bios_geom;
 		sectors      = chs->sectors;
 		heads        = chs->heads;
 		total_cyl    = heads * sectors;
 	fix_partition_order(*disk);
 }
 
+/* The next three are for lfdisk compatibility with fdisk */
+static int
+do_change_sectors(PedDisk **disk)
+{
+	PedSector sectors = (*disk)->dev->bios_geom.sectors;
+	if (fdisk_command_line_get_llinteger(_("Number of sectors"), &sectors)) {
+		(*disk)->dev->bios_geom.sectors = sectors;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+static int
+do_change_heads(PedDisk **disk)
+{
+	PedSector heads = (*disk)->dev->bios_geom.heads;
+	if (fdisk_command_line_get_llinteger(_("Number of heads"), &heads)) {
+		(*disk)->dev->bios_geom.heads = heads;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+static int
+do_change_cylinders(PedDisk **disk)
+{
+	PedSector cylinders = (*disk)->dev->bios_geom.cylinders;
+	if (fdisk_command_line_get_llinteger(_("Number of cylinders"), &cylinders)) {
+		(*disk)->dev->bios_geom.cylinders = cylinders;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+static int
+do_move_partition_beginning(PedDisk **disk)
+{
+	PedPartition *part = NULL;
+	PartPos pos;
+	if (!get_partition(_("Partition"), *disk, &part))
+		return 0;
+	pos.start.sector = part->geom.start;
+	pos.end.sector = part->geom.end;
+
+	pos.start.range = NULL;
+	pos.end.range = NULL;
+	
+	/* This gets the new start in sectors */
+	while (1) {
+		if (!fdisk_command_line_get_llinteger(_("New beginning of data"),
+						 &pos.start.sector))
+			return 0;
+		if (pos.start.sector < part->geom.start || 
+				pos.start.sector >= part->geom.end) 
+			printf(_("Value out of range."));
+		else
+			break;
+	}
+
+	return perform_resize(*disk,part,&pos,UI_NO_FS_RESIZE);
+}
+
 static void
 _init_messages ()
 {
 NULL), NULL, 1));
 
 
-  }
+  } 
+  if (fdisk_compatibility_mode)
+	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
+		str_list_create_unique ("b", _("b"), NULL),
+		do_move_partition_beginning,
+		str_list_create (
+_(" b   move beginning of data in a partition"),
+NULL), NULL, 1));
 
-
+  if (fdisk_compatibility_mode)
+	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
+		str_list_create_unique ("c", _("c"), NULL),
+		do_change_cylinders,
+		str_list_create (
+_(" c   change number of cylinders"),
+NULL), NULL, 1));
 
 	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("f", _("f"), NULL),
 _(" f   fix partition order"),
 NULL), NULL, 1));
 
+	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
+		str_list_create_unique ("g", _("g"), NULL),
+		do_dvh_mklabel,
+		str_list_create (
+_(" g   create an IRIX (SGI) partition table"),
+NULL), NULL, 1));
+
   if (fdisk_compatibility_mode)
   {
+	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
+		str_list_create_unique ("h", _("h"), NULL),
+		do_change_heads,
+		str_list_create (
+_(" h   change number of heads"),
+NULL), NULL, 1));
 
 	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("m", _("m"), NULL),
 _(" 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 ("s", _("s"), NULL),
+		do_change_sectors,
+		str_list_create (
+_(" s   change number of sectors/track"),
+NULL), NULL, 1));
 
         fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("w", _("w"), NULL),
 			          cylinder_unit = 0;
 			          break;
 			case 'v': _version (); break;
-			/* For Linux fdisk compatibility */
-			/*
-			case 'b': break;
-			case 'C': break;
-			case 'H': break;
-			case 'S': break;
-			*/
+			case 'b': 
+				user_sectsize = atoll(optarg);
+				if (user_sectsize <= 0 || user_sectsize % 512) {
+				        fdisk_usage_msg();
+	        			return 0;
+				}
+				break;
+			/* NOTE: user_cyls is actually not used ;) */
+			case 'C': user_cyls = atoll(optarg); break;
+			case 'H': user_heads = atoll(optarg); break;
+			case 'S': user_sectors = atoll(optarg); break;
 		}
 	}
 
 	else if (*argc_ptr) {
 		path = (*argv_ptr) [0];
 	}
+
 	/* specified on comand line? */
 	if (path) {
 		dev = ped_device_get (path);
 			printf(_("Unable to open %s\n"), path);
 			return NULL;
 		}
+		/* TODO: I have no idea why this is here, but I leave it as is */
 		if (*argc_ptr) {
 			(*argc_ptr)--;
 			(*argv_ptr)++;
 		}
-
+		if (fdisk_compatibility_mode) {
+			if (user_sectsize) {
+				/* This should be multiple of 512, checked at
+				   option parsing */
+				PedSector bytes = dev->sector_size * dev->length;
+				dev->sector_size = user_sectsize;
+				dev->length = bytes / user_sectsize;	
+			}
+			if (user_sectors || user_heads) {
+				if (user_sectors)
+					dev->bios_geom.sectors = user_sectors;
+				if (user_heads)
+					dev->bios_geom.heads = user_heads;
+				dev->bios_geom.cylinders
+					= dev->length / (dev->bios_geom.heads
+							* dev->bios_geom.sectors);
+			}
+		}
+		
 		if (!ped_device_open (dev)) {
 			printf(_("Unable to open %s\n"), path); 
 			return NULL;
 	        return 1;
 	/* Show the size of the partition */
 	if (fdisk_part_size) {
-		print_partitio_size(disk);
+		print_partition_size(disk);
 	}
 	/* List the specified disk. */
 	if (fdisk_list_table)
 int
 fdisk_command_line_get_integer (const char* prompt, int* value)
 {
-	char	def_str [10];
+	char	def_str [12];
 	char*	input;
 	int	valid;
 
-	snprintf (def_str, 10, "%d", *value);
+	snprintf (def_str, sizeof(def_str), "%d", *value);
 	input = fdisk_command_line_get_word (prompt, *value ? def_str : NULL,
 				       NULL, 1);
 	if (!input)
 	return valid;
 }
 
+fdisk_command_line_get_llinteger (const char* prompt, long long* value)
+{
+	char	def_str [22];
+	char*	input;
+	int	valid;
+
+	snprintf (def_str, sizeof(def_str), "%lld", *value);
+	input = fdisk_command_line_get_word (prompt, *value ? def_str : NULL,
+				       NULL, 1);
+	if (!input)
+		return 0;
+	valid = sscanf (input, "%lld", value);
+	free (input);
+	return valid;
+}
 
 int
 fdisk_command_line_get_option (const char* head, const Option* opts)
 /*extern int fdisk_command_line_get_disk_type (const char* prompt, const PedDiskType*(* value));*/
 /*extern int fdisk_command_line_get_device (const char* prompt, PedDevice** value);*/
 extern int fdisk_command_line_get_integer (const char* prompt, int* value);
+extern int fdisk_command_line_get_llinteger (const char* prompt, long long* value);
 extern int fdisk_command_line_get_part_type (const char* prompt, const PedDisk* disk,
 				      PedPartitionType* type);
 extern char* fdisk_command_line_peek_word ();
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.