- shrink mkswap and make v0 support optional. Thanks also to Tito for his ideas.

http://busybox.net/lists/busybox/2006-March/019326.html

   2137	      8	     28	   2173	    87d	util-linux/mkswap.o.orig
   1890	      8	     28	   1926	    786	util-linux/mkswap.o.v0+v1
   1560	      4	     28	   1592	    638	util-linux/mkswap.o.v1
This commit is contained in:
Bernhard Reutner-Fischer 2006-03-29 17:32:24 +00:00
parent b256bd334f
commit 56dd0bff06
2 changed files with 85 additions and 81 deletions

View File

@ -288,6 +288,16 @@ config CONFIG_MKSWAP
Once you have created swap space using 'mkswap' you need to enable Once you have created swap space using 'mkswap' you need to enable
the swap space using the 'swapon' utility. the swap space using the 'swapon' utility.
config CONFIG_FEATURE_MKSWAP_V0
bool " version 0 support"
default n
depends on CONFIG_MKSWAP
# depends on CONFIG_MKSWAP && CONFIG_DEPRECATED
help
Enable support for the old v0 style.
If your kernel is older than 2.1.117, then v0 support is the
only option.
config CONFIG_MORE config CONFIG_MORE
bool "more" bool "more"
default n default n

View File

@ -59,9 +59,17 @@ static int DEV = -1;
static long PAGES = 0; static long PAGES = 0;
static int check = 0; static int check = 0;
static int badpages = 0; static int badpages = 0;
#if ENABLE_FEATURE_MKSWAP_V0
static int version = -1; static int version = -1;
#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r)) #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
#else
#define version 1
/* and make sure that we optimize away anything which would deal with checking
* the kernel revision as we have v1 support only anyway.
*/
#define MAKE_VERSION(p,q,r) 1
#define get_kernel_revision() 1
#endif
/* /*
* The definition of the union swap_header uses the constant PAGE_SIZE. * The definition of the union swap_header uses the constant PAGE_SIZE.
@ -74,7 +82,7 @@ static unsigned int *signature_page;
static struct swap_header_v1 { static struct swap_header_v1 {
char bootbits[1024]; /* Space for disklabel etc. */ char bootbits[1024]; /* Space for disklabel etc. */
unsigned int version; unsigned int swap_version;
unsigned int last_page; unsigned int last_page;
unsigned int nr_badpages; unsigned int nr_badpages;
unsigned int padding[125]; unsigned int padding[125];
@ -172,23 +180,11 @@ static int bit_test_and_clear(unsigned int *addr, unsigned int nr)
return (r & m) != 0; return (r & m) != 0;
} }
static void page_ok(int page) static void page_ok(int page)
{ {
if (version == 0) if (ENABLE_FEATURE_MKSWAP_V0) {
bit_set(signature_page, page); bit_set(signature_page, page);
}
static inline void page_bad(int page)
{
if (version == 0)
bit_test_and_clear(signature_page, page);
else {
if (badpages == MAX_BADPAGES)
bb_error_msg_and_die("too many bad pages");
p->badpages[badpages] = page;
} }
badpages++;
} }
static void check_blocks(void) static void check_blocks(void)
@ -200,7 +196,7 @@ static void check_blocks(void)
buffer = xmalloc(pagesize); buffer = xmalloc(pagesize);
current_page = 0; current_page = 0;
while (current_page < PAGES) { while (current_page < PAGES) {
if (!check) { if (!check && version == 0) {
page_ok(current_page++); page_ok(current_page++);
continue; continue;
} }
@ -208,15 +204,23 @@ static void check_blocks(void)
current_page * pagesize) current_page * pagesize)
bb_error_msg_and_die("seek failed in check_blocks"); bb_error_msg_and_die("seek failed in check_blocks");
if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) { if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
page_bad(current_page++); current_page++;
if (version == 0)
bit_test_and_clear(signature_page, current_page);
else {
if (badpages == MAX_BADPAGES)
bb_error_msg_and_die("too many bad pages");
p->badpages[badpages] = current_page;
}
badpages++;
continue; continue;
} }
page_ok(current_page++); page_ok(current_page++);
} }
if (badpages == 1) if (ENABLE_FEATURE_CLEAN_UP)
printf("one bad page\n"); free(buffer);
else if (badpages > 1) if (badpages > 0)
printf("%d bad pages\n", badpages); printf("%d bad page%s\n", badpages, (badpages==1)?"":"s");
} }
static long valid_offset(int fd, int offset) static long valid_offset(int fd, int offset)
@ -249,17 +253,15 @@ static int find_size(int fd)
} }
/* return size in pages, to avoid integer overflow */ /* return size in pages, to avoid integer overflow */
static long get_size(const char *file) static inline long get_size(const char *file)
{ {
int fd; int fd;
long size; long size;
if ((fd = open(file, O_RDONLY)) < 0) if ((fd = open(file, O_RDONLY)) < 0) /* TODO: bb_xopen3 */
bb_perror_msg_and_die("%s", file); bb_perror_msg_and_die("%s", file);
if (ioctl(fd, BLKGETSIZE, &size) >= 0) { if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
int sectors_per_page = pagesize / 512; size /= pagesize / 512;
size /= sectors_per_page;
} else { } else {
size = find_size(fd) / pagesize; size = find_size(fd) / pagesize;
} }
@ -274,66 +276,53 @@ int mkswap_main(int argc, char **argv)
int sz; int sz;
int maxpages; int maxpages;
int goodpages; int goodpages;
int offset; #ifdef __sparc__
int force = 0; int force = 0;
#endif
init_signature_page(); /* get pagesize */ init_signature_page(); /* get pagesize */
while (argc-- > 1) { bb_opt_complementally = "?"; /* call bb_show_usage internally */
argv++; sz = bb_getopt_ulflags(argc, argv, "+cfv:", &tmp);
if (argv[0][0] != '-') { if (sz & 1)
if (device_name) {
int blocks_per_page = pagesize / 1024;
PAGES = strtol(argv[0], &tmp, 0) / blocks_per_page;
if (*tmp)
bb_show_usage();
} else
device_name = argv[0];
} else {
switch (argv[0][1]) {
case 'c':
check = 1; check = 1;
break; #ifdef __sparc__
case 'f': if (sz & 2)
force = 1; force = 1;
break; #endif
case 'v': #if ENABLE_FEATURE_MKSWAP_V0
version = atoi(argv[0] + 2); if (sz & 4) {
break; version = bb_xgetlarg(tmp, 10, 0, 1);
default: } else {
bb_show_usage();
}
}
}
if (!device_name) {
bb_error_msg("error: Nowhere to set up swap on?");
bb_show_usage();
}
sz = get_size(device_name);
if (!PAGES) {
PAGES = sz;
} else if (PAGES > sz && !force) {
bb_error_msg("error: size %ld is larger than device size %d",
PAGES * (pagesize / 1024), sz * (pagesize / 1024));
return EXIT_FAILURE;
}
if (version == -1) {
if (get_kernel_revision() < MAKE_VERSION(2, 1, 117)) if (get_kernel_revision() < MAKE_VERSION(2, 1, 117))
version = 0; version = 0;
else else
version = 1; version = 1;
} }
if (version != 0 && version != 1) { #endif
bb_error_msg("error: unknown version %d", version);
bb_show_usage(); argv += optind;
argc -= optind;
goodpages = pagesize / 1024; /* cache division */
while (argc--) {
if (device_name) {
PAGES = bb_xgetlarg(argv[0], 0, 10, sz * goodpages) / goodpages;
argc = 0; /* ignore any surplus args.. */
} else {
device_name = argv[0];
sz = get_size(device_name);
argv++;
} }
if (PAGES < 10) {
bb_error_msg("error: swap area needs to be at least %ldkB",
(long) (10 * pagesize / 1024));
bb_show_usage();
} }
if (!device_name) {
bb_error_msg_and_die("error: Nowhere to set up swap on?");
}
if (!PAGES) {
PAGES = sz;
}
#if 0 #if 0
maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES); maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
#else #else
@ -350,7 +339,7 @@ int mkswap_main(int argc, char **argv)
if (PAGES > maxpages) { if (PAGES > maxpages) {
PAGES = maxpages; PAGES = maxpages;
bb_error_msg("warning: truncating swap area to %ldkB", bb_error_msg("warning: truncating swap area to %ldkB",
PAGES * pagesize / 1024); PAGES * goodpages);
} }
DEV = open(device_name, O_RDWR); DEV = open(device_name, O_RDWR);
@ -389,7 +378,7 @@ int mkswap_main(int argc, char **argv)
if (version == 0 && !bit_test_and_clear(signature_page, 0)) if (version == 0 && !bit_test_and_clear(signature_page, 0))
bb_error_msg_and_die("fatal: first page unreadable"); bb_error_msg_and_die("fatal: first page unreadable");
if (version == 1) { if (version == 1) {
p->version = version; p->swap_version = version;
p->last_page = PAGES - 1; p->last_page = PAGES - 1;
p->nr_badpages = badpages; p->nr_badpages = badpages;
} }
@ -401,11 +390,12 @@ int mkswap_main(int argc, char **argv)
version, (long) (goodpages * pagesize)); version, (long) (goodpages * pagesize));
write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2"); write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
offset = ((version == 0) ? 0 : 1024); sz = ((version == 0) ? 0 : 1024); /* offset */
if (lseek(DEV, offset, SEEK_SET) != offset) if (lseek(DEV, sz, SEEK_SET) != sz)
bb_error_msg_and_die("unable to rewind swap-device"); bb_error_msg_and_die("unable to rewind swap-device");
if (write(DEV, (char *) signature_page + offset, pagesize - offset) goodpages = pagesize - sz; /* cache substraction */
!= pagesize - offset) if (write(DEV, (char *) signature_page + sz, goodpages)
!= goodpages)
bb_error_msg_and_die("unable to write signature page"); bb_error_msg_and_die("unable to write signature page");
/* /*
@ -414,5 +404,9 @@ int mkswap_main(int argc, char **argv)
*/ */
if (fsync(DEV)) if (fsync(DEV))
bb_error_msg_and_die("fsync failed"); bb_error_msg_and_die("fsync failed");
if (ENABLE_FEATURE_CLEAN_UP) {
close(DEV);
free(signature_page);
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }