aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2026-02-01 14:23:00 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2026-02-01 14:23:00 +0100
commit47775e8e6a28be04e5e6e1ec73b28cf429d4f001 (patch)
treeb9985e2150af95e2ab6359bb17ec2214261b3903
parent7ac2bd69175d4216f0b53b16b132c1df806ac8b5 (diff)
downloadbusybox-w32-47775e8e6a28be04e5e6e1ec73b28cf429d4f001.tar.gz
busybox-w32-47775e8e6a28be04e5e6e1ec73b28cf429d4f001.tar.bz2
busybox-w32-47775e8e6a28be04e5e6e1ec73b28cf429d4f001.zip
fdisk: simplify start/len calcualtions for Sun labels
function old new delta new_partition 1060 1054 -6 fetch_sun 219 207 -12 verify_sun_cmp 54 39 -15 verify_sun 508 429 -79 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-112) Total: -112 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--util-linux/fdisk.c1
-rw-r--r--util-linux/fdisk_sun.c122
2 files changed, 61 insertions, 62 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index abd48ec9b..f49a6219a 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -445,7 +445,6 @@ struct globals {
445 smallint sun_other_endian; 445 smallint sun_other_endian;
446 smallint sun_scsi_disk; 446 smallint sun_scsi_disk;
447 smallint sun_floppy; 447 smallint sun_floppy;
448 unsigned *verify_sun_starts;
449#endif 448#endif
450#if ENABLE_FEATURE_OSF_LABEL 449#if ENABLE_FEATURE_OSF_LABEL
451# if !defined(__alpha__) 450# if !defined(__alpha__)
diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c
index 955ae1e5e..d70bd111c 100644
--- a/util-linux/fdisk_sun.c
+++ b/util-linux/fdisk_sun.c
@@ -105,7 +105,8 @@ check_sun_label(void)
105 } 105 }
106 G.sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED); 106 G.sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
107 ush = ((unsigned short *) (sunlabel + 1)) - 1; 107 ush = ((unsigned short *) (sunlabel + 1)) - 1;
108 for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--; 108 for (csum = 0; ush >= (unsigned short *)sunlabel;)
109 csum ^= *ush--;
109 if (csum) { 110 if (csum) {
110 printf("Detected sun disklabel with wrong checksum.\n" 111 printf("Detected sun disklabel with wrong checksum.\n"
111"Probably you'll have to set all the values,\n" 112"Probably you'll have to set all the values,\n"
@@ -361,32 +362,37 @@ toggle_sunflags(int i, unsigned char mask)
361 set_changed(i); 362 set_changed(i);
362} 363}
363 364
365typedef struct start_and_len {
366 unsigned start;
367 unsigned len;
368} start_and_len_t;
369
364static void 370static void
365fetch_sun(unsigned *starts, unsigned *lens, unsigned *start, unsigned *stop) 371fetch_sun(start_and_len_t *sl, unsigned *start, unsigned *stop)
366{ 372{
367 int i, continuous = 1; 373 int i, continuous = 1;
368 374
369 *start = 0; 375 *start = 0;
370 *stop = g_cylinders * g_heads * g_sectors; 376 *stop = g_cylinders * g_heads * g_sectors;
371 for (i = 0; i < g_partitions; i++) { 377 for (i = 0; i < g_partitions; i++) {
372 if (sunlabel->partitions[i].num_sectors 378 sl[i].start = 0;
373 && sunlabel->infos[i].id 379 sl[i].len = 0;
374 && sunlabel->infos[i].id != SUN_WHOLE_DISK) { 380 if (sunlabel->partitions[i].num_sectors != 0
375 starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors; 381 && sunlabel->infos[i].id != 0
376 lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); 382 && sunlabel->infos[i].id != SUN_WHOLE_DISK
383 ) {
384 sl[i].start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors;
385 sl[i].len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
377 if (continuous) { 386 if (continuous) {
378 if (starts[i] == *start) 387 if (sl[i].start == *start)
379 *start += lens[i]; 388 *start += sl[i].len;
380 else if (starts[i] + lens[i] >= *stop) 389 else if (sl[i].start + sl[i].len >= *stop)
381 *stop = starts[i]; 390 *stop = sl[i].start;
382 else 391 else
383 continuous = 0; 392 continuous = 0;
384 /* There will be probably more gaps 393 /* There will be probably more gaps
385 than one, so lets check afterwards */ 394 than one, so lets check afterwards */
386 } 395 }
387 } else {
388 starts[i] = 0;
389 lens[i] = 0;
390 } 396 }
391 } 397 }
392} 398}
@@ -394,11 +400,11 @@ fetch_sun(unsigned *starts, unsigned *lens, unsigned *start, unsigned *stop)
394static int 400static int
395verify_sun_cmp(const void *aa, const void *bb) 401verify_sun_cmp(const void *aa, const void *bb)
396{ 402{
397 const int *a = aa; 403 const start_and_len_t *a = aa;
398 const int *b = bb; 404 const start_and_len_t *b = bb;
399 if (*a == -1) return 1; 405 if (a->len == 0) return 1;
400 if (*b == -1) return -1; 406 if (b->len == 0) return -1;
401 if (G.verify_sun_starts[*a] > G.verify_sun_starts[*b]) 407 if (a->start > b->start)
402 return 1; 408 return 1;
403 return -1; 409 return -1;
404} 410}
@@ -406,34 +412,37 @@ verify_sun_cmp(const void *aa, const void *bb)
406static NOINLINE void 412static NOINLINE void
407verify_sun(void) 413verify_sun(void)
408{ 414{
409 unsigned starts[8], lens[8], start, stop; 415 start_and_len_t sl[8];
410 int i,j,k,starto,endo; 416 unsigned start, stop;
411 int array[8]; 417 int i,j,k;
412 418
413 fetch_sun(starts, lens, &start, &stop); 419 fetch_sun(sl, &start, &stop);
414 for (k = 0; k < 7; k++) { 420 for (k = 0; k < 7; k++) {
415 for (i = 0; i < 8; i++) { 421 for (i = 0; i < 8; i++) {
416 if (k && (lens[i] % (g_heads * g_sectors))) { 422 if (k && (sl[i].len % (g_heads * g_sectors))) {
417 printf("Partition %u doesn't end on cylinder boundary\n", i+1); 423 printf("Partition %u doesn't end on cylinder boundary\n", i+1);
418 } 424 }
419 if (lens[i]) { 425 if (sl[i].len) {
420 for (j = 0; j < i; j++) 426 for (j = 0; j < i; j++)
421 if (lens[j]) { 427 if (sl[j].len) {
422 if (starts[j] == starts[i]+lens[i]) { 428 if (sl[j].start == sl[i].start + sl[i].len) {
423 starts[j] = starts[i]; lens[j] += lens[i]; 429 sl[j].start = sl[i].start;
424 lens[i] = 0; 430 sl[j].len += sl[i].len;
425 } else if (starts[i] == starts[j]+lens[j]){ 431 sl[i].len = 0;
426 lens[j] += lens[i]; 432 } else if (sl[i].start == sl[j].start + sl[j].len) {
427 lens[i] = 0; 433 sl[j].len += sl[i].len;
434 sl[i].len = 0;
428 } else if (!k) { 435 } else if (!k) {
429 if (starts[i] < starts[j]+lens[j] 436 if (sl[i].start < sl[j].start + sl[j].len
430 && starts[j] < starts[i]+lens[i]) { 437 && sl[j].start < sl[i].start + sl[i].len
431 starto = starts[i]; 438 ) {
432 if (starts[j] > starto) 439 unsigned starto, endo;
433 starto = starts[j]; 440 starto = sl[i].start;
434 endo = starts[i]+lens[i]; 441 if (sl[j].start > starto)
435 if (starts[j]+lens[j] < endo) 442 starto = sl[j].start;
436 endo = starts[j]+lens[j]; 443 endo = sl[i].start + sl[i].len;
444 if (sl[j].start + sl[j].len < endo)
445 endo = sl[j].start + sl[j].len;
437 printf("Partition %u overlaps with others in " 446 printf("Partition %u overlaps with others in "
438 "sectors %u-%u\n", i+1, starto, endo); 447 "sectors %u-%u\n", i+1, starto, endo);
439 } 448 }
@@ -442,28 +451,19 @@ verify_sun(void)
442 } 451 }
443 } 452 }
444 } 453 }
445 for (i = 0; i < 8; i++) { 454 qsort(sl, ARRAY_SIZE(sl), sizeof(sl[0]), verify_sun_cmp);
446 if (lens[i])
447 array[i] = i;
448 else
449 array[i] = -1;
450 }
451//TODO: probably can eliminate the need in G.verify_sun_starts
452//if merge starts[] and lens[] in a single array?
453 G.verify_sun_starts = starts;
454 qsort(array, ARRAY_SIZE(array), sizeof(array[0]), verify_sun_cmp);
455 455
456 if (array[0] == -1) { 456 if (sl[0].len == 0) {
457 printf("No partitions defined\n"); 457 printf("No partitions defined\n");
458 return; 458 return;
459 } 459 }
460 stop = g_cylinders * g_heads * g_sectors; 460 stop = g_cylinders * g_heads * g_sectors;
461 if (starts[array[0]]) 461 if (sl[0].start != 0)
462 printf("Unused gap - sectors %u-%u\n", 0, starts[array[0]]); 462 printf("Unused gap - sectors %u-%u\n", 0, sl[0].start);
463 for (i = 0; i < 7 && array[i+1] != -1; i++) { 463 for (i = 0; i < 7 && sl[i+1].len != 0; i++) {
464 printf("Unused gap - sectors %u-%u\n", starts[array[i]]+lens[array[i]], starts[array[i+1]]); 464 printf("Unused gap - sectors %u-%u\n", sl[i].start + sl[i].len, sl[i+1].start);
465 } 465 }
466 start = starts[array[i]] + lens[array[i]]; 466 start = sl[i].start + sl[i].len;
467 if (start < stop) 467 if (start < stop)
468 printf("Unused gap - sectors %u-%u\n", start, stop); 468 printf("Unused gap - sectors %u-%u\n", start, stop);
469} 469}
@@ -472,7 +472,7 @@ static void
472add_sun_partition(int n, int sys) 472add_sun_partition(int n, int sys)
473{ 473{
474 unsigned start, stop, stop2; 474 unsigned start, stop, stop2;
475 unsigned starts[8], lens[8]; 475 start_and_len_t sl[8];
476 int whole_disk = 0; 476 int whole_disk = 0;
477 477
478 char mesg[256]; 478 char mesg[256];
@@ -483,7 +483,7 @@ add_sun_partition(int n, int sys)
483 return; 483 return;
484 } 484 }
485 485
486 fetch_sun(starts, lens, &start, &stop); 486 fetch_sun(sl, &start, &stop);
487 if (stop <= start) { 487 if (stop <= start) {
488 if (n == 2) 488 if (n == 2)
489 whole_disk = 1; 489 whole_disk = 1;
@@ -529,7 +529,7 @@ and is of type 'Whole disk'\n");
529 starting at block 0 in an md, or the label will 529 starting at block 0 in an md, or the label will
530 be trashed. */ 530 be trashed. */
531 for (i = 0; i < g_partitions; i++) 531 for (i = 0; i < g_partitions; i++)
532 if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first) 532 if (sl[i].len && sl[i].start <= first && sl[i].start + sl[i].len > first)
533 break; 533 break;
534 if (i < g_partitions && !whole_disk) { 534 if (i < g_partitions && !whole_disk) {
535 if (n == 2 && !first) { 535 if (n == 2 && !first) {
@@ -543,8 +543,8 @@ and is of type 'Whole disk'\n");
543 stop = g_cylinders * g_heads * g_sectors; 543 stop = g_cylinders * g_heads * g_sectors;
544 stop2 = stop; 544 stop2 = stop;
545 for (i = 0; i < g_partitions; i++) { 545 for (i = 0; i < g_partitions; i++) {
546 if (starts[i] > first && starts[i] < stop) 546 if (sl[i].start > first && sl[i].start < stop)
547 stop = starts[i]; 547 stop = sl[i].start;
548 } 548 }
549 snprintf(mesg, sizeof(mesg), 549 snprintf(mesg, sizeof(mesg),
550 "Last %s or +size or +sizeM or +sizeK", 550 "Last %s or +size or +sizeM or +sizeK",