blockdev: code shrink

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>
This commit is contained in:
Denys Vlasenko 2019-03-30 20:07:21 +01:00
parent bb3a9531b2
commit 35082fc2c1

View File

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