From ab518eea9c41235a3fcde80f3ea99669eaade621 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 Mar 2017 16:49:37 +0100 Subject: mount: create loop devices with LO_FLAGS_AUTOCLEAR flag The "autolooped" mount (mount [-oloop] IMAGE /DIR/DIR) always creates AUTOCLEARed loopdevs, so that umounting drops them (and this does not require any code in the umount userspace). This happens since circa linux-2.6.25: commit 96c5865559cee0f9cbc5173f3c949f6ce3525581 Date: Wed Feb 6 01:36:27 2008 -0800 Subject: Allow auto-destruction of loop devices IOW: in this case, umount does not have to use -d to drop the loopdev. The explicit loop mount (mount /dev/loopN /DIR/DIR) does not do this. In this case, umount without -d should not drop loopdev. Unfortunately, bbox umount currently always implies -d, this probably needs fixing. function old new delta set_loop 537 597 +60 singlemount 1101 1138 +37 losetup_main 419 432 +13 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 110/0) Total: 110 bytes Signed-off-by: Denys Vlasenko --- util-linux/losetup.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'util-linux/losetup.c') diff --git a/util-linux/losetup.c b/util-linux/losetup.c index 4424d9cbb..d356f49c2 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c @@ -127,12 +127,37 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) d = *argv++; if (argv[0]) { - if (set_loop(&d, argv[0], offset, (opt & OPT_r)) < 0) + if (set_loop(&d, argv[0], offset, (opt & OPT_r) ? BB_LO_FLAGS_READ_ONLY : 0) < 0) bb_simple_perror_msg_and_die(argv[0]); return EXIT_SUCCESS; } } + /* TODO: util-linux 2.28 shows this when run w/o params: + * NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO + * /dev/loop0 0 0 1 0 /PATH/TO/FILE 0 + * + * implemented by reading /sys: + * + * open("/sys/block", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 + * newfstatat(3, "loop0/loop/backing_file", {st_mode=S_IFREG|0444, st_size=4096, ...}, 0) = 0 + * stat("/dev/loop0", {st_mode=S_IFBLK|0660, st_rdev=makedev(7, 0), ...}) = 0 + * open("/sys/dev/block/7:0/loop/offset", O_RDONLY|O_CLOEXEC) = 5 + * read(5, "0\n", 4096) = 2 + * open("/sys/dev/block/7:0/loop/sizelimit", O_RDONLY|O_CLOEXEC) = 5 + * read(5, "0\n", 4096) = 2 + * open("/sys/dev/block/7:0/loop/offset", O_RDONLY|O_CLOEXEC) = 5 + * read(5, "0\n", 4096) = 2 + * open("/sys/dev/block/7:0/loop/autoclear", O_RDONLY|O_CLOEXEC) = 5 + * read(5, "1\n", 4096) = 2 + * open("/sys/dev/block/7:0/ro", O_RDONLY|O_CLOEXEC) = 5 + * read(5, "0\n", 4096) = 2 + * open("/sys/dev/block/7:0/loop/backing_file", O_RDONLY|O_CLOEXEC) = 5 + * read(5, "/PATH/TO/FILE", 4096) = 37 + * open("/sys/dev/block/7:0/loop/dio", O_RDONLY|O_CLOEXEC) = 5 + * read(5, "0\n", 4096) = 2 + */ + bb_show_usage(); /* does not return */ /*return EXIT_FAILURE;*/ } -- cgit v1.2.3