[PATCH v2 2/9] loop:refactor: extract subfunction get_next_free_loop()
Xiaoming Ni
nixiaoming at huawei.com
Fri Nov 18 12:14:41 UTC 2022
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 <nixiaoming at 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..71fd8c1bc 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 i = get_free_loop();
+ if (i >= 0) {
+ sprintf(dev, LOOP_FORMAT, i);
+ return 1; /* use /dev/loop-control */
+ } else if (i == -2) {
+ sprintf(dev, LOOP_FORMAT, id);
+ return 2;
+ } else {
+ 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
More information about the busybox
mailing list