diff options
-rw-r--r-- | util-linux/fdisk.c | 647 |
1 files changed, 330 insertions, 317 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 291be4b9b..4fecbbb89 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -7,19 +7,10 @@ * published by the Free Software Foundation: either version 1 or * (at your option) any later version. * - * For detailed old history, see older versions. - * Contributions before 2001 by faith@cs.unc.edu, Michael Bischoff, - * LeBlanc@mcc.ac.uk, martin@cs.unc.edu, leisner@sdsp.mc.xerox.com, - * esr@snark.thyrsus.com, aeb@cwi.nl, quinlan@yggdrasil.com, - * fasten@cs.bonn.edu, orschaer@cip.informatik.uni-erlangen.de, - * jj@sunsite.mff.cuni.cz, fasten@shw.com, ANeuper@GUUG.de, - * kgw@suse.de, kalium@gmx.de, dhuggins@linuxcare.com, - * michal@ellpspace.math.ualberta.ca and probably others. - * * Vladimir Oleynik <dzo@simtreas.ru> 2001,2002 Busybox port */ -#define UTIL_LINUX_VERSION "2.11z" +#define UTIL_LINUX_VERSION "2.12pre" #define PROC_PARTITIONS "/proc/partitions" @@ -43,6 +34,7 @@ #include <sys/ioctl.h> #include <sys/param.h> +#include <sys/sysmacros.h> /* major */ #include <stdint.h> /* for uint32_t, uint16_t, uint8_t, int16_t, etc */ @@ -63,7 +55,7 @@ #define BLKGETSIZE _IO(0x12,96) /* return device size */ #define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ #define BLKSSZGET _IO(0x12,104) /* get block device sector size */ - +#define BLKGETSIZE64 _IOR(0x12,114,8) /* 8 = sizeof(u64) */ /* fdisk.h @@ -117,6 +109,9 @@ struct systypes { const unsigned char *name; }; +static uint sector_size = DEFAULT_SECTOR_SIZE, + user_set_sector_size, + sector_offset = 1; /* * Raw disk label. For DOS-type partition tables the MBR, @@ -405,8 +400,11 @@ typedef struct { /* Changes: - Sat Mar 20 09:51:38 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br> - Internationalization + * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br> + * Internationalization + * + * 2003-03-20 Phillip Kesling <pkesling@sgi.com> + * Some fixes */ static int aix_other_endian; @@ -515,6 +513,9 @@ check_aix_label( void ) #elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) || defined (__hppa__) #define BSD_LABELSECTOR 0 #define BSD_LABELOFFSET 64 +#elif defined (__s390__) || defined (__s390x__) +#define BSD_LABELSECTOR 1 +#define BSD_LABELOFFSET 0 #else #error unknown architecture #endif @@ -830,6 +831,7 @@ typedef struct { unsigned short csum; /* Label xor'd checksum */ } sun_partition; + #define SUN_LABEL_MAGIC 0xDABE #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA #define sunlabel ((sun_partition *)MBRbuffer) @@ -1216,7 +1218,8 @@ xbsd_create_disklabel (void) { c = read_char (_("Do you want to create a disklabel? (y/n) ")); if (c == 'y' || c == 'Y') { if (xbsd_initlabel ( -#if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) +#if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) || \ + defined (__s390__) || defined (__s390x__) NULL, &xbsd_dlabel, 0 #else xbsd_part, &xbsd_dlabel, xbsd_part_index @@ -1557,7 +1560,7 @@ xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d) static int xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d) { - int sector; + unsigned int sector; #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__) sector = get_start_sect(p) + BSD_LABELSECTOR; @@ -1663,7 +1666,10 @@ __swap16(unsigned short x) { static inline uint32_t __swap32(uint32_t x) { - return (((uint32_t)(x) & 0xFF) << 24) | (((uint32_t)(x) & 0xFF00) << 8) | (((uint32_t)(x) & 0xFF0000) >> 8) | (((uint32_t)(x) & 0xFF000000) >> 24); + return (((x & 0xFF) << 24) | + ((x & 0xFF00) << 8) | + ((x & 0xFF0000) >> 8) | + ((x & 0xFF000000) >> 24)); } #endif @@ -1689,40 +1695,39 @@ static short sgi_volumes=1; * only dealing with free blocks here */ -typedef struct { int first; int last; } freeblocks; +typedef struct { unsigned int first; unsigned int last; } freeblocks; static freeblocks freelist[17]; /* 16 partitions can produce 17 vacant slots */ static void -setfreelist( int i, int f, int l ) { +setfreelist(int i, unsigned int f, unsigned int l) { freelist[i].first = f; freelist[i].last = l; } static void -add2freelist( int f, int l ) { +add2freelist(unsigned int f, unsigned int l) { int i = 0; - for( ; i<17 ; i++ ) { - if(freelist[i].last==0) break; - } - setfreelist( i, f, l ); + for ( ; i < 17 ; i++) + if (freelist[i].last == 0) + break; + setfreelist(i, f, l); } static void clearfreelist(void) { - int i = 0; - for( ; i<17 ; i++ ) { - setfreelist( i, 0, 0 ); - } + int i; + + for (i = 0; i < 17 ; i++) + setfreelist(i, 0, 0); } -static int -isinfreelist( int b ) { - int i = 0; - for( ; i<17 ; i++ ) { - if (freelist[i].first <= b && freelist[i].last >= b) { +static unsigned int +isinfreelist(unsigned int b) { + int i; + + for (i = 0; i < 17 ; i++) + if (freelist[i].first <= b && freelist[i].last >= b) return freelist[i].last; - } - } return 0; } /* return last vacant block of this stride (never 0). */ @@ -1764,11 +1769,6 @@ sgi_get_ntrks(void) { return SGI_SSWAP16(sgilabel->devparam.ntrks); } -static int -sgi_get_pcylcount(void) { - return SGI_SSWAP16(sgilabel->devparam.pcylcount); -} - static void sgi_nolabel(void) { sgilabel->magic = 0; @@ -1777,13 +1777,13 @@ sgi_nolabel(void) { } static unsigned int -two_s_complement_32bit_sum(unsigned int* base, int size /* in bytes */ ) { +two_s_complement_32bit_sum(unsigned int* base, int size /* in bytes */) { int i=0; unsigned int sum=0; - size = size / sizeof( unsigned int ); - for( i=0; i<size; i++ ) - sum = sum - SGI_SSWAP32(base[i]); + size /= sizeof(unsigned int); + for (i = 0; i < size; i++) + sum -= SGI_SSWAP32(base[i]); return sum; } @@ -1807,15 +1807,10 @@ check_sgi_label(void) { /* * test for correct checksum */ - if( two_s_complement_32bit_sum( (unsigned int*)sgilabel, - sizeof(*sgilabel) ) ) - { - fprintf( stderr, _("Detected sgi disklabel with wrong checksum.\n")); - } else - { - heads = sgi_get_ntrks(); - cylinders = sgi_get_pcylcount(); - sectors = sgi_get_nsect(); + if (two_s_complement_32bit_sum((unsigned int*)sgilabel, + sizeof(*sgilabel))) { + fprintf(stderr, + _("Detected sgi disklabel with wrong checksum.\n")); } update_units(); sgi_label = 1; @@ -1824,18 +1819,18 @@ check_sgi_label(void) { return 1; } -static int -sgi_get_start_sector( int i ) { +static unsigned int +sgi_get_start_sector(int i) { return SGI_SSWAP32(sgilabel->partitions[i].start_sector); } -static int -sgi_get_num_sectors( int i ) { +static unsigned int +sgi_get_num_sectors(int i) { return SGI_SSWAP32(sgilabel->partitions[i].num_sectors); } static int -sgi_get_sysid( int i ) +sgi_get_sysid(int i) { return SGI_SSWAP32(sgilabel->partitions[i].id); } @@ -1853,13 +1848,13 @@ sgi_get_swappartition(void) } static void -sgi_list_table( int xtra ) { +sgi_list_table(int xtra) { int i, w; int kpi = 0; /* kernel partition ID */ - w = strlen( disk_device ); + w = strlen(disk_device); - if( xtra ) { + if(xtra) { printf(_("\nDisk %s (SGI disk label): %d heads, %d sectors\n" "%d cylinders, %d physical cylinders\n" "%d extra sects/cyl, interleave %d:1\n" @@ -1901,14 +1896,13 @@ sgi_list_table( int xtra ) { } printf(_("----- Bootinfo -----\nBootfile: %s\n" "----- Directory Entries -----\n"), - sgilabel->boot_file ); - for (i = 0 ; i < sgi_volumes; i++) - { - if (sgilabel->directory[i].vol_file_size) - { + sgilabel->boot_file); + for (i = 0 ; i < sgi_volumes; i++) { + if (sgilabel->directory[i].vol_file_size) { uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start); uint32_t len = SGI_SSWAP32(sgilabel->directory[i].vol_file_size); char*name = sgilabel->directory[i].vol_file_name; + printf(_("%2d: %-10s sector%5u size%8u\n"), i, name, (unsigned int) start, (unsigned int) len); } @@ -1921,7 +1915,7 @@ sgi_set_bootpartition( int i ) sgilabel->boot_part = SGI_SSWAP16(((short)i)); } -static int +static unsigned int sgi_get_lastblock(void) { return heads * sectors * cylinders; } @@ -1932,28 +1926,29 @@ sgi_set_swappartition( int i ) { } static int -sgi_check_bootfile( const char* aFile ) { - if( strlen( aFile ) < 3 ) /* "/a\n" is minimum */ - { - printf( _("\nInvalid Bootfile!\n" +sgi_check_bootfile(const char* aFile) { + + if (strlen(aFile) < 3) /* "/a\n" is minimum */ { + printf(_("\nInvalid Bootfile!\n" "\tThe bootfile must be an absolute non-zero pathname,\n" - "\te.g. \"/unix\" or \"/unix.save\".\n") ); + "\te.g. \"/unix\" or \"/unix.save\".\n")); return 0; - } else - if( strlen( aFile ) > 16 ) - { - printf( _("\n\tName of Bootfile too long: 16 bytes maximum.\n") ); + } else { + if (strlen(aFile) > 16) { + printf(_("\n\tName of Bootfile too long: " + "16 bytes maximum.\n")); return 0; - } else - if( aFile[0] != '/' ) - { - printf( _("\n\tBootfile must have a fully qualified pathname.\n") ); + } else { + if (aFile[0] != '/') { + printf(_("\n\tBootfile must have a " + "fully qualified pathname.\n")); return 0; } - if( strncmp( aFile, sgilabel->boot_file, 16 ) ) - { - printf( _("\n\tBe aware, that the bootfile is not checked for existence.\n\t" - "SGI's default is \"/unix\" and for backup \"/unix.save\".\n") ); + } + } + if (strncmp(aFile, sgilabel->boot_file, 16)) { + printf(_("\n\tBe aware, that the bootfile is not checked for existence.\n\t" + "SGI's default is \"/unix\" and for backup \"/unix.save\".\n")); /* filename is correct and did change */ return 1; } @@ -1966,21 +1961,19 @@ sgi_get_bootfile(void) { } static void -sgi_set_bootfile( const char* aFile ) -{ +sgi_set_bootfile(const char* aFile) { int i = 0; - if( sgi_check_bootfile( aFile ) ) - { - while( i<16 ) - { - if( (aFile[i] != '\n') /* in principle caught again by next line */ - && (strlen( aFile ) > i ) ) + + if (sgi_check_bootfile(aFile)) { + while (i < 16) { + if ((aFile[i] != '\n') /* in principle caught again by next line */ + && (strlen(aFile) > i)) sgilabel->boot_file[i] = aFile[i]; else sgilabel->boot_file[i] = 0; i++; } - printf( _("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file ); + printf(_("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file); } } @@ -1988,200 +1981,179 @@ static void create_sgiinfo(void) { /* I keep SGI's habit to write the sgilabel to the second block */ - sgilabel->directory[0].vol_file_start = SGI_SSWAP32( 2 ); - sgilabel->directory[0].vol_file_size = SGI_SSWAP32( sizeof( sgiinfo ) ); - strncpy( sgilabel->directory[0].vol_file_name, "sgilabel", 8 ); + sgilabel->directory[0].vol_file_start = SGI_SSWAP32(2); + sgilabel->directory[0].vol_file_size = SGI_SSWAP32(sizeof(sgiinfo)); + strncpy(sgilabel->directory[0].vol_file_name, "sgilabel", 8); } -static sgiinfo * fill_sgiinfo(void); +static sgiinfo *fill_sgiinfo(void); static void -sgi_write_table(void) -{ +sgi_write_table(void) { sgilabel->csum = 0; - sgilabel->csum = SGI_SSWAP32( two_s_complement_32bit_sum( + sgilabel->csum = SGI_SSWAP32(two_s_complement_32bit_sum( (unsigned int*)sgilabel, - sizeof(*sgilabel) ) ); - assert( two_s_complement_32bit_sum( - (unsigned int*)sgilabel, sizeof(*sgilabel) ) == 0 ); - if( lseek(fd, 0, SEEK_SET) < 0 ) + sizeof(*sgilabel))); + assert(two_s_complement_32bit_sum( + (unsigned int*)sgilabel, sizeof(*sgilabel)) == 0); + if (lseek(fd, 0, SEEK_SET) < 0) fdisk_fatal(unable_to_seek); - if( write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE ) + if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE) fdisk_fatal(unable_to_write); - if( ! strncmp( sgilabel->directory[0].vol_file_name, "sgilabel",8 ) ) - { + if (! strncmp(sgilabel->directory[0].vol_file_name, "sgilabel", 8)) { /* - * keep this habbit of first writing the "sgilabel". + * keep this habit of first writing the "sgilabel". * I never tested whether it works without (AN 981002). */ - sgiinfo*info = fill_sgiinfo(); /* fills the block appropriately */ - int infostartblock = SGI_SSWAP32( sgilabel->directory[0].vol_file_start ); - if( lseek(fd, (ext2_loff_t)infostartblock* - SECTOR_SIZE, SEEK_SET) < 0 ) + sgiinfo *info = fill_sgiinfo(); + int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start); + if (lseek(fd, (long long)infostartblock* + SECTOR_SIZE, SEEK_SET) < 0) fdisk_fatal(unable_to_seek); - if( write(fd, info, SECTOR_SIZE) != SECTOR_SIZE ) + if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE) fdisk_fatal(unable_to_write); - free( info ); + free(info); } } static int -compare_start( int *x, int *y ) { +compare_start(int *x, int *y) { /* * sort according to start sectors * and prefers largest partition: * entry zero is entire disk entry */ - int i = *x; - int j = *y; - int a = sgi_get_start_sector(i); - int b = sgi_get_start_sector(j); - int c = sgi_get_num_sectors(i); - int d = sgi_get_num_sectors(j); - if( a == b ) - { - return( d - c ); - } - return( a - b ); + unsigned int i = *x; + unsigned int j = *y; + unsigned int a = sgi_get_start_sector(i); + unsigned int b = sgi_get_start_sector(j); + unsigned int c = sgi_get_num_sectors(i); + unsigned int d = sgi_get_num_sectors(j); + + if (a == b) + return (d > c) ? 1 : (d == c) ? 0 : -1; + return (a > b) ? 1 : -1; } static int -verify_sgi( int verbose ) +verify_sgi(int verbose) { int Index[16]; /* list of valid partitions */ int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */ - int entire = 0, i = 0; /* local counters */ - int start = 0; - int gap = 0; /* count unused blocks */ - int lastblock = sgi_get_lastblock(); - /* - */ + int entire = 0, i = 0; + unsigned int start = 0; + long long gap = 0; /* count unused blocks */ + unsigned int lastblock = sgi_get_lastblock(); + clearfreelist(); - for( i=0; i<16; i++ ) - { - if( sgi_get_num_sectors(i)!=0 ) - { + for (i=0; i<16; i++) { + if (sgi_get_num_sectors(i) != 0) { Index[sortcount++]=i; - if( sgi_get_sysid(i) == ENTIRE_DISK ) - { - if( entire++ == 1 ) - { - if(verbose) + if (sgi_get_sysid(i) == ENTIRE_DISK) { + if (entire++ == 1) { + if (verbose) printf(_("More than one entire disk entry present.\n")); } } } } - if( sortcount == 0 ) - { - if(verbose) + if (sortcount == 0) { + if (verbose) printf(_("No partitions defined\n")); - return lastblock; + return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1; } - qsort( Index, sortcount, sizeof(Index[0]), (void*)compare_start ); - if( sgi_get_sysid( Index[0] ) == ENTIRE_DISK ) - { - if( ( Index[0] != 10 ) && verbose ) - printf( _("IRIX likes when Partition 11 covers the entire disk.\n") ); - if( ( sgi_get_start_sector( Index[0] ) != 0 ) && verbose ) - printf( _("The entire disk partition should start at block 0,\nnot " - "at diskblock %d.\n"), sgi_get_start_sector(Index[0] ) ); - if(debug) /* I do not understand how some disks fulfil it */ - if( ( sgi_get_num_sectors( Index[0] ) != lastblock ) && verbose ) - printf( _("The entire disk partition is only %d diskblock large,\n" + qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start); + if (sgi_get_sysid(Index[0]) == ENTIRE_DISK) { + if ((Index[0] != 10) && verbose) + printf(_("IRIX likes when Partition 11 covers the entire disk.\n")); + if ((sgi_get_start_sector(Index[0]) != 0) && verbose) + printf(_("The entire disk partition should start " + "at block 0,\n" + "not at diskblock %d.\n"), + sgi_get_start_sector(Index[0])); + if (debug) /* I do not understand how some disks fulfil it */ + if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose) + printf(_("The entire disk partition is only %d diskblock large,\n" "but the disk is %d diskblocks long.\n"), - sgi_get_num_sectors( Index[0] ), lastblock ); - lastblock = sgi_get_num_sectors( Index[0] ); - } else - { - if( verbose ) - printf( _("One Partition (#11) should cover the entire disk.\n") ); - if(debug>2) - printf( "sysid=%d\tpartition=%d\n", - sgi_get_sysid( Index[0] ), Index[0]+1 ); + sgi_get_num_sectors(Index[0]), lastblock); + lastblock = sgi_get_num_sectors(Index[0]); + } else { + if (verbose) + printf(_("One Partition (#11) should cover the entire disk.\n")); + if (debug>2) + printf("sysid=%d\tpartition=%d\n", + sgi_get_sysid(Index[0]), Index[0]+1); } - for( i=1, start=0; i<sortcount; i++ ) - { + for (i=1, start=0; i<sortcount; i++) { int cylsize = sgi_get_nsect() * sgi_get_ntrks(); - if( (sgi_get_start_sector( Index[i] ) % cylsize) != 0 ) - { - if(debug) /* I do not understand how some disks fulfil it */ - if( verbose ) - printf( _("Partition %d does not start on cylinder boundary.\n"), - Index[i]+1 ); - } - if( sgi_get_num_sectors( Index[i] ) % cylsize != 0 ) - { - if(debug) /* I do not understand how some disks fulfil it */ - if( verbose ) - printf( _("Partition %d does not end on cylinder boundary.\n"), - Index[i]+1 ); + + if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) { + if (debug) /* I do not understand how some disks fulfil it */ + if (verbose) + printf(_("Partition %d does not start on cylinder boundary.\n"), + Index[i]+1); + } + if (sgi_get_num_sectors(Index[i]) % cylsize != 0) { + if (debug) /* I do not understand how some disks fulfil it */ + if (verbose) + printf(_("Partition %d does not end on cylinder boundary.\n"), + Index[i]+1); } /* We cannot handle several "entire disk" entries. */ - if( sgi_get_sysid( Index[i] ) == ENTIRE_DISK ) continue; - if( start > sgi_get_start_sector( Index[i] ) ) - { - if( verbose ) - printf( _("The Partition %d and %d overlap by %d sectors.\n"), + if (sgi_get_sysid(Index[i]) == ENTIRE_DISK) continue; + if (start > sgi_get_start_sector(Index[i])) { + if (verbose) + printf(_("The Partition %d and %d overlap by %d sectors.\n"), Index[i-1]+1, Index[i]+1, - start - sgi_get_start_sector( Index[i] ) ); - if( gap > 0 ) gap = -gap; - if( gap == 0 ) gap = -1; - } - if( start < sgi_get_start_sector( Index[i] ) ) - { - if( verbose ) - printf( _("Unused gap of %8d sectors - sectors %8d-%d\n"), - sgi_get_start_sector( Index[i] ) - start, - start, sgi_get_start_sector( Index[i] )-1 ); - gap += sgi_get_start_sector( Index[i] ) - start; - add2freelist( start, sgi_get_start_sector( Index[i] ) ); - } - start = sgi_get_start_sector( Index[i] ) - + sgi_get_num_sectors( Index[i] ); - if(debug>1) - { - if( verbose ) - printf( "%2d:%12d\t%12d\t%12d\n", Index[i], + start - sgi_get_start_sector(Index[i])); + if (gap > 0) gap = -gap; + if (gap == 0) gap = -1; + } + if (start < sgi_get_start_sector(Index[i])) { + if (verbose) + printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"), + sgi_get_start_sector(Index[i]) - start, + start, sgi_get_start_sector(Index[i])-1); + gap += sgi_get_start_sector(Index[i]) - start; + add2freelist(start, sgi_get_start_sector(Index[i])); + } + start = sgi_get_start_sector(Index[i]) + + sgi_get_num_sectors(Index[i]); + if (debug > 1) { + if (verbose) + printf("%2d:%12d\t%12d\t%12d\n", Index[i], sgi_get_start_sector(Index[i]), sgi_get_num_sectors(Index[i]), - sgi_get_sysid(Index[i]) ); + sgi_get_sysid(Index[i])); } } - if( ( start < lastblock ) ) - { - if( verbose ) - printf( _("Unused gap of %8d sectors - sectors %8d-%d\n"), - lastblock - start, start, lastblock-1 ); + if (start < lastblock) { + if (verbose) + printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"), + lastblock - start, start, lastblock-1); gap += lastblock - start; - add2freelist( start, lastblock ); + add2freelist(start, lastblock); } /* * Done with arithmetics * Go for details now */ - if( verbose ) - { - if( !sgi_get_num_sectors( sgi_get_bootpartition() ) ) - { - printf( _("\nThe boot partition does not exist.\n") ); - } - if( !sgi_get_num_sectors( sgi_get_swappartition() ) ) - { - printf( _("\nThe swap partition does not exist.\n") ); - } else - if( ( sgi_get_sysid( sgi_get_swappartition() ) != SGI_SWAP ) - && ( sgi_get_sysid( sgi_get_swappartition() ) != LINUX_SWAP ) ) - { - printf( _("\nThe swap partition has no swap type.\n") ); + if (verbose) { + if (!sgi_get_num_sectors(sgi_get_bootpartition())) { + printf(_("\nThe boot partition does not exist.\n")); } - if( sgi_check_bootfile( "/unix" ) ) - { - printf( _("\tYou have chosen an unusual boot file name.\n") ); + if (!sgi_get_num_sectors(sgi_get_swappartition())) { + printf(_("\nThe swap partition does not exist.\n")); + } else { + if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP) + && (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP)) + printf(_("\nThe swap partition has no swap type.\n")); } + if (sgi_check_bootfile("/unix")) + printf(_("\tYou have chosen an unusual boot file name.\n")); } - return gap; + return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; } static int @@ -2221,32 +2193,32 @@ sgi_change_sysid( int i, int sys ) /* returns partition index of first entry marked as entire disk */ static int sgi_entire(void) { - int i=0; - for( i=0; i<16; i++ ) - if( sgi_get_sysid(i) == SGI_VOLUME ) + int i; + + for(i=0; i<16; i++) + if(sgi_get_sysid(i) == SGI_VOLUME) return i; return -1; } static void -sgi_set_partition( int i, uint start, uint length, int sys ) { - sgilabel->partitions[i].id = - SGI_SSWAP32( sys ); - sgilabel->partitions[i].num_sectors = - SGI_SSWAP32( length ); - sgilabel->partitions[i].start_sector = - SGI_SSWAP32( start ); +sgi_set_partition(int i, unsigned int start, unsigned int length, int sys) { + + sgilabel->partitions[i].id = SGI_SSWAP32(sys); + sgilabel->partitions[i].num_sectors = SGI_SSWAP32(length); + sgilabel->partitions[i].start_sector = SGI_SSWAP32(start); set_changed(i); - if( sgi_gaps() < 0 ) /* rebuild freelist */ + if (sgi_gaps() < 0) /* rebuild freelist */ printf(_("Do You know, You got a partition overlap on the disk?\n")); } static void sgi_set_entire(void) { int n; - for( n=10; n<partitions; n++ ) { - if(!sgi_get_num_sectors( n ) ) { - sgi_set_partition( n, 0, sgi_get_lastblock(), SGI_VOLUME ); + + for(n=10; n < partitions; n++) { + if(!sgi_get_num_sectors(n) ) { + sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME); break; } } @@ -2283,34 +2255,28 @@ static void sgi_add_partition( int n, int sys ) { char mesg[256]; - int first=0, last=0; + unsigned int first=0, last=0; if( n == 10 ) { sys = SGI_VOLUME; } else if ( n == 8 ) { sys = 0; } - if( sgi_get_num_sectors(n) ) - { + if(sgi_get_num_sectors(n)) { printf(_("Partition %d is already defined. Delete " "it before re-adding it.\n"), n + 1); return; } - if( (sgi_entire() == -1) - && (sys != SGI_VOLUME) ) - { + if( (sgi_entire() == -1) && (sys != SGI_VOLUME) ) { printf(_("Attempting to generate entire disk entry automatically.\n")); sgi_set_entire(); sgi_set_volhdr(); } - if( (sgi_gaps() == 0) - && (sys != SGI_VOLUME) ) - { + if( (sgi_gaps() == 0) && (sys != SGI_VOLUME) ) { printf(_("The entire disk is already covered with partitions.\n")); return; } - if( sgi_gaps() < 0 ) - { + if(sgi_gaps() < 0) { printf(_("You got a partition overlap on the disk. Fix it first!\n")); return; } @@ -2354,48 +2320,62 @@ sgi_add_partition( int n, int sys ) sgi_set_partition( n, first, last-first, sys ); } +#ifdef CONFIG_FEATURE_FDISK_ADVANCED static void create_sgilabel(void) { struct hd_geometry geometry; - struct { int start; - int nsect; - int sysid; } old[4]; + struct { + unsigned int start; + unsigned int nsect; + int sysid; + } old[4]; int i=0; + long longsectors; /* the number of sectors on the device */ + int res; /* the result from the ioctl */ + int sec_fac; /* the sector factor */ + + sec_fac = sector_size / 512; /* determine the sector factor */ + fprintf( stderr, _("Building a new SGI disklabel. Changes will remain in memory only,\n" "until you decide to write them. After that, of course, the previous\n" "content will be unrecoverably lost.\n\n")); sgi_other_endian = (BYTE_ORDER == LITTLE_ENDIAN); - -#ifdef HDIO_REQ - if (!ioctl(fd, HDIO_REQ, &geometry)) -#else - if (!ioctl(fd, HDIO_GETGEO, &geometry)) -#endif - { + res = ioctl(fd, BLKGETSIZE, &longsectors); + if (!ioctl(fd, HDIO_GETGEO, &geometry)) { heads = geometry.heads; sectors = geometry.sectors; + if (res == 0) { + /* the get device size ioctl was successful */ + cylinders = longsectors / (heads * sectors); + cylinders /= sec_fac; + } else { + /* otherwise print error and use truncated version */ cylinders = geometry.cylinders; + fprintf(stderr, + _("Warning: BLKGETSIZE ioctl failed on %s. " + "Using geometry cylinder value of %d.\n" + "This value may be truncated for devices" + " > 33.8 GB.\n"), disk_device, cylinders); } - for (i = 0; i < 4; i++) - { + } + for (i = 0; i < 4; i++) { old[i].sysid = 0; - if( valid_part_table_flag(MBRbuffer) ) - { - if( get_part_table(i)->sys_ind ) - { + if(valid_part_table_flag(MBRbuffer)) { + if(get_part_table(i)->sys_ind) { old[i].sysid = get_part_table(i)->sys_ind; - old[i].start = get_start_sect( get_part_table(i) ); - old[i].nsect = get_nr_sects( get_part_table(i) ); - printf( _("Trying to keep parameters of partition %d.\n"), i ); - if( debug ) - printf( _("ID=%02x\tSTART=%d\tLENGTH=%d\n"), - old[i].sysid, old[i].start, old[i].nsect ); + old[i].start = get_start_sect(get_part_table(i)); + old[i].nsect = get_nr_sects(get_part_table(i)); + printf(_("Trying to keep parameters of partition %d.\n"), i); + if (debug) + printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"), + old[i].sysid, old[i].start, old[i].nsect); } } } + memset(MBRbuffer, 0, sizeof(MBRbuffer)); sgilabel->magic = SGI_SSWAP32(SGI_LABEL_MAGIC); sgilabel->boot_part = SGI_SSWAP16(0); @@ -2438,11 +2418,9 @@ create_sgilabel(void) sgi_volumes = 15; sgi_set_entire(); sgi_set_volhdr(); - for (i = 0; i < 4; i++) - { - if( old[i].sysid ) - { - sgi_set_partition( i, old[i].start, old[i].nsect, old[i].sysid ); + for (i = 0; i < 4; i++) { + if(old[i].sysid) { + sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid); } } } @@ -2452,14 +2430,16 @@ sgi_set_xcyl(void) { /* do nothing in the beginning */ } +#endif /* CONFIG_FEATURE_FDISK_ADVANCED */ /* _____________________________________________________________ */ -static sgiinfo* +static sgiinfo * fill_sgiinfo(void) { - sgiinfo*info=calloc( 1, sizeof(sgiinfo) ); + sgiinfo *info = calloc(1, sizeof(sgiinfo)); + info->magic=SGI_SSWAP32(SGI_INFO_MAGIC); info->b1=SGI_SSWAP32(-1); info->b2=SGI_SSWAP16(-1); @@ -2498,6 +2478,7 @@ static int floppy; #ifndef IDE1_MAJOR #define IDE1_MAJOR 22 #endif + static void guess_device_type(void) { struct stat bootstat; @@ -2505,12 +2486,12 @@ static void guess_device_type(void) { scsi_disk = 0; floppy = 0; } else if (S_ISBLK(bootstat.st_mode) - && ((bootstat.st_rdev >> 8) == IDE0_MAJOR || - (bootstat.st_rdev >> 8) == IDE1_MAJOR)) { + && (major(bootstat.st_rdev) == IDE0_MAJOR || + major(bootstat.st_rdev) == IDE1_MAJOR)) { scsi_disk = 0; floppy = 0; } else if (S_ISBLK(bootstat.st_mode) - && (bootstat.st_rdev >> 8) == FLOPPY_MAJOR) { + && major(bootstat.st_rdev) == FLOPPY_MAJOR) { scsi_disk = 0; floppy = 1; } else { @@ -2736,11 +2717,7 @@ static void create_sunlabel(void) } } if (!p || floppy) { -#ifdef HDIO_REQ - if (!ioctl(fd, HDIO_REQ, &geometry)) { -#else if (!ioctl(fd, HDIO_GETGEO, &geometry)) { -#endif heads = geometry.heads; sectors = geometry.sectors; cylinders = geometry.cylinders; @@ -3046,15 +3023,16 @@ and is of type `Whole disk'\n"); static void sun_delete_partition(int i) { + unsigned int nsec; + if (i == 2 && sunlabel->infos[i].id == WHOLE_DISK && !sunlabel->partitions[i].start_cylinder && - SUN_SSWAP32(sunlabel->partitions[i].num_sectors) + (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == heads * sectors * cylinders) printf(_("If you want to maintain SunOS/Solaris compatibility, " "consider leaving this\n" "partition as Whole disk (5), starting at 0, with %u " - "sectors\n"), - (uint) SUN_SSWAP32(sunlabel->partitions[i].num_sectors)); + "sectors\n"), nsec); sunlabel->infos[i].id = 0; sunlabel->partitions[i].num_sectors = 0; } @@ -3132,6 +3110,8 @@ sun_list_table(int xtra) { } } +#ifdef CONFIG_FEATURE_FDISK_ADVANCED + static void sun_set_alt_cyl(void) { sunlabel->nacyl = @@ -3171,6 +3151,7 @@ sun_set_pcylcount(void) { SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0, _("Number of physical cylinders"))); } +#endif /* CONFIG_FEATURE_FDISK_ADVANCED */ static void sun_write_table(void) { @@ -3368,11 +3349,8 @@ static uint pt_heads, pt_sectors; static uint kern_heads, kern_sectors; static uint extended_offset; /* offset of link pointers */ -static uint sector_size = DEFAULT_SECTOR_SIZE, - user_set_sector_size, - sector_offset = 1; -static unsigned long total_number_of_sectors; +static unsigned long long total_number_of_sectors; static jmp_buf listingbuf; @@ -3979,7 +3957,7 @@ get_partition_table_geometry(void) { void get_geometry(void) { int sec_fac; - unsigned long longsectors; + unsigned long long bytes; /* really u64 */ get_sectorsize(); sec_fac = sector_size / 512; @@ -3999,20 +3977,25 @@ get_geometry(void) { sectors = user_sectors ? user_sectors : pt_sectors ? pt_sectors : kern_sectors ? kern_sectors : 63; + if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) { + /* got bytes */ + } else { + unsigned long longsectors; if (ioctl(fd, BLKGETSIZE, &longsectors)) longsectors = 0; + bytes = ((unsigned long long) longsectors) << 9; + } + + total_number_of_sectors = (bytes >> 9); sector_offset = 1; if (dos_compatible_flag) sector_offset = sectors; - cylinders = longsectors / (heads * sectors); - cylinders /= sec_fac; + cylinders = total_number_of_sectors / (heads * sectors * sec_fac); if (!cylinders) cylinders = user_cylinders; - - total_number_of_sectors = longsectors; } /* @@ -4198,10 +4181,10 @@ read_int(uint low, uint dflt, uint high, uint base, char *mesg) default_ok = 0; if (default_ok) - snprintf(ms, mslen, _("%s (%d-%d, default %d): "), + snprintf(ms, mslen, _("%s (%u-%u, default %u): "), mesg, low, high, dflt); else - snprintf(ms, mslen, "%s (%d-%d): ", + snprintf(ms, mslen, "%s (%u-%u): ", mesg, low, high); while (1) { @@ -4227,8 +4210,10 @@ read_int(uint low, uint dflt, uint high, uint base, char *mesg) if (!display_in_cyl_units) i *= heads * sectors; break; - case 'k': case 'K': + absolute = 1024; + break; + case 'k': absolute = 1000; break; case 'm': @@ -4263,7 +4248,7 @@ read_int(uint low, uint dflt, uint high, uint base, char *mesg) } } if (use_default) - printf(_("Using default value %d\n"), i = dflt); + printf(_("Using default value %u\n"), i = dflt); if (i >= low && i <= high) break; else @@ -4466,7 +4451,18 @@ change_sysid(void) { int i, sys, origsys; struct partition *p; +#ifdef CONFIG_FEATURE_SGI_LABEL + /* If sgi_label then don't use get_existing_partition, + let the user select a partition, since get_existing_partition() + only works for Linux like partition tables. */ + if (!sgi_label) { i = get_existing_partition(0, partitions); + } else { + i = get_partition(0, partitions); + } +#else + i = get_existing_partition(0, partitions); +#endif if (i == -1) return; p = ptes[i].part_table; @@ -4618,7 +4614,7 @@ static void check_consistency(const struct partition *p, int partition) { static void list_disk_geometry(void) { - long long bytes = (long long) total_number_of_sectors * 512; + long long bytes = (total_number_of_sectors << 9); long megabytes = bytes/1000000; if (megabytes < 10000) @@ -4630,7 +4626,7 @@ list_disk_geometry(void) { printf(_("%d heads, %d sectors/track, %d cylinders"), heads, sectors, cylinders); if (units_per_sector == 1) - printf(_(", total %lu sectors"), + printf(_(", total %llu sectors"), total_number_of_sectors / (sector_size/512)); printf(_("\nUnits = %s of %d * %d = %d bytes\n\n"), str_units(PLURAL), @@ -4831,14 +4827,14 @@ list_table(int xtra) { if (sector_size > 1024) pblocks *= (sector_size / 1024); printf( - "%s %c %9ld %9ld %9ld%c %2x %s\n", + "%s %c %11lu %11lu %11lu%c %2x %s\n", partname(disk_device, i+1, w+2), /* boot flag */ !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG ? '*' : '?', -/* start */ (long) cround(get_partition_start(pe)), -/* end */ (long) cround(get_partition_start(pe) + psects +/* start */ (unsigned long) cround(get_partition_start(pe)), +/* end */ (unsigned long) cround(get_partition_start(pe) + psects - (psects ? 1 : 0)), -/* odd flag on end */ (long) pblocks, podd ? '+' : ' ', +/* odd flag on end */ (unsigned long) pblocks, podd ? '+' : ' ', /* type id */ p->sys_ind, /* type name */ partition_type(p->sys_ind)); check_consistency(p, i); @@ -4867,7 +4863,7 @@ x_list_table(int extend) { pe = &ptes[i]; p = (extend ? pe->ext_pointer : pe->part_table); if (p != NULL) { - printf("%2d %02x%4d%4d%5d%4d%4d%5d%9d%9d %02x\n", + printf("%2d %02x%4d%4d%5d%4d%4d%5d%11u%11u %02x\n", i + 1, p->boot_ind, p->head, sector(p->sector), cylinder(p->sector, p->cyl), p->end_head, @@ -5007,6 +5003,7 @@ add_partition(int n, int sys) { int i, readed = 0; struct partition *p = ptes[n].part_table; struct partition *q = ptes[ext_index].part_table; + long long llimit; uint start, stop = 0, limit, temp, first[partitions], last[partitions]; @@ -5018,10 +5015,13 @@ add_partition(int n, int sys) { fill_bounds(first, last); if (n < 4) { start = sector_offset; - if (display_in_cyl_units) - limit = heads * sectors * cylinders - 1; + if (display_in_cyl_units || !total_number_of_sectors) + llimit = heads * sectors * cylinders - 1; else - limit = total_number_of_sectors - 1; + llimit = total_number_of_sectors - 1; + limit = llimit; + if (limit != llimit) + limit = 0x7fffffff; if (extended_offset) { first[ext_index] = extended_offset; last[ext_index] = get_start_sect(q) + @@ -5792,7 +5792,20 @@ int fdisk_main(int argc, char **argv) { break; case 'd': { - int j = get_existing_partition(1, partitions); + int j; +#ifdef CONFIG_FEATURE_SGI_LABEL + /* If sgi_label then don't use get_existing_partition, + let the user select a partition, since + get_existing_partition() only works for Linux-like + partition tables */ + if (!sgi_label) { + j = get_existing_partition(1, partitions); + } else { + j = get_partition(1, partitions); + } +#else + j = get_existing_partition(1, partitions); +#endif if (j >= 0) delete_partition(j); } |