mount,losetup: use /dev/loop-control is it exists
function old new delta get_free_loop - 58 +58 set_loop 597 649 +52 losetup_main 482 476 -6 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/1 up/down: 110/-6) Total: 104 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		
							
								
								
									
										42
									
								
								libbb/loop.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								libbb/loop.c
									
									
									
									
									
								
							@@ -78,6 +78,24 @@ int FAST_FUNC del_loop(const char *device)
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Obtain an unused loop device number */
 | 
			
		||||
int FAST_FUNC get_free_loop(void)
 | 
			
		||||
{
 | 
			
		||||
	int fd;
 | 
			
		||||
	int loopdevno;
 | 
			
		||||
 | 
			
		||||
	fd = open("/dev/loop-control", O_RDWR | O_CLOEXEC);
 | 
			
		||||
	if (fd == -1)
 | 
			
		||||
		return fd - 1; /* -2: "no /dev/loop-control" */
 | 
			
		||||
 | 
			
		||||
#ifndef LOOP_CTL_GET_FREE
 | 
			
		||||
# define LOOP_CTL_GET_FREE 0x4C82
 | 
			
		||||
#endif
 | 
			
		||||
	loopdevno = ioctl(fd, LOOP_CTL_GET_FREE);
 | 
			
		||||
	close(fd);
 | 
			
		||||
	return loopdevno; /* can be -1 if error */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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.  This
 | 
			
		||||
@@ -106,12 +124,24 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
 | 
			
		||||
		return -errno;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
//TODO: use LOOP_CTL_GET_FREE instead of trying every loopN in sequence? a-la:
 | 
			
		||||
// fd = open("/dev/loop-control", O_RDWR);
 | 
			
		||||
// loopN = ioctl(fd, LOOP_CTL_GET_FREE);
 | 
			
		||||
//
 | 
			
		||||
	try = *device;
 | 
			
		||||
	if (!try) {
 | 
			
		||||
		i = get_free_loop();
 | 
			
		||||
		if (i == -2) { /* no /dev/loop-control */
 | 
			
		||||
			i = 0;
 | 
			
		||||
			try = dev;
 | 
			
		||||
			goto old_style;
 | 
			
		||||
		}
 | 
			
		||||
		if (i == -1) {
 | 
			
		||||
			close(ffd);
 | 
			
		||||
			return -1; /* no free loop devices */
 | 
			
		||||
		}
 | 
			
		||||
		try = *device = xasprintf(LOOP_FORMAT, i);
 | 
			
		||||
		goto try_to_open;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 old_style:
 | 
			
		||||
	/* Find a loop device.  */
 | 
			
		||||
	try = *device ? *device : dev;
 | 
			
		||||
	/* 1048575 (0xfffff) is a max possible minor number in Linux circa 2010 */
 | 
			
		||||
	for (i = 0; rc && i < 1048576; i++) {
 | 
			
		||||
		sprintf(dev, LOOP_FORMAT, i);
 | 
			
		||||
@@ -170,7 +200,7 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
 | 
			
		||||
					rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo);
 | 
			
		||||
				}
 | 
			
		||||
				if (rc != 0) {
 | 
			
		||||
					ioctl(dfd, LOOP_CLR_FD, 0);
 | 
			
		||||
					ioctl(dfd, LOOP_CLR_FD, 0); // actually, 0 param is unnecessary
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user