]> err.no Git - util-linux/commitdiff
losetup: add --set-capacity
authorKarel Zak <kzak@redhat.com>
Fri, 29 May 2009 19:46:00 +0000 (21:46 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 29 May 2009 19:46:00 +0000 (21:46 +0200)
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@yahoo.co.jp>
Signed-off-by: Karel Zak <kzak@redhat.com>
mount/lomount.c
mount/loop.h
mount/losetup.8

index c173409ec2b1e424e4519d5846b55103d700273c..1b191ab71c719011e4674e96a14c4552883d4f4f 100644 (file)
@@ -348,6 +348,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;
@@ -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 {
index 606885297aa487ed0bff26077d73915d8da80d48..64df33916fb101ed3ed44b963ff57796f6236695 100644 (file)
@@ -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 {
index eae58043bfcae41a86400eae912e1cfa0b58116a..66631b724b22206e3a65949e4bd9759d85ec48d8 100644 (file)
@@ -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"