c832e53
--- util-linux-2.13-pre6/fdisk/fdisk.c.gpt	2005-11-24 15:30:36.000000000 +0100
c832e53
+++ util-linux-2.13-pre6/fdisk/fdisk.c	2005-11-24 15:30:36.000000000 +0100
169b953
@@ -34,6 +34,8 @@
169b953
 #include <linux/blkpg.h>
169b953
 #endif
169b953
 
169b953
+#include "gpt.h"
169b953
+
169b953
 static void delete_partition(int i);
169b953
 
169b953
 #define hex_val(c)	({ \
169b953
@@ -2400,6 +2402,14 @@
169b953
 }
169b953
 
169b953
 static void
169b953
+gpt_warning(char *dev)
169b953
+{
169b953
+	if (gpt_probe_signature_devname(dev))
169b953
+		fprintf(stderr, _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
169b953
+			"The util fdisk doesn't support GPT. Use GNU Parted.\n\n"), dev);
169b953
+}
169b953
+
169b953
+static void
169b953
 try(char *device, int user_specified) {
169b953
 	int gb;
169b953
 
169b953
@@ -2409,6 +2419,7 @@
169b953
 	if (!user_specified)
169b953
 		if (is_ide_cdrom_or_tape(device))
169b953
 			return;
169b953
+	gpt_warning(device);
169b953
 	if ((fd = open(disk_device, type_open)) >= 0) {
169b953
 		gb = get_boot(try_only);
169b953
 		if (gb > 0) { /* I/O error */
169b953
@@ -2470,6 +2481,8 @@
169b953
 	printf(_("%c: unknown command\n"), c);
169b953
 }
169b953
 
169b953
+
169b953
+
169b953
 int
169b953
 main(int argc, char **argv) {
169b953
 	int j, c;
169b953
@@ -2574,6 +2587,7 @@
169b953
 
169b953
 		for (j = optind; j < argc; j++) {
169b953
 			disk_device = argv[j];
169b953
+			gpt_warning(disk_device);
169b953
 			if ((fd = open(disk_device, type_open)) < 0)
169b953
 				fatal(unable_to_open);
169b953
 			if (disksize(fd, &size))
169b953
@@ -2594,6 +2608,7 @@
169b953
 	else
169b953
 		fatal(usage2);
169b953
 
169b953
+	gpt_warning(disk_device);
169b953
 	get_boot(fdisk);
169b953
 
169b953
 	if (osf_label) {
c832e53
--- /dev/null	2005-11-14 15:52:26.044616250 +0100
c832e53
+++ util-linux-2.13-pre6/fdisk/gpt.h	2005-11-24 15:30:36.000000000 +0100
169b953
@@ -0,0 +1,9 @@
169b953
+
169b953
+#ifndef __GPT_H__
169b953
+#define __GPT_H__
169b953
+
169b953
+extern int gpt_probe_signature_fd(int fd);
169b953
+extern int gpt_probe_signature_devname(char *devname);
169b953
+
169b953
+#endif /* __GPT_H__ */
169b953
+
c832e53
--- util-linux-2.13-pre6/fdisk/Makefile.am.gpt	2005-10-16 14:12:52.000000000 +0200
c832e53
+++ util-linux-2.13-pre6/fdisk/Makefile.am	2005-11-24 15:31:42.000000000 +0100
35b2031
@@ -5,13 +5,13 @@
169b953
 sbin_PROGRAMS = fdisk
169b953
 man_MANS = fdisk.8
c832e53
 fdisk_SOURCES = fdisk.c disksize.c fdiskbsdlabel.c fdisksgilabel.c \
169b953
-	fdisksunlabel.c fdiskaixlabel.c i386_sys_types.c partname.c
169b953
+	fdisksunlabel.c fdiskaixlabel.c i386_sys_types.c partname.c gpt.c
169b953
 
169b953
 if !SPARC
169b953
 
169b953
 sbin_PROGRAMS += sfdisk
169b953
 man_MANS += sfdisk.8
169b953
-sfdisk_SOURCES = sfdisk.c disksize.c i386_sys_types.c partname.c
169b953
+sfdisk_SOURCES = sfdisk.c disksize.c i386_sys_types.c partname.c gpt.c
169b953
 
169b953
 if USE_SLANG
169b953
 sbin_PROGRAMS += cfdisk
c832e53
--- util-linux-2.13-pre6/fdisk/fdisk.8.gpt	2005-11-24 15:30:36.000000000 +0100
c832e53
+++ util-linux-2.13-pre6/fdisk/fdisk.8	2005-11-24 15:30:36.000000000 +0100
169b953
@@ -42,6 +42,11 @@
169b953
 partition tables.
169b953
 It understands DOS type partition tables and BSD or SUN type disklabels.
169b953
 
169b953
+.B fdisk 
169b953
+doesn't understand GUID Partition Table (GPT) and 
169b953
+it is not designed for large partitions. In particular case use more advanced GNU 
169b953
+.B parted(8).
169b953
+
169b953
 The
169b953
 .I device
169b953
 is usually one of the following:
c832e53
--- util-linux-2.13-pre6/fdisk/sfdisk.8.gpt	2004-12-31 17:28:30.000000000 +0100
c832e53
+++ util-linux-2.13-pre6/fdisk/sfdisk.8	2005-11-24 15:30:36.000000000 +0100
169b953
@@ -18,6 +18,11 @@
169b953
 on a device, check the partitions on a device, and - very dangerous -
169b953
 repartition a device.
169b953
 
169b953
+.B sfdisk 
169b953
+doesn't understand GUID Partition Table (GPT) and 
169b953
+it is not designed for large partitions. In particular case use more advanced GNU 
169b953
+.B parted(8).
169b953
+
169b953
 .SS "List Sizes"
169b953
 .BI "sfdisk \-s " partition
169b953
 gives the size of
c832e53
--- /dev/null	2005-11-14 15:52:26.044616250 +0100
c832e53
+++ util-linux-2.13-pre6/fdisk/gpt.c	2005-11-24 15:30:36.000000000 +0100
169b953
@@ -0,0 +1,287 @@
169b953
+/*
169b953
+    GPT (GUID Partition Table) signature detection. Based on libparted and 
169b953
+    util-linux/partx.
169b953
+  
169b953
+    Warning: this code doesn't do all GPT checks (CRC32, Protective MBR, ..). It's
169b953
+             really GPT signature detection only.
169b953
+    
169b953
+    -- Karel Zak <kzak@redhat.com> (Jun-2-2005)
169b953
+
169b953
+*/
169b953
+
169b953
+#include <stdio.h>
169b953
+#include <string.h>
169b953
+#include <stdlib.h>
169b953
+#include <inttypes.h>
169b953
+#include <sys/stat.h>
169b953
+#include <sys/ioctl.h>
169b953
+#include <sys/utsname.h>
169b953
+#include <sys/types.h>
169b953
+#include <fcntl.h>
169b953
+#include <unistd.h>
169b953
+#include <errno.h>
169b953
+#include <linux/fs.h>
169b953
+
169b953
+#include "gpt.h"
169b953
+
169b953
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
169b953
+#define SECTOR_SIZE	512	/* default */
169b953
+
169b953
+#define _GET_BYTE(x, n)		( ((x) >> (8 * (n))) & 0xff )
169b953
+
169b953
+#define _PED_SWAP64(x)		( (_GET_BYTE(x, 0) << 56)	\
169b953
+				+ (_GET_BYTE(x, 1) << 48)	\
169b953
+				+ (_GET_BYTE(x, 2) << 40)	\
169b953
+				+ (_GET_BYTE(x, 3) << 32)	\
169b953
+				+ (_GET_BYTE(x, 4) << 24)	\
169b953
+				+ (_GET_BYTE(x, 5) << 16)	\
169b953
+				+ (_GET_BYTE(x, 6) << 8)	\
169b953
+				+ (_GET_BYTE(x, 7) << 0) )
169b953
+
169b953
+#define PED_SWAP64(x)           ((uint64_t) _PED_SWAP64( (uint64_t) (x) ))
169b953
+
169b953
+#if __BYTE_ORDER == __LITTLE_ENDIAN
169b953
+# define CPU_TO_LE64(x)	(x)
169b953
+#else
169b953
+# define CPU_TO_LE64(x)	PED_SWAP64(x)
169b953
+#endif
169b953
+
169b953
+#define BLKSSZGET  _IO(0x12,104) /* get block device sector size */
169b953
+#define BLKGETLASTSECT  _IO(0x12,108)   /* get last sector of block device */
169b953
+#define BLKGETSIZE _IO(0x12,96)	/* return device size */
169b953
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)	/* return device size in bytes (u64 *arg) */
169b953
+
169b953
+#define GPT_HEADER_SIGNATURE 0x5452415020494645LL
169b953
+#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
169b953
+
169b953
+typedef struct {
169b953
+        uint32_t time_low;
169b953
+        uint16_t time_mid;
169b953
+        uint16_t time_hi_and_version;
169b953
+        uint8_t  clock_seq_hi_and_reserved;
169b953
+        uint8_t  clock_seq_low;
169b953
+        uint8_t  node[6];
169b953
+} /* __attribute__ ((packed)) */ efi_guid_t;
169b953
+/* commented out "__attribute__ ((packed))" to work around gcc bug (fixed
169b953
+ * in gcc3.1): __attribute__ ((packed)) breaks addressing on initialized
169b953
+ * data.  It turns out we don't need it in this case, so it doesn't break
169b953
+ * anything :)
169b953
+ */
169b953
+
169b953
+typedef struct _GuidPartitionTableHeader_t {
169b953
+	uint64_t Signature;
169b953
+	uint32_t Revision;
169b953
+	uint32_t HeaderSize;
169b953
+	uint32_t HeaderCRC32;
169b953
+	uint32_t Reserved1;
169b953
+	uint64_t MyLBA;
169b953
+	uint64_t AlternateLBA;
169b953
+	uint64_t FirstUsableLBA;
169b953
+	uint64_t LastUsableLBA;
169b953
+	efi_guid_t DiskGUID;
169b953
+	uint64_t PartitionEntryLBA;
169b953
+	uint32_t NumberOfPartitionEntries;
169b953
+	uint32_t SizeOfPartitionEntry;
169b953
+	uint32_t PartitionEntryArrayCRC32;
169b953
+	uint8_t Reserved2[512 - 92];
169b953
+} __attribute__ ((packed)) GuidPartitionTableHeader_t;
169b953
+
169b953
+struct blkdev_ioctl_param {
169b953
+        unsigned int block;
169b953
+        size_t content_length;
169b953
+        char * block_contents;
169b953
+};
169b953
+
169b953
+static int
169b953
+_get_linux_version (void)
169b953
+{
169b953
+	static int kver = -1;
169b953
+	struct utsname uts;
169b953
+	int major;
169b953
+	int minor;
169b953
+	int teeny;
169b953
+
169b953
+	if (kver != -1)
169b953
+		return kver;
169b953
+	if (uname (&uts))
169b953
+		return kver = 0;
169b953
+	if (sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny) != 3)
169b953
+		return kver = 0;
169b953
+	return kver = KERNEL_VERSION (major, minor, teeny);
169b953
+}
169b953
+
169b953
+static unsigned int
169b953
+_get_sector_size (int fd)
169b953
+{
169b953
+	unsigned int sector_size;
169b953
+
169b953
+	if (_get_linux_version() < KERNEL_VERSION (2,3,0))
169b953
+		return SECTOR_SIZE;
169b953
+	if (ioctl (fd, BLKSSZGET, &sector_size))
169b953
+		return SECTOR_SIZE;
169b953
+	return sector_size;
169b953
+}
169b953
+
169b953
+static uint64_t
169b953
+_get_num_sectors(int fd)
169b953
+{
169b953
+	int version = _get_linux_version();
169b953
+	unsigned long	size;
169b953
+	uint64_t bytes=0;
169b953
+
169b953
+	if (version >= KERNEL_VERSION(2,5,4) || 
169b953
+		(version <  KERNEL_VERSION(2,5,0) && 
169b953
+		 version >= KERNEL_VERSION (2,4,18)))
169b953
+	{
169b953
+                if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) 
169b953
+                        return bytes / _get_sector_size(fd);
169b953
+	}
169b953
+	if (ioctl (fd, BLKGETSIZE, &size))
169b953
+		return 0;
169b953
+	return size;
169b953
+}
169b953
+
169b953
+static uint64_t
169b953
+last_lba(int fd)
169b953
+{
169b953
+	int rc;
169b953
+	uint64_t sectors = 0;
169b953
+	struct stat s;
169b953
+
169b953
+	memset(&s, 0, sizeof (s));
169b953
+	rc = fstat(fd, &s);
169b953
+	if (rc == -1) 
169b953
+	{
169b953
+		fprintf(stderr, "last_lba() could not stat: %s\n",
169b953
+			strerror(errno));
169b953
+		return 0;
169b953
+	}
169b953
+	if (S_ISBLK(s.st_mode))
169b953
+		sectors = _get_num_sectors(fd);
169b953
+	else 
169b953
+	{
169b953
+		fprintf(stderr,
169b953
+			"last_lba(): I don't know how to handle files with mode %x\n",
169b953
+			s.st_mode);
169b953
+		sectors = 1;
169b953
+	}
169b953
+	return sectors - 1;
169b953
+}
169b953
+
169b953
+static ssize_t
169b953
+read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)
169b953
+{
169b953
+        int rc;
169b953
+        struct blkdev_ioctl_param ioctl_param;
169b953
+
169b953
+        if (!buffer) return 0; 
169b953
+
169b953
+        ioctl_param.block = 0; /* read the last sector */
169b953
+        ioctl_param.content_length = count;
169b953
+        ioctl_param.block_contents = buffer;
169b953
+
169b953
+        rc = ioctl(fd, BLKGETLASTSECT, &ioctl_param);
169b953
+        if (rc == -1) perror("read failed");
169b953
+
169b953
+        return !rc;
169b953
+}
169b953
+
169b953
+static ssize_t
169b953
+read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
169b953
+{
169b953
+	int sector_size = _get_sector_size(fd);
169b953
+	off_t offset = lba * sector_size;
169b953
+        ssize_t bytesread;
169b953
+
169b953
+	lseek(fd, offset, SEEK_SET);
169b953
+	bytesread = read(fd, buffer, bytes);
169b953
+
169b953
+        /* Kludge.  This is necessary to read/write the last
169b953
+           block of an odd-sized disk, until Linux 2.5.x kernel fixes.
169b953
+           This is only used by gpt.c, and only to read
169b953
+           one sector, so we don't have to be fancy.
169b953
+        */
169b953
+        if (!bytesread && !(last_lba(fd) & 1) && lba == last_lba(fd))
169b953
+                bytesread = read_lastoddsector(fd, lba, buffer, bytes);
169b953
+        return bytesread;
169b953
+}
169b953
+
169b953
+static GuidPartitionTableHeader_t *
169b953
+alloc_read_gpt_header(int fd, uint64_t lba)
169b953
+{
169b953
+	GuidPartitionTableHeader_t *gpt = 
169b953
+		(GuidPartitionTableHeader_t *) malloc(sizeof (GuidPartitionTableHeader_t));
169b953
+	if (!gpt)
169b953
+		return NULL;
169b953
+	memset(gpt, 0, sizeof (*gpt));
169b953
+	if (!read_lba(fd, lba, gpt, sizeof (GuidPartitionTableHeader_t))) 
169b953
+	{
169b953
+		free(gpt);
169b953
+		return NULL;
169b953
+	}
169b953
+	return gpt;
169b953
+}
169b953
+
169b953
+static int
169b953
+gpt_check_signature(int fd, uint64_t lba)
169b953
+{
169b953
+	GuidPartitionTableHeader_t *gpt;
169b953
+	int res=0;
169b953
+
169b953
+	if ((gpt = alloc_read_gpt_header(fd, lba)))
169b953
+	{
169b953
+		if (gpt->Signature == CPU_TO_LE64(GPT_HEADER_SIGNATURE))
169b953
+			res = 1;
169b953
+		free(gpt);
169b953
+	}
169b953
+	return res;
169b953
+}
169b953
+
169b953
+/* returns:
169b953
+ *	0 not found GPT
169b953
+ * 	1 for valid primary GPT header
169b953
+ *	2 for valid alternative GPT header
169b953
+ */
169b953
+int
169b953
+gpt_probe_signature_fd(int fd)
169b953
+{
169b953
+	int res = 0;
169b953
+
169b953
+	/* check primary GPT header */	
169b953
+	if (gpt_check_signature(fd, GPT_PRIMARY_PARTITION_TABLE_LBA))
169b953
+		res = 1;
169b953
+	else
169b953
+	{
169b953
+		/* check alternative GPT header */
169b953
+		uint64_t lastlba = last_lba(fd);
169b953
+        	if (gpt_check_signature(fd, lastlba))
169b953
+			res = 2;
169b953
+	}
169b953
+	return res;
169b953
+}
169b953
+
169b953
+int
169b953
+gpt_probe_signature_devname(char *devname)
169b953
+{
169b953
+	int res, fd;
169b953
+	if ((fd = open(devname, O_RDONLY)) < 0)
169b953
+		return 0;
169b953
+	res = gpt_probe_signature_fd(fd);
169b953
+	close(fd);
169b953
+	return res;
169b953
+}
169b953
+
169b953
+#ifdef GPT_TEST_MAIN
169b953
+int
169b953
+main(int argc, char **argv)
169b953
+{
169b953
+	if (argc!=2)
169b953
+	{
169b953
+		fprintf(stderr, "usage: %s <dev>\n", argv[0]);
169b953
+		exit(EXIT_FAILURE);
169b953
+	}
169b953
+	if (gpt_probe_signature_devname(argv[1]))
169b953
+		printf("GPT (GUID Partition Table) detected on %s\n", argv[1]);
169b953
+	exit(EXIT_SUCCESS);
169b953
+}
169b953
+#endif
c832e53
--- util-linux-2.13-pre6/fdisk/sfdisk.c.gpt	2005-10-16 14:18:32.000000000 +0200
c832e53
+++ util-linux-2.13-pre6/fdisk/sfdisk.c	2005-11-24 15:30:36.000000000 +0100
169b953
@@ -50,6 +50,8 @@
169b953
 #include "nls.h"
169b953
 #include "common.h"
169b953
 
169b953
+#include "gpt.h"
169b953
+
169b953
 #define SIZE(a)	(sizeof(a)/sizeof(a[0]))
169b953
 
169b953
 /*
c832e53
@@ -2457,6 +2459,23 @@
169b953
 	return NULL;
169b953
 }	
169b953
 
169b953
+static void
169b953
+gpt_warning(char *dev, int warn_only)
169b953
+{
169b953
+	if (force)
169b953
+		warn_only = 1;
169b953
+	
169b953
+	if (gpt_probe_signature_devname(dev)) {
169b953
+		fflush(stdout);
169b953
+		fprintf(stderr, _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
169b953
+			"The util sfdisk doesn't support GPT. Use GNU Parted.\n\n"), dev);
169b953
+		if (!warn_only) {
169b953
+			fprintf(stderr, _("Use the --force flag to overrule this check.\n"));
169b953
+			exit(1);
169b953
+		}
169b953
+	}
169b953
+}
169b953
+
169b953
 static void do_list(char *dev, int silent);
169b953
 static void do_size(char *dev, int silent);
169b953
 static void do_geom(char *dev, int silent);
c832e53
@@ -2602,6 +2621,7 @@
169b953
 	while ((dev = nextproc()) != NULL) {
169b953
 	    if (is_ide_cdrom_or_tape(dev))
169b953
 		continue;
169b953
+	    gpt_warning(dev, 1);
169b953
 	    if (opt_out_geom)
169b953
 		do_geom(dev, 1);
169b953
 	    if (opt_out_pt_geom)
c832e53
@@ -2629,6 +2649,7 @@
169b953
 
169b953
     if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
169b953
 	while (optind < argc) {
169b953
+	    gpt_warning(argv[optind], 1);
169b953
 	    if (opt_out_geom)
169b953
 	      do_geom(argv[optind], 0);
169b953
 	    if (opt_out_pt_geom)
c832e53
@@ -2657,6 +2678,7 @@
169b953
 	  fatal(_("usage: sfdisk --change-id device partition-number Id\n"));
169b953
 	else if (optind != argc-3 && optind != argc-2)
169b953
 	  fatal(_("usage: sfdisk --id device partition-number [Id]\n"));
169b953
+	gpt_warning(argv[optind], 0);
169b953
 	do_change_id(argv[optind], argv[optind+1],
169b953
 		     (optind == argc-2) ? 0 : argv[optind+2]);
169b953
 	exit(exit_status);
c832e53
@@ -2666,6 +2688,8 @@
169b953
       fatal(_("can specify only one device (except with -l or -s)\n"));
169b953
     dev = argv[optind];
169b953
 
169b953
+    gpt_warning(dev, 0);
169b953
+    
169b953
     if (opt_reread)
169b953
       do_reread(dev);
169b953
     else if (restore_sector_file)
c832e53
@@ -2842,6 +2866,8 @@
169b953
 
169b953
     z = &old;;
169b953
 
169b953
+    gpt_warning(dev, 0);
169b953
+    
169b953
     rw = (!no_write && (arg || ac > 1));
169b953
     fd = my_open(dev, rw, 0);
169b953
 
c832e53
@@ -2943,6 +2969,8 @@
169b953
 
169b953
     z = &old;;
169b953
 
169b953
+    gpt_warning(dev, 0);
169b953
+    
169b953
     rw = !no_write;
169b953
     fd = my_open(dev, rw, 0);
169b953