- shrink mkswap and make v0 support optional. Thanks also to Tito for his ideas.
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Wed, 29 Mar 2006 17:32:24 +0000 (17:32 -0000)
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Wed, 29 Mar 2006 17:32:24 +0000 (17:32 -0000)
  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

util-linux/Config.in
util-linux/mkswap.c

index 28292bd40c8e7b0dfdd0bf42e14981ba2fd8ef7d..33567d9a988b0ec68f56ba04b052451a0866487c 100644 (file)
@@ -288,6 +288,16 @@ config CONFIG_MKSWAP
          Once you have created swap space using 'mkswap' you need to enable
          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
        bool "more"
        default n
index 4107329a65b494b9f0574d6aee930d3a78261cde..ce123e50236e34b197ee7fd26a5716308a4f06f0 100644 (file)
@@ -59,9 +59,17 @@ static int DEV = -1;
 static long PAGES = 0;
 static int check = 0;
 static int badpages = 0;
+#if ENABLE_FEATURE_MKSWAP_V0
 static int version = -1;
-
 #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.
@@ -74,7 +82,7 @@ static unsigned int *signature_page;
 
 static struct swap_header_v1 {
        char bootbits[1024];            /* Space for disklabel etc. */
-       unsigned int version;
+       unsigned int swap_version;
        unsigned int last_page;
        unsigned int nr_badpages;
        unsigned int padding[125];
@@ -172,23 +180,11 @@ static int bit_test_and_clear(unsigned int *addr, unsigned int nr)
        return (r & m) != 0;
 }
 
-
 static void page_ok(int page)
 {
-       if (version == 0)
+       if (ENABLE_FEATURE_MKSWAP_V0) {
                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)
@@ -200,7 +196,7 @@ static void check_blocks(void)
        buffer = xmalloc(pagesize);
        current_page = 0;
        while (current_page < PAGES) {
-               if (!check) {
+               if (!check && version == 0) {
                        page_ok(current_page++);
                        continue;
                }
@@ -208,15 +204,23 @@ static void check_blocks(void)
                        current_page * pagesize)
                        bb_error_msg_and_die("seek failed in check_blocks");
                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;
                }
                page_ok(current_page++);
        }
-       if (badpages == 1)
-               printf("one bad page\n");
-       else if (badpages > 1)
-               printf("%d bad pages\n", badpages);
+       if (ENABLE_FEATURE_CLEAN_UP)
+               free(buffer);
+       if (badpages > 0)
+               printf("%d bad page%s\n", badpages, (badpages==1)?"":"s");
 }
 
 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 */
-static long get_size(const char *file)
+static inline long get_size(const char *file)
 {
        int fd;
        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);
        if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
-               int sectors_per_page = pagesize / 512;
-
-               size /= sectors_per_page;
+               size /= pagesize / 512;
        } else {
                size = find_size(fd) / pagesize;
        }
@@ -274,66 +276,53 @@ int mkswap_main(int argc, char **argv)
        int sz;
        int maxpages;
        int goodpages;
-       int offset;
+#ifdef __sparc__
        int force = 0;
+#endif
 
        init_signature_page();          /* get pagesize */
 
-       while (argc-- > 1) {
-               argv++;
-               if (argv[0][0] != '-') {
-                       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];
+       bb_opt_complementally = "?"; /* call bb_show_usage internally */
+       sz = bb_getopt_ulflags(argc, argv, "+cfv:", &tmp);
+       if (sz & 1)
+               check = 1;
+#ifdef __sparc__
+       if (sz & 2)
+               force = 1;
+#endif
+#if ENABLE_FEATURE_MKSWAP_V0
+       if (sz & 4) {
+               version = bb_xgetlarg(tmp, 10, 0, 1);
+       } else {
+               if (get_kernel_revision() < MAKE_VERSION(2, 1, 117))
+                       version = 0;
+               else
+                       version = 1;
+       }
+#endif
+
+       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 {
-                       switch (argv[0][1]) {
-                       case 'c':
-                               check = 1;
-                               break;
-                       case 'f':
-                               force = 1;
-                               break;
-                       case 'v':
-                               version = atoi(argv[0] + 2);
-                               break;
-                       default:
-                               bb_show_usage();
-                       }
+                       device_name = argv[0];
+                       sz = get_size(device_name);
+                       argv++;
                }
        }
+
        if (!device_name) {
-               bb_error_msg("error: Nowhere to set up swap on?");
-               bb_show_usage();
+               bb_error_msg_and_die("error: Nowhere to set up swap on?");
        }
-       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))
-                       version = 0;
-               else
-                       version = 1;
-       }
-       if (version != 0 && version != 1) {
-               bb_error_msg("error: unknown version %d", version);
-               bb_show_usage();
-       }
-       if (PAGES < 10) {
-               bb_error_msg("error: swap area needs to be at least %ldkB",
-                               (long) (10 * pagesize / 1024));
-               bb_show_usage();
-       }
 #if 0
        maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
 #else
@@ -350,7 +339,7 @@ int mkswap_main(int argc, char **argv)
        if (PAGES > maxpages) {
                PAGES = maxpages;
                bb_error_msg("warning: truncating swap area to %ldkB",
-                               PAGES * pagesize / 1024);
+                               PAGES * goodpages);
        }
 
        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))
                bb_error_msg_and_die("fatal: first page unreadable");
        if (version == 1) {
-               p->version = version;
+               p->swap_version = version;
                p->last_page = PAGES - 1;
                p->nr_badpages = badpages;
        }
@@ -401,11 +390,12 @@ int mkswap_main(int argc, char **argv)
                   version, (long) (goodpages * pagesize));
        write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
 
-       offset = ((version == 0) ? 0 : 1024);
-       if (lseek(DEV, offset, SEEK_SET) != offset)
+       sz = ((version == 0) ? 0 : 1024); /* offset */
+       if (lseek(DEV, sz, SEEK_SET) != sz)
                bb_error_msg_and_die("unable to rewind swap-device");
-       if (write(DEV, (char *) signature_page + offset, pagesize - offset)
-               != pagesize - offset)
+       goodpages = pagesize - sz; /* cache substraction */
+       if (write(DEV, (char *) signature_page + sz, goodpages)
+               != goodpages)
                bb_error_msg_and_die("unable to write signature page");
 
        /*
@@ -414,5 +404,9 @@ int mkswap_main(int argc, char **argv)
         */
        if (fsync(DEV))
                bb_error_msg_and_die("fsync failed");
+       if (ENABLE_FEATURE_CLEAN_UP) {
+               close(DEV);
+               free(signature_page);
+       }
        return EXIT_SUCCESS;
 }