On Friday, November 18, 2022, Xiaoming Ni <[email protected]> wrote:
> Step 6 of micro-refactoring the set_loop():
> Use structs to avoid transferring a large number of parameters
> in set_loop_configure() and set_loop_info()
>
> function old new delta
> set_loop 708 720 +12
>
------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 1/0 up/down: 12/0) Total: 12
bytes
>
> Signed-off-by: Xiaoming Ni <[email protected]>
> ---
> libbb/loop.c | 54 +++++++++++++++++++++++++++++-----------------------
> 1 file changed, 30 insertions(+), 24 deletions(-)
>
> diff --git a/libbb/loop.c b/libbb/loop.c
> index 914af57b2..2200ccb9a 100644
> --- a/libbb/loop.c
> +++ b/libbb/loop.c
> @@ -126,32 +126,21 @@ static int open_file(const char *file, unsigned
flags, int *mode)
> return ffd;
> }
>
> -static int set_loop_configure(int ffd, int lfd, const char *file,
> - unsigned long long offset, unsigned long long sizelimit,
unsigned flags)
> +static int set_loop_configure(int ffd, int lfd, bb_loop_info *loopinfo)
> {
> int rc;
> - bb_loop_info loopinfo;
> + bb_loop_info loopinfo2;
> /* Associate free loop device with file */
> if (ioctl(lfd, LOOP_SET_FD, ffd)) {
> return -1;
> }
> - memset(&loopinfo, 0, sizeof(loopinfo));
> - safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);
> - loopinfo.lo_offset = offset;
> - loopinfo.lo_sizelimit = sizelimit;
> - /*
> - * Used by mount to set LO_FLAGS_AUTOCLEAR.
> - * LO_FLAGS_READ_ONLY is not set because RO is controlled by open
type of the file.
> - * Note that closing LO_FLAGS_AUTOCLEARed lfd before mount
> - * is wrong (would free the loop device!)
> - */
> - loopinfo.lo_flags = (flags & ~BB_LO_FLAGS_READ_ONLY);
> - rc = ioctl(lfd, BB_LOOP_SET_STATUS, &loopinfo);
> - if (rc != 0 && (loopinfo.lo_flags & BB_LO_FLAGS_AUTOCLEAR)) {
> + rc = ioctl(lfd, BB_LOOP_SET_STATUS, loopinfo);
> + if (rc != 0 && (loopinfo->lo_flags & BB_LO_FLAGS_AUTOCLEAR)) {
> + memcpy(&loopinfo2, loopinfo, sizeof(*loopinfo));
Just use `loopinfo2 = loopinfo;`
Also, it is unclear why there is the need to clone the loopinfo buffer.
> /* Old kernel, does not support LO_FLAGS_AUTOCLEAR? */
> /* (this code path is not tested) */
> - loopinfo.lo_flags -= BB_LO_FLAGS_AUTOCLEAR;
> - rc = ioctl(lfd, BB_LOOP_SET_STATUS, &loopinfo);
> + loopinfo2.lo_flags -= BB_LO_FLAGS_AUTOCLEAR;
> + rc = ioctl(lfd, BB_LOOP_SET_STATUS, &loopinfo2);
> }
> if (rc == 0) {
> return lfd;
> @@ -161,21 +150,36 @@ static int set_loop_configure(int ffd, int lfd,
const char *file,
> return -1;
> }
>
> -static int set_loop_info(int ffd, int lfd, const char *file,
> - unsigned long long offset, unsigned long long sizelimit,
unsigned flags)
> +static int set_loop_info(int ffd, int lfd, bb_loop_info *loopinfo)
> {
> int rc;
> - bb_loop_info loopinfo;
> + bb_loop_info tmp;
>
> - rc = ioctl(lfd, BB_LOOP_GET_STATUS, &loopinfo);
> + rc = ioctl(lfd, BB_LOOP_GET_STATUS, &tmp);
>
> /* If device is free, try to claim it */
> if (rc && errno == ENXIO) {
> - return set_loop_configure(ffd, lfd, file, offset,
sizelimit, flags);
> + return set_loop_configure(ffd, lfd, loopinfo);
> }
> return -1;
> }
>
> +static void init_bb_loop_info(bb_loop_info *loopinfo, const char *file,
> + unsigned long long offset, unsigned long long sizelimit,
unsigned flags)
> +{
> + memset(loopinfo, 0, sizeof(*loopinfo));
Would it reduce code size by doing the initialization like this?
```
bb_loop_info empty = {0};
loopinfo = empty;
```
> + safe_strncpy((char *)loopinfo->lo_file_name, file, LO_NAME_SIZE);
> + loopinfo->lo_offset = offset;
> + loopinfo->lo_sizelimit = sizelimit;
> + /*
> + * Used by mount to set LO_FLAGS_AUTOCLEAR.
> + * LO_FLAGS_READ_ONLY is not set because RO is controlled by open
type of the file.
> + * Note that closing LO_FLAGS_AUTOCLEARed lfd before mount
> + * is wrong (would free the loop device!)
> + */
> + loopinfo->lo_flags = (flags & ~BB_LO_FLAGS_READ_ONLY);
> +}
> +
> /* Returns opened fd to the loop device, <0 on error.
> * *device is loop device to use, or if *device==NULL finds a loop
device to
> * mount it on and sets *device to a strdup of that loop device name.
> @@ -187,12 +191,14 @@ int FAST_FUNC set_loop(char **device, const char
*file, unsigned long long offse
> char *try;
> struct stat statbuf;
> int i, lfd, ffd, mode, rc;
> + bb_loop_info loopinfo;
>
> ffd = open_file(file, flags, &mode);
> if (ffd < 0) {
> return -errno;
> }
>
> + init_bb_loop_info(&loopinfo, file, offset, sizelimit, flags);
> try = *device;
> if (!try) {
> try = dev;
> @@ -239,7 +245,7 @@ int FAST_FUNC set_loop(char **device, const char
*file, unsigned long long offse
> }
> goto try_next_loopN;
> }
> - rc = set_loop_info(ffd, lfd, file, offset, sizelimit,
flags);
> + rc = set_loop_info(ffd, lfd, &loopinfo);
> if (rc == lfd) {
> /* SUCCESS! */
> if (!*device)
> --
> 2.27.0
>
>
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox