From 1aba9ab44409ccd32240de10141ae5ea4eccf554 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Wed, 19 Aug 2015 14:16:42 +0200 Subject: [PATCH] Cryptsetup resize will try resize also underlying device. If encrypted device is file-backed, resize should try to resize underlying loop device as well. --- lib/setup.c | 8 ++++++++ lib/utils_loop.c | 23 +++++++++++++++++++++-- lib/utils_loop.h | 4 +++- tests/compat-test | 4 ++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/setup.c b/lib/setup.c index 01e2c80a..bd0c1b84 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -1387,6 +1387,14 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) goto out; } + if (crypt_loop_device(crypt_get_device_name(cd))) { + log_dbg("Trying to resize underlying loop device %s.", + crypt_get_device_name(cd)); + /* Here we always use default size not new_size */ + if (crypt_loop_resize(crypt_get_device_name(cd))) + log_err(NULL, _("Cannot resize loop device.\n")); + } + r = device_block_adjust(cd, dmd.data_device, DEV_OK, dmd.u.crypt.offset, &new_size, &dmd.flags); if (r) diff --git a/lib/utils_loop.c b/lib/utils_loop.c index d7b03a13..ff30a27c 100644 --- a/lib/utils_loop.c +++ b/lib/utils_loop.c @@ -1,8 +1,8 @@ /* * loopback block device utilities * - * Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2012, Milan Broz + * Copyright (C) 2011-2015, Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2015, Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -42,6 +42,10 @@ #define LOOP_CTL_GET_FREE 0x4C82 #endif +#ifndef LOOP_SET_CAPACITY +#define LOOP_SET_CAPACITY 0x4C07 +#endif + static char *crypt_loop_get_device_old(void) { char dev[20]; @@ -157,6 +161,21 @@ int crypt_loop_detach(const char *loop) return r; } +int crypt_loop_resize(const char *loop) +{ + int loop_fd = -1, r = 1; + + loop_fd = open(loop, O_RDONLY); + if (loop_fd < 0) + return 1; + + if (!ioctl(loop_fd, LOOP_SET_CAPACITY, 0)) + r = 0; + + close(loop_fd); + return r; +} + static char *_ioctl_backing_file(const char *loop) { struct loop_info64 lo64 = {0}; diff --git a/lib/utils_loop.h b/lib/utils_loop.h index 052623d8..e8c2a5dd 100644 --- a/lib/utils_loop.h +++ b/lib/utils_loop.h @@ -1,7 +1,8 @@ /* * loopback block device utilities * - * Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2015, Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2015, Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,5 +30,6 @@ int crypt_loop_device(const char *loop); int crypt_loop_attach(const char *loop, const char *file, int offset, int autoclear, int *readonly); int crypt_loop_detach(const char *loop); +int crypt_loop_resize(const char *loop); #endif /* _UTILS_LOOP_H */ diff --git a/tests/compat-test b/tests/compat-test index 5247fd33..2dbc7c1b 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -361,6 +361,10 @@ $CRYPTSETUP -q resize $DEV_NAME --size 100 || fail $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail $CRYPTSETUP -q resize $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "19997 sectors" || fail +# Resize underlying loop device as well +truncate -s 16M $IMG || fail +$CRYPTSETUP -q resize $DEV_NAME || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "32765 sectors" || fail $CRYPTSETUP -q remove $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME >/dev/null && fail echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha1 $LOOPDEV || fail