Anonymous avatar Anonymous committed 56ca13d

Implement basic partition table verification. Fix choosing c/h/s (llint -> int). Fix the display of start and end sector in lfdisk. Remove some unneeded things. (fdisk@sv.gnu.org/fdisk--main--0--patch-52)
fdisk@sv.gnu.org/fdisk--main--0--patch-52
Keywords:

Comments (0)

Files changed (3)

 };
 #define DOS_DATA_SIZE sizeof(struct DosPDCopyMem)
 
-#define DO_NOT_SAVE (PED_PARTITION_FREESPACE | PED_PARTITION_METADATA)
+#define NOT_PARTITION (PED_PARTITION_FREESPACE | PED_PARTITION_METADATA)
 
 struct DOSGeomList {
 	PedGeometry geom;
 	/* We check that order of the partitions is really wrong */
 	for (walk = ped_disk_next_partition(disk,NULL); walk;
 	     walk = ped_disk_next_partition(disk,walk)) {
-		if (walk->type & DO_NOT_SAVE)
+		if (walk->type & NOT_PARTITION)
 			continue;
 		if (walk->type & PED_PARTITION_LOGICAL) {
 			j++;
 	/* 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)
+		if (walk->type & NOT_PARTITION)
 			continue;
 
 		/* We save the partition in the list */
 	return 1;
 }
 
+
+void
+check_partition_consistency (PedPartition *part)
+{
+	int end_cyl,end_head,end_sector;
+	char *part_chs = NULL;
+	part_chs = ped_unit_format_custom(part->disk->dev,part->geom.end,
+	                                  PED_UNIT_CHS);
+	sscanf(part_chs, "%d,%d,%d", &end_cyl, &end_head, &end_sector);
+	ped_free(part_chs);
+
+	/* We check that the partition ends at the cylinder boundary */
+	if (end_head != part->disk->dev->bios_geom.heads - 1 ||
+	    end_sector != part->disk->dev->bios_geom.sectors - 1)
+		ped_exception_throw(PED_EXCEPTION_WARNING, PED_EXCEPTION_OK,
+			_("Partition %i does not end on cylinder boundary."),
+			part->num);
+}
+
+void
+verify_partition_table (PedDisk *disk)
+{
+	/* One sector is used for the master boot record */
+	PedSector used_sectors = 1LL;
+	PedPartition *part;
+
+	/* We count the allocated sectors */
+	for (part = ped_disk_next_partition(disk,NULL); part;
+	     part = ped_disk_next_partition(disk,part)) {
+		if (part->type & NOT_PARTITION)
+			continue;
+		check_partition_consistency(part);
+
+		/* We don't want to count the extended partition */
+		if (part->type & PED_PARTITION_EXTENDED)
+			continue;
+
+		used_sectors += part->geom.length;
+		/* The logical partitions take an additional sector */
+		if (part->type & PED_PARTITION_LOGICAL)
+			used_sectors++;
+	}
+
+	/* If the used sectors are more than the available, issue a warning */
+	if (used_sectors > disk->dev->length)
+		ped_exception_throw(PED_EXCEPTION_WARNING, PED_EXCEPTION_OK,
+				_("Total allocated sectors %lld greater than "
+				"the maximum %lld"),
+				used_sectors, disk->dev->length);
+	else if (used_sectors < disk->dev->length)
+		ped_exception_throw(PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK,
+		                    _("%lld unallocated sectors"),
+		                    disk->dev->length - used_sectors);
+}
+
 char*
 partition_print_flags (PedPartition* part)
 {
 extern int perform_commit (PedDisk*, UIOpts);
 extern int perform_maximize (PedDisk*, PedPartition*);
 extern int fix_partition_order (PedDisk*);
+extern void check_partition_consistency (PedPartition *part);
+extern void verify_partition_table (PedDisk *disk);
+
 
 
 /* Additional functions */
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <limits.h>
 
 #ifdef ENABLE_MTRACE
 #include <mcheck.h>
 /* 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;
+int 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 "
 	for (part = ped_disk_next_partition (*disk, NULL); part;
 	     part = ped_disk_next_partition (*disk, part)) {
 
+		
 		cyl_start     = (part->geom.start / (total_cyl)) + 1; 
 		cyl_end       = (part->geom.end   / (total_cyl)) + 1;
 
-	  	if (unit == PED_UNIT_SECTOR) {	
-			start     = (part->geom.start / total_cyl 
-				    	* total_cyl) + sectors; 
-		        end       = part->geom.end / total_cyl * total_cyl;
+	  	if (unit == PED_UNIT_SECTOR) {
+			/* In Linux fdisk compatibility mode, display exact */
+			if (fdisk_compatibility_mode) {
+				start = part->geom.start;
+				end = part->geom.end; 
+			}
+			/* In fdisk, round up the sectors to cylinders */
+			else {	
+				start = (part->geom.start / total_cyl 
+				    		* total_cyl) + sectors; 
+		        	end   = part->geom.end / total_cyl * total_cyl;
+			}
 			blocks    = ((cyl_end * total_cyl) 
-					- ((part->num == 1) ? 
+						- ((part->num == 1) ? 
 			(cyl_start * sectors) : (cyl_start * total_cyl))) 
 					/ (1024 / sect_size);
 		} else {
 				printf ("%+4s %+9s ", _("5"), _("Extended"));
 			ped_device_end_external_access((*disk)->dev);
 		}
-		#if 0
-		/* Check to see if we have a boot flag. */
-		if (ped_partition_get_flag (part, PED_PARTITION_BOOT)) {
-	  		printf ("  *  ");
-			printf ("%10lld %11lld %11lu ", start, end, blocks);
-
-			char *type = (char *)ped_partition_type_get_name (part->type);
-			if (part->fs_type 
-			    && !strcmp (part->fs_type->name, "linux-swap"))
-				printf ("%+4s %+21s ", _("82"), _("Linux Swap / Solaris"));
-			else if (is_bsd_partition ((*disk)->dev->path, 
-				part->geom.start * sect_size, sect_size))
-				printf ("%+4s %+17s ", _("a5"), _("Free/Net/OpenBSD"));
-			else if (!strcmp (type, "primary")) 
-				printf ("%+4s %+6s ", _("83"), _("Linux"));
-			else if (!strcmp (type, "extended"))
-				printf ("%+4s %+9s ", _("5"), _("Extended"));
-		} else {
-			printf ("%15lld %11lld %11lld ", start, end, blocks);
-			char *type = (char *)ped_partition_type_get_name (part->type);
-			if (part->fs_type 
-			    && !strcmp (part->fs_type->name, "linux-swap"))
-				printf ("%+4s %+21s ", _("82"), _("Linux Swap / Solaris"));
-			else if (is_bsd_partition ((*disk)->dev->path, 
-				part->geom.start * sect_size, sect_size))
-				printf ("%+4s %+17s ", _("a5"), _("Free/Net/OpenBSD"));
-			else if (!strcmp (type, "primary")) 
-				printf ("%+4s %+6s ", _("83"), _("Linux"));
-			else if (!strcmp (type, "extended"))
-				printf ("%+4s %+9s ", _("5"), _("Extended"));
-		}
-		#endif
 		printf ("\n");
 		start = end = blocks = 0;
+		/* At the end we check the partition consistency for lfdisk */
+		if (fdisk_compatibility_mode)
+			check_partition_consistency(part);
 	}
 	ped_free (cyl_size);
         printf ("\n");
 	return 1;
 }
 
+
+
 static int
 do_fix_partition_order (PedDisk **disk)
 {
 	return perform_resize(*disk,part,&pos,UI_NO_FS_RESIZE);
 }
 
+static int
+do_verify(PedDisk **disk)
+{
+	verify_partition_table (*disk);
+	return 1;
+}
+
 static void
 _init_messages ()
 {
 _(" s   change number of sectors/track"),
 NULL), NULL, 1));
 
