Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e877ad7a authored by Ken Sumrall's avatar Ken Sumrall Committed by Android (Google) Code Review
Browse files

Merge "Add -o loop= option to mount, and fix error detection in mount and umount"

parents ae3736a3 940c8107
Loading
Loading
Loading
Loading
+19 −11
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@

#define ARRAY_SIZE(x)	(sizeof(x) / sizeof(x[0]))

// FIXME - only one loop mount is supported at a time
#define LOOP_DEVICE "/dev/block/loop0"
#define DEFAULT_LOOP_DEVICE "/dev/block/loop0"
#define LOOPDEV_MAXLEN 64

struct mount_opts {
	const char str[8];
@@ -87,7 +87,7 @@ static void add_extra_option(struct extra_opts *extra, char *s)
}

static unsigned long
parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, int* loop)
parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, int* loop, char *loopdev)
{
	char *s;
    
@@ -100,8 +100,15 @@ parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, i
		if (no)
			s += 2;

        if (strncmp(s, "loop=", 5) == 0) {
            *loop = 1;
            strlcpy(loopdev, s + 5, LOOPDEV_MAXLEN);
            continue;
        }

        if (strcmp(s, "loop") == 0) {
            *loop = 1;
            strlcpy(loopdev, DEFAULT_LOOP_DEVICE, LOOPDEV_MAXLEN);
            continue;
        }
		for (i = 0, res = 1; i < ARRAY_SIZE(options); i++) {
@@ -131,7 +138,8 @@ static struct extra_opts extra;
static unsigned long rwflag;

static int
do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int loop)
do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int loop,
         char *loopdev)
{
	char *s;
	int error = 0;
@@ -142,14 +150,13 @@ do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int

        flags = (rwflag & MS_RDONLY) ? O_RDONLY : O_RDWR;
        
        // FIXME - only one loop mount supported at a time
        file_fd = open(dev, flags);
        if (file_fd < -1) {
        if (file_fd < 0) {
            perror("open backing file failed");
            return 1;
        }
        device_fd = open(LOOP_DEVICE, flags);
        if (device_fd < -1) {
        device_fd = open(loopdev, flags);
        if (device_fd < 0) {
            perror("open loop device failed");
            close(file_fd);
            return 1;
@@ -163,7 +170,7 @@ do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int

        close(file_fd);
        close(device_fd);
        dev = LOOP_DEVICE;
        dev = loopdev;
    }

	while ((s = strsep(&type, ",")) != NULL) {
@@ -268,6 +275,7 @@ int mount_main(int argc, char *argv[])
	char *dir = NULL;
	int c;
	int loop = 0;
	char loopdev[LOOPDEV_MAXLEN];

	progname = argv[0];
	rwflag = MS_VERBOSE;
@@ -281,7 +289,7 @@ int mount_main(int argc, char *argv[])
			break;
		switch (c) {
		case 'o':
			rwflag = parse_mount_options(optarg, rwflag, &extra, &loop);
			rwflag = parse_mount_options(optarg, rwflag, &extra, &loop, loopdev);
			break;
		case 'r':
			rwflag |= MS_RDONLY;
@@ -319,6 +327,6 @@ int mount_main(int argc, char *argv[])
		exit(1);
	}

	return do_mount(dev, dir, type, rwflag, extra.str, loop);
	return do_mount(dev, dir, type, rwflag, extra.str, loop, loopdev);
	/* We leak dev and dir in some cases, but we're about to exit */
}
+24 −8
Original line number Diff line number Diff line
@@ -7,10 +7,24 @@
#include <unistd.h>
#include <linux/loop.h>

// FIXME - only one loop mount is supported at a time
#define LOOP_DEVICE "/dev/block/loop0"
#define LOOPDEV_MAXLEN 64
#define LOOP_MAJOR 7

static int is_loop_mount(const char* path)
static int is_loop(char *dev)
{
    struct stat st;
    int ret = 0;

    if (stat(dev, &st) == 0) {
        if (S_ISBLK(st.st_mode) && (major(st.st_rdev) == LOOP_MAJOR)) {
            ret = 1;
        }
    }

    return ret;
}

static int is_loop_mount(const char* path, char *loopdev)
{
    FILE* f;
    int count;
@@ -29,7 +43,8 @@ static int is_loop_mount(const char* path)
    do {
        count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest);
        if (count == 3) {
            if (strcmp(LOOP_DEVICE, device) == 0 && strcmp(path, mount_path) == 0) {
            if (is_loop(device) && strcmp(path, mount_path) == 0) {
                strlcpy(loopdev, device, LOOPDEV_MAXLEN);
                result = 1;
                break;
            }
@@ -43,13 +58,14 @@ static int is_loop_mount(const char* path)
int umount_main(int argc, char *argv[])
{
    int loop, loop_fd;
    char loopdev[LOOPDEV_MAXLEN];

    if(argc != 2) {
        fprintf(stderr,"umount <path>\n");
        return 1;
    }

    loop = is_loop_mount(argv[1]);
    loop = is_loop_mount(argv[1], loopdev);
    if(umount(argv[1])){
        fprintf(stderr,"failed.\n");
        return 1;
@@ -57,8 +73,8 @@ int umount_main(int argc, char *argv[])

    if (loop) {
        // free the loop device
        loop_fd = open(LOOP_DEVICE, O_RDONLY);
        if (loop_fd < -1) {
        loop_fd = open(loopdev, O_RDONLY);
        if (loop_fd < 0) {
            perror("open loop device failed");
            return 1;
        }