bin/103911: [patch] gpt cannot add partitions >2TB on IA32
Mike Hibler
mike at cs.utah.edu
Mon Oct 2 09:40:25 PDT 2006
>Number: 103911
>Category: bin
>Synopsis: [patch] gpt cannot add partitions >2TB on IA32
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Oct 02 16:40:12 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Mike Hibler
>Release: FreeBSD 6.2-PRERELEASE i386
>Organization:
University of Utah
>Environment:
System: FreeBSD pc361.emulab.net 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #0: Thu Sep 28 13:51:51 MDT 2006 root at server.server.testbed.emulab.net:/usr/obj/usr/src/sys/OPS i386
>Description:
The -s and -b command line arguments to gpt are parsed with strtol
under the assumption that sizeof(long) == sizeof(off_t).
The result is that partitions greater than 2TB cannot be manipulated.
>How-To-Repeat:
Use 'gpt create' to create a partition table on a 2TB+ array.
Use 'gpt add' to add a partition with 4G+ sectors.
It will succeed but the result is smaller than expected.
>Fix:
Here is one way, though probably not the best:
Index: add.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/add.c,v
retrieving revision 1.11.2.2
diff -u -r1.11.2.2 add.c
--- add.c 7 Jul 2006 03:30:37 -0000 1.11.2.2
+++ add.c 29 Sep 2006 01:57:43 -0000
@@ -163,7 +163,7 @@
case 'b':
if (block > 0)
usage_add();
- block = strtol(optarg, &p, 10);
+ block = strtoofft(optarg, &p, 10);
if (*p != 0 || block < 1)
usage_add();
break;
@@ -177,7 +177,7 @@
case 's':
if (size > 0)
usage_add();
- size = strtol(optarg, &p, 10);
+ size = strtoofft(optarg, &p, 10);
if (*p != 0 || size < 1)
usage_add();
break;
Index: gpt.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/gpt.c,v
retrieving revision 1.10.2.2
diff -u -r1.10.2.2 gpt.c
--- gpt.c 7 Jul 2006 03:30:37 -0000 1.10.2.2
+++ gpt.c 29 Sep 2006 01:57:08 -0000
@@ -118,6 +118,14 @@
return crc ^ ~0U;
}
+off_t
+strtoofft(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ if (sizeof(off_t) == sizeof(long))
+ return (strtol(nptr, endptr, base));
+ return (strtoll(nptr, endptr, base));
+}
+
uint8_t *
utf16_to_utf8(uint16_t *s16)
{
Index: gpt.h
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/gpt.h,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 gpt.h
--- gpt.h 7 Jul 2006 03:30:37 -0000 1.7.2.2
+++ gpt.h 29 Sep 2006 01:56:12 -0000
@@ -71,6 +71,7 @@
int gpt_open(const char *);
void* gpt_read(int, off_t, size_t);
int gpt_write(int, map_t *);
+off_t strtoofft(const char * __restrict, char ** __restrict, int);
uint8_t *utf16_to_utf8(uint16_t *);
void utf8_to_utf16(const uint8_t *, uint16_t *, size_t);
Index: label.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/label.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 label.c
--- label.c 7 Jul 2006 03:30:37 -0000 1.1.2.2
+++ label.c 29 Sep 2006 01:58:27 -0000
@@ -184,7 +184,7 @@
case 'b':
if (block > 0)
usage_label();
- block = strtol(optarg, &p, 10);
+ block = strtoofft(optarg, &p, 10);
if (*p != 0 || block < 1)
usage_label();
break;
@@ -208,7 +208,7 @@
case 's':
if (size > 0)
usage_label();
- size = strtol(optarg, &p, 10);
+ size = strtoofft(optarg, &p, 10);
if (*p != 0 || size < 1)
usage_label();
break;
Index: remove.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/remove.c,v
retrieving revision 1.4.2.2
diff -u -r1.4.2.2 remove.c
--- remove.c 7 Jul 2006 03:30:37 -0000 1.4.2.2
+++ remove.c 2 Oct 2006 16:16:51 -0000
@@ -155,7 +155,7 @@
case 'b':
if (block > 0)
usage_remove();
- block = strtol(optarg, &p, 10);
+ block = strtoofft(optarg, &p, 10);
if (*p != 0 || block < 1)
usage_remove();
break;
@@ -169,7 +169,7 @@
case 's':
if (size > 0)
usage_remove();
- size = strtol(optarg, &p, 10);
+ size = strtoofft(optarg, &p, 10);
if (*p != 0 || size < 1)
usage_remove();
break;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list