blockdev: code shrink
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 30 Mar 2019 19:07:21 +0000 (20:07 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 30 Mar 2019 19:07:21 +0000 (20:07 +0100)
function                                             old     new   delta
bdcmd_names                                            -      82     +82
bdcmd_ioctl                                            -      44     +44
bdcmd_flags                                            -      11     +11
blockdev_main                                        273     258     -15
bdcommands                                           176       -    -176
------------------------------------------------------------------------------
(add/remove: 3/1 grow/shrink: 0/1 up/down: 137/-191)          Total: -54 bytes
   text    data     bss     dec     hex filename
 982326     485    7296  990107   f1b9b busybox_old
 982272     485    7296  990053   f1b65 busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
util-linux/blockdev.c

index 5d8e465b46fbebf35e8a4c4c8cdf4ac942846269..e9b5b8bf9d2d426d7f7d138126f625d50d798862 100644 (file)
 #include "libbb.h"
 #include <linux/fs.h>
 
+/* Takes less space is separate arrays than one array of struct */
+static const char bdcmd_names[] ALIGN1 =
+       "setro"     "\0"
+#define CMD_SETRO 0
+       "setrw"     "\0"
+       "getro"     "\0"
+       "getss"     "\0"
+       "getbsz"    "\0"
+       "setbsz"    "\0"
+#define CMD_SETBSZ 5
+       "getsz"     "\0"
+       "getsize"   "\0"
+       "getsize64" "\0"
+       "flushbufs" "\0"
+       "rereadpt"  "\0"
+;
+static const uint32_t bdcmd_ioctl[] = {
+       BLKROSET,       //setro
+       BLKROSET,       //setrw
+       BLKROGET,       //getro
+       BLKSSZGET,      //getss
+       BLKBSZGET,      //getbsz
+       BLKBSZSET,      //setbsz
+       BLKGETSIZE64,   //getsz
+       BLKGETSIZE,     //getsize
+       BLKGETSIZE64,   //getsize64
+       BLKFLSBUF,      //flushbufs
+       BLKRRPART,      //rereadpt
+};
 enum {
        ARG_NONE   = 0,
        ARG_INT    = 1,
@@ -46,83 +75,26 @@ enum {
        FL_NORESULT = 8,
        FL_SCALE512 = 16,
 };
-
-struct bdc {
-       uint32_t   ioc;                       /* ioctl code */
-       const char name[sizeof("flushbufs")]; /* "--setfoo" wothout "--" */
-       uint8_t    flags;
-       int8_t     argval;                    /* default argument value */
+static const uint8_t bdcmd_flags[] ALIGN1 = {
+       ARG_INT + FL_NORESULT,             //setro
+       ARG_INT + FL_NORESULT,             //setrw
+       ARG_INT,                           //getro
+       ARG_INT,                           //getss
+       ARG_INT,                           //getbsz
+       ARG_INT + FL_NORESULT + FL_USRARG, //setbsz
+       ARG_U64 + FL_SCALE512,             //getsz
+       ARG_ULONG,                         //getsize
+       ARG_U64,                           //getsize64
+       ARG_NONE + FL_NORESULT,            //flushbufs
+       ARG_NONE + FL_NORESULT,            //rereadpt
 };
 
-static const struct bdc bdcommands[] = {
-       {
-               .ioc = BLKROSET,
-               .name = "setro",
-               .flags = ARG_INT + FL_NORESULT,
-               .argval = 1,
-       },{
-               .ioc = BLKROSET,
-               .name = "setrw",
-               .flags = ARG_INT + FL_NORESULT,
-               .argval = 0,
-       },{
-               .ioc = BLKROGET,
-               .name = "getro",
-               .flags = ARG_INT,
-               .argval = -1,
-       },{
-               .ioc = BLKSSZGET,
-               .name = "getss",
-               .flags = ARG_INT,
-               .argval = -1,
-       },{
-               .ioc = BLKBSZGET,
-               .name = "getbsz",
-               .flags = ARG_INT,
-               .argval = -1,
-       },{
-               .ioc = BLKBSZSET,
-               .name = "setbsz",
-               .flags = ARG_INT + FL_NORESULT + FL_USRARG,
-               .argval = 0,
-       },{
-               .ioc = BLKGETSIZE64,
-               .name = "getsz",
-               .flags = ARG_U64 + FL_SCALE512,
-               .argval = -1,
-       },{
-               .ioc = BLKGETSIZE,
-               .name = "getsize",
-               .flags = ARG_ULONG,
-               .argval = -1,
-       },{
-               .ioc = BLKGETSIZE64,
-               .name = "getsize64",
-               .flags = ARG_U64,
-               .argval = -1,
-       },{
-               .ioc = BLKFLSBUF,
-               .name = "flushbufs",
-               .flags = ARG_NONE + FL_NORESULT,
-               .argval = 0,
-       },{
-               .ioc = BLKRRPART,
-               .name = "rereadpt",
-               .flags = ARG_NONE + FL_NORESULT,
-               .argval = 0,
-       }
-};
-
-static const struct bdc *find_cmd(const char *s)
+static unsigned find_cmd(const char *s)
 {
-       const struct bdc *bdcmd = bdcommands;
        if (s[0] == '-' && s[1] == '-') {
-               s += 2;
-               do {
-                       if (strcmp(s, bdcmd->name) == 0)
-                               return bdcmd;
-                       bdcmd++;
-               } while (bdcmd != bdcommands + ARRAY_SIZE(bdcommands));
+               int n = index_in_strings(bdcmd_names, s + 2);
+               if (n >= 0)
+                       return n;
        }
        bb_show_usage();
 }
@@ -130,7 +102,8 @@ static const struct bdc *find_cmd(const char *s)
 int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int blockdev_main(int argc UNUSED_PARAM, char **argv)
 {
-       const struct bdc *bdcmd;
+       unsigned bdcmd;
+       unsigned flags;
        int fd;
        uint64_t u64;
        union {
@@ -144,10 +117,13 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv)
                bb_show_usage();
 
        bdcmd = find_cmd(*argv);
-
-       u64 = (int)bdcmd->argval;
-       if (bdcmd->flags & FL_USRARG)
+       /* setrw translates to BLKROSET(0), most other ioctls don't care... */
+       /* ...setro will do BLKROSET(1) */
+       u64 = (bdcmd == CMD_SETRO);
+       if (bdcmd == CMD_SETBSZ) {
+               /* ...setbsz is BLKBSZSET(bytes) */
                u64 = xatoi_positive(*++argv);
+       }
 
        argv++;
        if (!argv[0] || argv[1])
@@ -155,6 +131,7 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv)
        fd = xopen(argv[0], O_RDONLY);
 
        ioctl_val_on_stack.u64 = u64;
+       flags = bdcmd_flags[bdcmd];
 #if BB_BIG_ENDIAN
        /* Store data properly wrt data size.
         * (1) It's no-op for little-endian.
@@ -162,7 +139,7 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv)
         * and it is ARG_INT. --setbsz USER_VAL is also ARG_INT.
         * Thus, we don't need to handle ARG_ULONG.
         */
-       switch (bdcmd->flags & ARG_MASK) {
+       switch (flags & ARG_MASK) {
        case ARG_INT:
                ioctl_val_on_stack.i = (int)u64;
                break;
@@ -174,17 +151,17 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv)
        }
 #endif
 
-       if (ioctl(fd, bdcmd->ioc, &ioctl_val_on_stack.u64) == -1)
+       if (ioctl(fd, bdcmd_ioctl[bdcmd], &ioctl_val_on_stack.u64) == -1)
                bb_simple_perror_msg_and_die(*argv);
 
        /* Fetch it into register(s) */
        u64 = ioctl_val_on_stack.u64;
 
-       if (bdcmd->flags & FL_SCALE512)
+       if (flags & FL_SCALE512)
                u64 >>= 9;
 
        /* Zero- or one-extend the value if needed, then print */
-       switch (bdcmd->flags & (ARG_MASK+FL_NORESULT)) {
+       switch (flags & (ARG_MASK+FL_NORESULT)) {
        case ARG_INT:
                /* Smaller code when we use long long
                 * (gcc tail-merges printf call)