[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Loop-aes and a changed block device size
Hello list, Hello Jari,
I'm using loop-AES on my laptop or a few years. All filesystems are
loop-AES-encrypted on lvm volumes. Today I had to enlarge my /home
partition. As you certainly know, lvm volumes can grow online and
meanwhile at least reiserfs and ext3 have the ability to resize a
filesystem on-line. But unfortunately the loop device layer which
resides between those two does not grow with the underlying block
device.
I was bored tonight, and had a look at the loop-aes source to find out
whether it would be possible to adjust a loop device to the new size
of its its underlying block device. I think I have found a way, but I
am not competent enough to see whether I break something with it. It
works for me so far that I can create a file-backed loop device,
create a reiserfs on it and mount it, append a few megabytes to the
container file, call my new LOOP_RESET_SIZE ioctl and resize the file
system with resize_reiserfs, while the fs is mounted.
Maybe you can have a quick look on it. Is it really so simple or am I
missing some important point here? Would it be worth the effort to
include a this functionality into losetup? I haven't written C for
many years and have never read or written any kernel code before
today, so please don't expect too much. I would really appreciate any
comment.
Regards,
Jim
--- ../linux/modules/loop-AES-v3.0d/loop.c-2.6.patched 2005-06-11 17:10:40.000000000 +0200
+++ loop-aes-RESIZE/loop.c-2.6.patched 2005-09-16 23:51:52.000000000 +0200
@@ -117,6 +117,10 @@
# define LOOP_MULTI_KEY_SETUP_V3 0x4C4E
#endif
+#ifndef LOOP_RESET_SIZE
+# define LOOP_RESET_SIZE 0x4C07
+#endif
+
#if defined(CONFIG_COMPAT) && !defined(HAVE_COMPAT_IOCTL)
# include <linux/ioctl32.h>
# define IOCTL32_COMPATIBLE_PTR ((void*)0)
@@ -634,6 +638,14 @@
return err;
}
+static int loop_reset_size(struct loop_device *lo, struct block_device *bdev)
+{
+ if (figure_loop_size(lo, bdev)) {
+ return -EFBIG;
+ }
+ return 0;
+}
+
static inline int lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf,
char *lbuf, int size, sector_t rblock)
{
@@ -1747,6 +1759,9 @@
case LOOP_GET_STATUS64:
err = loop_get_status64(lo, (struct loop_info64 *) arg);
break;
+ case LOOP_RESET_SIZE:
+ err = loop_reset_size(lo, bdev);
+ break;
default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
}
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#define LOOP_RESET_SIZE 0x4C07
int main(int argc, char **argv)
{
int fd, result;
fd = open(argv[1], O_RDONLY);
result = ioctl(fd, LOOP_RESET_SIZE);
printf("result: %d\n", result);
}