--- util-linux-2.13-pre7/fdisk/cfdisk.c	2005-11-17 02:14:33.000000000 +0100
+++ util-linux-2.13-pre7d/fdisk/cfdisk.c	2008-08-31 21:40:43.000000000 +0200
@@ -87,11 +87,12 @@
 #define DEFAULT_DEVICE "/dev/hda"
 #define ALTERNATE_DEVICE "/dev/sda"
 
-/* With K=1024 we have `binary' megabytes, gigabytes, etc.
+/* With Ki=1024 we have `binary' megabytes, gigabytes, etc.
    Some misguided hackers like that.
    With K=1000 we have MB and GB that follow the standards
    [SI, ATA, IEEE etc] and the disk manufacturers and the law. */
 #define K	1000
+#define Ki	1024
 
 #define LINE_LENGTH 80
 #define MAXIMUM_PARTS 60
@@ -133,8 +134,15 @@
 /* Display units */
 #define GIGABYTES 1
 #define MEGABYTES 2
-#define SECTORS 3
+#define SECTORS   3
 #define CYLINDERS 4
+#define KILOBYTES 5
+#define KIBIBYTES 6
+#define _2KBLOCKS 7
+#define _4KBLOCKS 8
+#define MEBIBYTES 9
+#define GIBIBYTES 0
+#define JUSTBYTES 10
 
 #define GS_DEFAULT -1
 #define GS_ESCAPE -2
@@ -1398,6 +1406,7 @@
     long long first = p_info[i].first_sector;
     long long last = p_info[i].last_sector;
     long long offset = 0;
+    long long k;
     int flags = 0;
     int id = LINUX;
     int num = -1;
@@ -1439,19 +1448,26 @@
 	for (j = 0;
 	     j < len-1 && (isdigit(response[j]) || response[j] == '.');
 	     j++);
-	if (toupper(response[j]) == 'K') {
-	    num_sects = num_cyls(atof(response)*K)*cylinder_size;
-	} else if (toupper(response[j]) == 'M') {
-	    num_sects = num_cyls(atof(response)*K*K)*cylinder_size;
-	} else if (toupper(response[j]) == 'G') {
-	    num_sects = num_cyls(atof(response)*K*K*K)*cylinder_size;
-	} else if (toupper(response[j]) == 'C') {
-	    num_sects = round_int(atof(response))*cylinder_size;
-	} else if (toupper(response[j]) == 'S') {
-	    num_sects = round_int(atof(response));
-	} else {
-	    num_sects = num_cyls(atof(response)*K*K)*cylinder_size;
-	}
+        if (j+1 < len && toupper(response[j+1]) == 'I') {
+            k = Ki; /* KIBIBYTE, 1024 byte */
+        } else {
+            k = K;  /* KILOBYTE, 1000 byte */
+        }
+        if (toupper(response[j]) == 'B') {
+            num_sects = num_cyls(atof(response))*cylinder_size;
+        } else if (toupper(response[j]) == 'K') {
+            num_sects = num_cyls(atof(response)*k)*cylinder_size;
+        } else if (toupper(response[j]) == 'M') {
+            num_sects = num_cyls(atof(response)*k*k)*cylinder_size;
+        } else if (toupper(response[j]) == 'G') {
+            num_sects = num_cyls(atof(response)*k*k*k)*cylinder_size;
+        } else if (toupper(response[j]) == 'C') {
+            num_sects = round_int(atof(response))*cylinder_size;
+        } else if (toupper(response[j]) == 'S') {
+            num_sects = round_int(atof(response));
+        } else { /* Size specification not given: use MB (not MiB) */
+            num_sects = num_cyls(atof(response)*K*K)*cylinder_size;
+        }
     }
 
     if (num_sects <= 0 ||
@@ -2578,13 +2594,27 @@
     size = p_info[i].last_sector - p_info[i].first_sector + 1;
     fsize = (double) size * SECTOR_SIZE;
     if (display_units == SECTORS)
-	mvprintw(y, SIZE_START, "%11lld", size);
+	mvprintw(y, SIZE_START, "%13lld", size);
     else if (display_units == CYLINDERS)
-	mvprintw(y, SIZE_START, "%11lld", size/cylinder_size);
+	mvprintw(y, SIZE_START, "%13.3f", ceil((1000.0*size)/cylinder_size)/1000.0);
     else if (display_units == MEGABYTES)
-	mvprintw(y, SIZE_START, "%11.2f", ceiling((100*fsize)/(K*K))/100);
+	mvprintw(y, SIZE_START, "%13.3f", ceil((1000.0*fsize)/(K*K))/1000.0);
     else if (display_units == GIGABYTES)
-	mvprintw(y, SIZE_START, "%11.2f", ceiling((100*fsize)/(K*K*K))/100);
+	mvprintw(y, SIZE_START, "%13.3f", ceil((1000.0*fsize)/(K*K*K))/1000.0);
+    else if (display_units == KILOBYTES)
+	mvprintw(y, SIZE_START, "%13.2f", ceil((100.0*fsize)/K)/100.0);
+    else if (display_units == JUSTBYTES)
+	mvprintw(y, SIZE_START, "%13.0f", fsize);
+    else if (display_units == KIBIBYTES)
+	mvprintw(y, SIZE_START, "%13.2f", ceil((100.0*fsize)/Ki)/100.0);
+    else if (display_units == _2KBLOCKS)
+	mvprintw(y, SIZE_START, "%13.2f", ceil((100.0*fsize)/(2.0*Ki))/100.0);
+    else if (display_units == _4KBLOCKS)
+	mvprintw(y, SIZE_START, "%13.2f", ceil((100.0*fsize)/(4.0*Ki))/100.0);
+    else if (display_units == MEBIBYTES)
+	mvprintw(y, SIZE_START, "%13.3f", ceil((1000.0*fsize)/(Ki*Ki))/1000.0);
+    else if (display_units == GIBIBYTES)
+	mvprintw(y, SIZE_START, "%13.3f", ceil((1000.0*fsize)/(Ki*Ki*Ki))/1000.0);
     if (size % cylinder_size != 0 ||
 	p_info[i].first_sector % cylinder_size != 0)
 	mvprintw(y, COLUMNS-1, "*");
@@ -2659,13 +2689,27 @@
     mvaddstr(DISK_TABLE_START, FSTYPE_START, _("FS Type"));
     mvaddstr(DISK_TABLE_START, LABEL_START+1, _("[Label]"));
     if (display_units == SECTORS)
-	mvaddstr(DISK_TABLE_START, SIZE_START, _("    Sectors"));
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size(Sectors)"));
     else if (display_units == CYLINDERS)
-	mvaddstr(DISK_TABLE_START, SIZE_START, _("  Cylinders"));
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size  (Cyl's)"));
     else if (display_units == MEGABYTES)
-	mvaddstr(DISK_TABLE_START, SIZE_START, _("  Size (MB)"));
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size     (MB)"));
     else if (display_units == GIGABYTES)
-	mvaddstr(DISK_TABLE_START, SIZE_START, _("  Size (GB)"));
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size     (GB)"));
+    else if (display_units == JUSTBYTES)
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size  (Bytes)"));
+    else if (display_units == KILOBYTES)
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size     (KB)"));
+    else if (display_units == KIBIBYTES)
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size    (KiB)"));
+    else if (display_units == _2KBLOCKS)
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size(2K-Blks)"));
+    else if (display_units == _4KBLOCKS)
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size(4K-Blks)"));
+    else if (display_units == MEBIBYTES)
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size    (MiB)"));
+    else if (display_units == GIBIBYTES)
+	mvaddstr(DISK_TABLE_START, SIZE_START, _("Size    (GiB)"));
 
     move(DISK_TABLE_START+1, 1);
     for (i = 1; i < COLS-1; i++)
@@ -2838,14 +2882,28 @@
 	    break;
 	case 'U':
 	case 'u':
-	    if (display_units == GIGABYTES)
-		display_units = MEGABYTES;
-	    else if (display_units == MEGABYTES)
+	    if (display_units == MEGABYTES)
+		display_units = MEBIBYTES;
+	    else if (display_units == MEBIBYTES)
+		display_units = GIGABYTES;
+	    else if (display_units == GIGABYTES)
+		display_units = GIBIBYTES;
+	    else if (display_units == GIBIBYTES)
 		display_units = SECTORS;
 	    else if (display_units == SECTORS)
 		display_units = CYLINDERS;
 	    else if (display_units == CYLINDERS)
-		display_units = MEGABYTES; 	/* not yet GIGA */
+		display_units = JUSTBYTES;
+	    else if (display_units == JUSTBYTES)
+		display_units = KILOBYTES;
+	    else if (display_units == KILOBYTES)
+		display_units = KIBIBYTES;
+	    else if (display_units == KIBIBYTES)
+		display_units = _2KBLOCKS;
+	    else if (display_units == _2KBLOCKS)
+		display_units = _4KBLOCKS;
+	    else if (display_units == _4KBLOCKS)
+		display_units = MEGABYTES;
 	    draw_screen();
 	    break;
 	case 'W':