+  if (fdisk_compatibility_mode)
+	fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
+		str_list_create_unique ("v", _("v"), NULL),
+		do_verify,
+		str_list_create (
+_(" v   verify the partition table"),
+NULL), NULL, 1));
+
         fdisk_command_register (fdisk_ex_menu_commands, fdisk_command_create (
 		str_list_create_unique ("w", _("w"), NULL),
 		do_commit,
 _(" u   change display/entry units"),
 NULL), NULL, 1));
 
+  if (fdisk_compatibility_mode)
+	fdisk_command_register (fdisk_main_menu_commands, fdisk_command_create (
+		str_list_create_unique ("v", _("v"), NULL),
+		do_verify,
+		str_list_create (
+_(" v   verify the partition table"),
+NULL), NULL, 1));
+
         fdisk_command_register (fdisk_main_menu_commands, fdisk_command_create (
 		str_list_create_unique ("w", _("w"), NULL),
 		do_commit,
 	        			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;
+			case 'C': user_cyls = atoi(optarg); break;
+			case 'H': user_heads = atoi(optarg); break;
+			case 'S': user_sectors = atoi(optarg); break;
 		}
 	}
 
 			(*argc_ptr)--;
 			(*argv_ptr)++;
 		}
+		/* If sector size, cylnders, heads or sectors are specified on
+		   the command line */
 		if (fdisk_compatibility_mode) {
 			if (user_sectsize) {
 				/* This should be multiple of 512, checked at
 				dev->length = bytes / user_sectsize;	
 			}
 			if (user_sectors || user_heads) {
+				/* NOTE: PedSector is long long */
+				long long llcyl;
 				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);
+				llcyl = dev->length / 
+						((long long)dev->bios_geom.heads
+						* dev->bios_geom.sectors);
+				dev->bios_geom.cylinders = llcyl;
+				/* If it was truncated, use the max value,
+				   as Linux fdisk */
+				/* FIXME: Linux fdisk uses uint */
+				if (dev->bios_geom.cylinders != llcyl)
+					dev->bios_geom.cylinders = INT_MAX;
+				if (!dev->bios_geom.cylinders)
+					dev->bios_geom.cylinders = user_cyls;
 			}
 		}
 		
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.