X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Floop.c;h=823fba07952779d41d652b7762d6e96e6a44b7f0;hb=ac4100e103ca2b4e6e782c5814b1f43cef58c00b;hp=abf05dc4f0113f5dad372c2a75d6ac9a85c3158a;hpb=98f1dc12f1554aca6c3743bec1c3d8982a077f7c;p=oweals%2Fbusybox.git diff --git a/libbb/loop.c b/libbb/loop.c index abf05dc4f..823fba079 100644 --- a/libbb/loop.c +++ b/libbb/loop.c @@ -5,7 +5,7 @@ * Copyright (C) 1999-2004 by Erik Andersen * Copyright (C) 2005 by Rob Landley * - * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #include "libbb.h" #include @@ -56,7 +56,7 @@ char* FAST_FUNC query_loop(const char *device) fd = open(device, O_RDONLY); if (fd >= 0) { if (ioctl(fd, BB_LOOP_GET_STATUS, &loopinfo) == 0) { - dev = xasprintf("%lu %s", (long) loopinfo.lo_offset, + dev = xasprintf("%"OFF_FMT"u %s", (off_t) loopinfo.lo_offset, (char *)loopinfo.lo_file_name); } close(fd); @@ -84,7 +84,7 @@ int FAST_FUNC del_loop(const char *device) search will re-use an existing loop device already bound to that file/offset if it finds one. */ -int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset) +int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro) { char dev[LOOP_NAMESIZE]; char *try; @@ -93,25 +93,38 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse int i, dfd, ffd, mode, rc = -1; /* Open the file. Barf if this doesn't work. */ - mode = O_RDWR; + mode = ro ? O_RDONLY : O_RDWR; ffd = open(file, mode); if (ffd < 0) { - mode = O_RDONLY; - ffd = open(file, mode); + if (mode != O_RDONLY) { + mode = O_RDONLY; + ffd = open(file, mode); + } if (ffd < 0) return -errno; } /* Find a loop device. */ try = *device ? *device : dev; - for (i = 0; rc; i++) { + /* 1048575 is a max possible minor number in Linux circa 2010 */ + for (i = 0; rc && i < 1048576; i++) { sprintf(dev, LOOP_FORMAT, i); - /* Ran out of block devices, return failure. */ + 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 + ) { + /* Node doesn't exist, try to create it. */ + if (mknod(dev, S_IFBLK|0644, makedev(7, i)) == 0) + goto try_to_open; + } + /* Ran out of block devices, return failure. */ rc = -ENOENT; break; } + try_to_open: /* Open the sucker and check its loopiness. */ dfd = open(try, mode); if (dfd < 0 && errno == EROFS) { @@ -137,9 +150,9 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse } /* If this block device already set up right, re-use it. - (Yes this is racy, but associating two loop devices with the same - file isn't pretty either. In general, mounting the same file twice - without using losetup manually is problematic.) + * (Yes this is racy, but associating two loop devices with the same + * file isn't pretty either. In general, mounting the same file twice + * without using losetup manually is problematic.) */ } else if (strcmp(file, (char *)loopinfo.lo_file_name) != 0