Step 2 of micro-refactoring the set_loop function ()
        Extract subfunction get_next_free_loop() from set_loop()

Also fix miss free(try) when stat(try) and mknod fail

function                                             old     new   delta
set_loop                                             758     734     -24
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-24)             Total: -24 bytes

Fixes: 3448914e8cc5 ("mount,losetup: use /dev/loop-control is it exists")
Signed-off-by: Xiaoming Ni <nixiaom...@huawei.com>
---
 libbb/loop.c | 55 ++++++++++++++++++++++++----------------------------
 1 file changed, 25 insertions(+), 30 deletions(-)

diff --git a/libbb/loop.c b/libbb/loop.c
index c517ceb13..baa02dabb 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -96,6 +96,20 @@ int FAST_FUNC get_free_loop(void)
        return loopdevno; /* can be -1 if error */
 }
 
+static int get_next_free_loop(char *dev, int id)
+{
+       int loopdevno = get_free_loop();
+       if (loopdevno >= 0) {
+               sprintf(dev, LOOP_FORMAT, loopdevno);
+               return 1; /* use /dev/loop-control */
+       }
+       if (loopdevno == -2) {
+               sprintf(dev, LOOP_FORMAT, id);
+               return 2;
+       }
+       return -1; /* no free loop devices */
+}
+
 static int open_file(const char *file, unsigned flags, int *mode)
 {
        int ffd;
@@ -132,30 +146,26 @@ int FAST_FUNC set_loop(char **device, const char *file, 
unsigned long long offse
 
        try = *device;
        if (!try) {
- get_free_loopN:
-               i = get_free_loop();
-               if (i == -1) {
-                       close(ffd);
-                       return -1; /* no free loop devices */
-               }
-               if (i >= 0) {
-                       try = xasprintf(LOOP_FORMAT, i);
-                       goto open_lfd;
-               }
-               /* i == -2: no /dev/loop-control. Do an old-style search for a 
free device */
                try = dev;
        }
 
        /* Find a loop device */
        /* 0xfffff is a max possible minor number in Linux circa 2010 */
        for (i = 0; i <= 0xfffff; i++) {
-               sprintf(dev, LOOP_FORMAT, i);
+               if (!*device) {
+                       rc = get_next_free_loop(dev, i);
+                       if (rc == -1) {
+                               break; /* no free loop devices */
+                       } else if (rc == 1) {
+                               goto open_lfd;
+                       }
+               }
 
                IF_FEATURE_MOUNT_LOOP_CREATE(errno = 0;)
                if (stat(try, &statbuf) != 0 || !S_ISBLK(statbuf.st_mode)) {
                        if (ENABLE_FEATURE_MOUNT_LOOP_CREATE
                         && errno == ENOENT
-                        && try == dev
+                        && (!*device)
                        ) {
                                /* Node doesn't exist, try to create it */
                                if (mknod(dev, S_IFBLK|0644, makedev(7, i)) == 
0)
@@ -188,13 +198,10 @@ int FAST_FUNC set_loop(char **device, const char *file, 
unsigned long long offse
                        /* Associate free loop device with file */
                        if (ioctl(lfd, LOOP_SET_FD, ffd)) {
                                /* Ouch. Are we racing with other mount? */
-                               if (!*device   /* yes */
-                                && try != dev /* tried a _kernel-offered_ 
loopN? */
-                               ) {
-                                       free(try);
+                               if (!*device) {
                                        close(lfd);
 //TODO: add "if (--failcount != 0) ..."?
-                                       goto get_free_loopN;
+                                       continue;
                                }
                                goto close_and_try_next_loopN;
                        }
@@ -218,8 +225,6 @@ int FAST_FUNC set_loop(char **device, const char *file, 
unsigned long long offse
                        }
                        if (rc == 0) {
                                /* SUCCESS! */
-                               if (try != dev) /* tried a kernel-offered free 
loopN? */
-                                       *device = try; /* malloced */
                                if (!*device)   /* was looping in search of 
free "/dev/loopN"? */
                                        *device = xstrdup(dev);
                                rc = lfd; /* return this */
@@ -227,16 +232,6 @@ int FAST_FUNC set_loop(char **device, const char *file, 
unsigned long long offse
                        }
                        /* failure, undo LOOP_SET_FD */
                        ioctl(lfd, LOOP_CLR_FD, 0); // actually, 0 param is 
unnecessary
-               } else {
-                       /* device is not free (rc == 0), or error other than 
ENXIO */
-                       if (rc == 0     /* device is not free? */
-                        && !*device    /* racing with other mount? */
-                        && try != dev  /* tried a _kernel-offered_ loopN? */
-                       ) {
-                               free(try);
-                               close(lfd);
-                               goto get_free_loopN;
-                       }
                }
  close_and_try_next_loopN:
                close(lfd);
-- 
2.27.0

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to