J. R. Okajima
53d6660836
loop: add ioctl to resize a loop device
Add the ability to 'resize' the loop device on the fly.
One practical application is a loop file with XFS filesystem, already
mounted: You can easily enlarge the file (append some bytes) and then call
ioctl(fd, LOOP_SET_CAPACITY, new); The loop driver will learn about the
new size and you can use xfs_growfs later on, which will allow you to use
full capacity of the loop file without the need to unmount.
Test app:
#include <linux/fs.h>
#include <linux/loop.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define _GNU_SOURCE
#include <getopt.h>
char *me;
void usage(FILE *f)
{
fprintf(f, "%s [options] loop_dev [backend_file]\n"
"-s, --set new_size_in_bytes\n"
"\twhen backend_file is given, "
"it will be expanded too while keeping the original contents\n",
me);
}
struct option opts[] = {
{
.name = "set",
.has_arg = 1,
.flag = NULL,
.val = 's'
},
{
.name = "help",
.has_arg = 0,
.flag = NULL,
.val = 'h'
}
};
void err_size(char *name, __u64 old)
{
fprintf(stderr, "size must be larger than current %s (%llu)\n",
name, old);
}
int main(int argc, char *argv[])
{
int fd, err, c, i, bfd;
ssize_t ssz;
size_t sz;
__u64 old, new, append;
char a[BUFSIZ];
struct stat st;
FILE *out;
char *backend, *dev;
err = EINVAL;
out = stderr;
me = argv[0];
new = 0;
while ((c = getopt_long(argc, argv, "s:h", opts, &i)) != -1) {
switch (c) {
case 's':
errno = 0;
new = strtoull(optarg, NULL, 0);
if (errno) {
err = errno;
perror(argv[i]);
goto out;
}
break;
case 'h':
err = 0;
out = stdout;
goto err;
default:
perror(argv[i]);
goto err;
}
}
if (optind < argc)
dev = argv[optind++];
else
goto err;
fd = open(dev, O_RDONLY);
if (fd < 0) {
err = errno;
perror(dev);
goto out;
}
err = ioctl(fd, BLKGETSIZE64, &old);
if (err) {
err = errno;
perror("ioctl BLKGETSIZE64");
goto out;
}
if (!new) {
printf("%llu\n", old);
goto out;
}
if (new < old) {
err = EINVAL;
err_size(dev, old);
goto out;
}
if (optind < argc) {
backend = argv[optind++];
bfd = open(backend, O_WRONLY|O_APPEND);
if (bfd < 0) {
err = errno;
perror(backend);
goto out;
}
err = fstat(bfd, &st);
if (err) {
err = errno;
perror(backend);
goto out;
}
if (new < st.st_size) {
err = EINVAL;
err_size(backend, st.st_size);
goto out;
}
append = new - st.st_size;
sz = sizeof(a);
while (append > 0) {
if (append < sz)
sz = append;
ssz = write(bfd, a, sz);
if (ssz != sz) {
err = errno;
perror(backend);
goto out;
}
append -= sz;
}
err = fsync(bfd);
if (err) {
err = errno;
perror(backend);
goto out;
}
}
err = ioctl(fd, LOOP_SET_CAPACITY, new);
if (err) {
err = errno;
perror("ioctl LOOP_SET_CAPACITY");
}
goto out;
err:
usage(out);
out:
return err;
}
Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp>
Signed-off-by: Tomas Matejicek <tomas@slax.org>
Cc: <util-linux-ng@vger.kernel.org>
Cc: Karel Zak <kzak@redhat.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Akinobu Mita <akinobu.mita@gmail.com>
Cc: <linux-api@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-04-01 08:59:17 -07:00
..
2009-03-26 18:14:15 +01:00
2009-03-10 20:33:19 -04:00
2009-03-11 13:49:46 +00:00
2009-03-18 19:45:11 -07:00
2009-03-26 22:45:23 -07:00
2009-03-26 18:14:14 +01:00
2009-03-26 16:11:41 -07:00
2009-03-05 14:39:32 -05:00
2009-03-26 15:23:24 -07:00
2009-03-24 16:38:23 -07:00
2009-03-26 18:14:14 +01:00
2009-03-26 11:20:23 -07:00
2009-03-26 18:14:15 +01:00
2009-03-26 18:14:15 +01:00
2009-03-24 12:35:17 +01:00
2009-02-26 10:45:48 +01:00
2009-04-01 08:59:14 -07:00
2009-03-28 13:30:43 -07:00
2009-04-01 08:59:14 -07:00
2009-03-17 14:55:55 -04:00
2009-03-27 14:51:13 +01:00
2009-03-26 18:14:15 +01:00
2009-03-26 18:14:14 +01:00
2009-03-27 14:43:57 -04:00
2009-03-26 18:14:23 +01:00
2009-03-12 21:33:03 +00:00
2009-03-24 16:38:26 -07:00
2009-03-09 15:07:33 -04:00
2009-03-30 22:05:16 +10:30
2009-03-04 15:05:33 +08:00
2009-03-26 18:14:14 +01:00
2009-03-21 13:31:23 -07:00
2009-03-27 14:43:59 -04:00
2009-03-01 00:19:35 -08:00
2009-03-24 16:38:26 -07:00
2009-03-26 18:14:15 +01:00
2009-03-26 18:14:15 +01:00
2009-03-18 11:53:48 +01:00
2009-03-08 10:23:05 -07:00
2009-03-17 15:45:07 -07:00
2009-03-30 21:46:44 +02:00
2009-03-24 16:38:27 -07:00
2009-03-16 08:32:27 -06:00
2009-03-24 20:56:50 +01:00
2009-03-28 17:30:00 -07:00
2009-03-30 11:31:47 -07:00
2009-03-20 01:33:32 -07:00
2009-03-24 12:35:17 +01:00
2009-03-05 16:10:59 +01:00
2009-04-01 08:59:14 -07:00
2009-03-28 21:34:44 +01:00
2009-02-24 19:19:49 +01:00
2009-03-30 12:43:28 -03:00
2009-03-28 21:34:45 +01:00
2009-02-24 19:19:49 +01:00
2009-03-27 12:46:47 +01:00
2009-03-27 20:13:02 -04:00
2009-03-26 18:14:15 +01:00
2009-03-28 13:30:43 -07:00
2009-03-27 00:46:44 -07:00
2009-03-26 18:14:14 +01:00
2009-03-24 00:35:43 +01:00
2009-03-30 13:41:00 -07:00
2009-03-30 21:46:54 +02:00
2009-03-02 09:43:32 +01:00
2009-03-26 18:14:15 +01:00
2009-03-31 01:14:44 +04:00
2009-03-30 21:46:54 +02:00
2009-03-27 17:28:43 +01:00
2009-03-13 14:32:29 +01:00
2009-03-30 12:43:22 -03:00
2009-03-26 18:14:15 +01:00
2009-03-26 18:14:17 +01:00
2009-03-30 12:43:15 -03:00
2009-03-28 23:55:59 -07:00
2009-03-24 16:38:26 -07:00
2009-03-24 11:03:11 +02:00
2009-03-24 11:02:55 +02:00
2009-03-24 11:03:15 +02:00
2009-03-24 22:52:39 -04:00
2009-04-01 08:59:17 -07:00
2009-03-12 12:58:05 -05:00
2009-02-27 16:07:32 +09:00
2009-03-26 18:14:15 +01:00
2009-03-13 15:57:40 -05:00
2009-04-01 08:59:13 -07:00
2009-04-01 08:59:14 -07:00
2009-04-01 08:59:11 -07:00
2009-03-24 16:38:24 -07:00
2009-03-26 10:56:35 -07:00
2009-03-26 18:14:14 +01:00
2009-03-27 14:44:00 -04:00
2009-03-04 00:03:08 -08:00
2009-03-13 12:09:29 -07:00
2009-03-15 19:59:13 -07:00
2009-03-28 13:30:43 -07:00
2009-03-24 16:37:55 -07:00
2009-03-28 23:55:58 -07:00
2009-03-27 14:43:59 -04:00
2009-03-27 14:43:59 -04:00
2009-03-10 20:33:18 -04:00
2009-03-27 20:13:04 -04:00
2009-04-01 08:59:13 -07:00
2009-04-01 08:59:14 -07:00
2009-04-01 08:59:13 -07:00
2009-03-30 14:04:53 +11:00
2009-03-30 21:46:56 +02:00
2009-03-10 16:27:48 +09:00
2009-03-26 18:14:15 +01:00
2009-03-13 15:41:19 -07:00
2009-03-24 16:38:26 -07:00
2009-03-24 16:38:26 -07:00
2009-04-01 08:59:13 -07:00
2009-03-13 16:09:12 -07:00
2009-03-26 18:14:14 +01:00
2009-03-31 01:14:44 +04:00
2009-03-26 02:18:35 +01:00
2009-03-26 02:18:37 +01:00
2009-02-26 04:08:14 +01:00
2009-02-26 04:08:14 +01:00
2009-02-26 04:08:14 +01:00
2009-02-26 04:08:14 +01:00
2009-02-26 23:42:11 -08:00
2009-03-30 14:28:58 -07:00
2009-03-30 12:16:38 -07:00
2009-03-30 12:16:39 -07:00
2009-03-30 12:33:01 -07:00
2009-03-30 12:16:39 -07:00
2009-03-19 23:49:41 -07:00
2009-04-01 08:59:11 -07:00
2009-03-28 15:01:37 +11:00
2009-03-26 18:14:15 +01:00
2009-03-30 22:05:11 +10:30
2009-03-07 18:41:38 -08:00
2009-02-27 16:53:50 +09:00
2009-03-29 01:40:34 -07:00
2009-03-24 10:25:21 +02:00
2009-03-26 16:11:41 -07:00
2009-04-01 08:59:13 -07:00
2009-03-26 18:14:14 +01:00
2009-04-01 08:59:16 -07:00
2009-04-01 08:59:15 -07:00
2009-03-15 20:09:55 -07:00
2009-03-26 18:14:14 +01:00
2009-03-30 17:17:35 -07:00
2009-03-26 18:14:14 +01:00
2009-02-25 18:38:15 +01:00
2009-04-01 08:59:10 -07:00
2009-03-26 18:14:21 +01:00
2009-03-02 11:06:49 +01:00
2009-03-24 16:38:24 -07:00
2009-03-24 16:20:34 -07:00
2009-03-24 16:20:36 -07:00
2009-02-27 16:26:21 -08:00
2009-03-26 18:14:14 +01:00
2009-03-30 12:43:40 -03:00
2009-03-30 12:43:15 -03:00
2009-02-24 21:52:45 +01:00
2009-04-01 08:59:13 -07:00
2009-03-26 18:14:14 +01:00