Re: [PATCH] loop file resizable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 03, 2009 at 10:18:04PM +0900, hooanon05@xxxxxxxxxxx wrote:
> 
> Karel Zak:
> >  It seems that the kernel part (LOOP_SET_CAPACITY) is not restricted
> >  and it supports resizing in both directions (increase/decrease).
> >  Right?
> 
> Right.
> The size check is done in userspace, grow only.
> 
> 
> >  Do we really need to hardcode this functionality to losetup(8)? Maybe
> >  users want to use a different way how to resize the file. For example
> >  the latest coreutils contains a nice user-friendly "truncate" utility
> >  that provides all necessary functionality. 
> >  
> >  From my point of view everything what we need in losetup(8) is to
> >  call LOOP_SET_CAPACITY ioctl.
> 
> So you prefer A, do you?
> 
> A.
> $ truncate backend_file
> $ losetup follow_the_size loopdev

 Implemented & committed.

    Karel


>From d34ac93a61984a9144f832582aab99e0a70f4e3b Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@xxxxxxxxxx>
Date: Fri, 29 May 2009 21:46:00 +0200
Subject: [PATCH] losetup: add --set-capacity

The LOOP_SET_CAPACITY allows to resize loop device size.

Example:

 # blockdev --getsize64 /dev/loop0
 10485760

 # dd if=/dev/zero of=/home/images/aaa.img count=10 bs=1M oflag=append conv=notrunc

 # blockdev --getsize64 /dev/loop0
 10485760

 # ./losetup --set-capacity /dev/loop0

 # blockdev --getsize64 /dev/loop0
 20971520

CC: J. R. Okajima <hooanon05@xxxxxxxxxxx>
Signed-off-by: Karel Zak <kzak@xxxxxxxxxx>
---
 mount/lomount.c |   45 +++++++++++++++++++++++++++++++++++++++------
 mount/loop.h    |    2 ++
 mount/losetup.8 |    9 +++++++++
 3 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/mount/lomount.c b/mount/lomount.c
index c173409..1b191ab 100644
--- a/mount/lomount.c
+++ b/mount/lomount.c
@@ -349,6 +349,28 @@ done:
 #ifdef MAIN
 
 static int
+set_capacity(const char *device)
+{
+	int errsv;
+	int fd = open(device, O_RDONLY);
+
+	if (fd == -1)
+		goto err;
+
+	if (ioctl(fd, LOOP_SET_CAPACITY) != 0)
+		goto err;
+
+	return 0;
+err:
+	errsv = errno;
+	fprintf(stderr, _("loop: can't set capacity on device %s: %s\n"),
+					device, strerror (errsv));
+	if (fd != -1)
+		close(fd);
+	return 2;
+}
+
+static int
 show_loop_fd(int fd, char *device) {
 	struct loop_info loopinfo;
 	struct loop_info64 loopinfo64;
@@ -877,6 +899,7 @@ usage(void) {
   " %1$s -a | --all                              list all used\n"
   " %1$s -d | --detach <loopdev> [<loopdev> ...] delete\n"
   " %1$s -f | --find                             find unused\n"
+  " %1$s -c | --set-capacity <loopdev>           resize\n"
   " %1$s -j | --associated <file> [-o <num>]     list all associated with <file>\n"
   " %1$s [ options ] {-f|--find|loopdev} <file>  setup\n"),
 		progname);
@@ -896,7 +919,7 @@ usage(void) {
 int
 main(int argc, char **argv) {
 	char *p, *offset, *sizelimit, *encryption, *passfd, *device, *file, *assoc;
-	int delete, find, c, all;
+	int delete, find, c, all, capacity;
 	int res = 0;
 	int showdev = 0;
 	int ro = 0;
@@ -904,6 +927,7 @@ main(int argc, char **argv) {
 	unsigned long long off, slimit;
 	struct option longopts[] = {
 		{ "all", 0, 0, 'a' },
+		{ "set-capacity", 0, 0, 'c' },
 		{ "detach", 0, 0, 'd' },
 		{ "encryption", 1, 0, 'e' },
 		{ "find", 0, 0, 'f' },
@@ -922,7 +946,7 @@ main(int argc, char **argv) {
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 
-	delete = find = all = 0;
+	capacity = delete = find = all = 0;
 	off = 0;
         slimit = 0;
 	assoc = offset = sizelimit = encryption = passfd = NULL;
@@ -931,12 +955,15 @@ main(int argc, char **argv) {
 	if ((p = strrchr(progname, '/')) != NULL)
 		progname = p+1;
 
-	while ((c = getopt_long(argc, argv, "ade:E:fhj:o:p:rsv",
+	while ((c = getopt_long(argc, argv, "acde:E:fhj:o:p:rsv",
 				longopts, NULL)) != -1) {
 		switch (c) {
 		case 'a':
 			all = 1;
 			break;
+		case 'c':
+			capacity = 1;
+			break;
 		case 'r':
 			ro = 1;
 			break;
@@ -979,16 +1006,20 @@ main(int argc, char **argv) {
 		usage();
 	} else if (delete) {
 		if (argc < optind+1 || encryption || offset || sizelimit ||
-				find || all || showdev || assoc || ro)
+		    capacity || find || all || showdev || assoc || ro)
 			usage();
 	} else if (find) {
-		if (all || assoc || argc < optind || argc > optind+1)
+		if (capacity || all || assoc || argc < optind || argc > optind+1)
 			usage();
 	} else if (all) {
 		if (argc > 2)
 			usage();
 	} else if (assoc) {
-		if (encryption || showdev || passfd || ro)
+		if (capacity || encryption || showdev || passfd || ro)
+			usage();
+	} else if (capacity) {
+		if (argc != optind + 1 || encryption || offset || sizelimit ||
+		    showdev || ro)
 			usage();
 	} else {
 		if (argc < optind+1 || argc > optind+2)
@@ -1027,6 +1058,8 @@ main(int argc, char **argv) {
 	if (delete) {
 		while (optind < argc)
 			res += del_loop(argv[optind++]);
+	} else if (capacity) {
+		res = set_capacity(device);
 	} else if (file == NULL)
 		res = show_loop(device);
 	else {
diff --git a/mount/loop.h b/mount/loop.h
index 6068852..64df339 100644
--- a/mount/loop.h
+++ b/mount/loop.h
@@ -22,6 +22,8 @@
 #define LOOP_GET_STATUS		0x4C03
 #define LOOP_SET_STATUS64	0x4C04
 #define LOOP_GET_STATUS64	0x4C05
+/* #define LOOP_CHANGE_FD	0x4C06 */
+#define LOOP_SET_CAPACITY	0x4C07
 
 /* Flags for loop_into{64,}->lo_flags */
 enum {
diff --git a/mount/losetup.8 b/mount/losetup.8
index eae5804..66631b7 100644
--- a/mount/losetup.8
+++ b/mount/losetup.8
@@ -48,7 +48,14 @@ Setup loop device:
 .RB [ \-r ]
 .RB { \-f [ \-\-show ] | \fIloopdev\fP }
 .I file
+.sp
 .in -13
+Resize loop device:
+.sp
+.in +5
+.B "losetup \-c"
+.I loopdev
+.in -5
 .ad b
 .SH DESCRIPTION
 .B losetup
@@ -75,6 +82,8 @@ and finds the module that knows how to perform that encryption.
 .SH OPTIONS
 .IP "\fB\-a, \-\-all\fP"
 show status of all loop devices
+.IP "\fB\-c, \-\-set-capacity\fP \fIloopdev\fP
+force loop driver to reread size of the file associated with the specified loop device
 .IP "\fB\-d, \-\-detach\fP \fIloopdev\fP [\fIloopdev\fP ...]" 
 detach the file or device associated with the specified loop device(s)
 .IP "\fB\-e, \-E, \-\-encryption \fIencryption_type\fP"
-- 
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux