Resizing a reiserfs loopback device encrypted with dm-crypt.

My home directories are encrypted via dm-crypt / cryptsetup using a loopback device and formatted with the reiserfs filesystem. See Disk cryptography with dm-crypt and SECURITY dmcrypt - Gentoo Linux Wiki.

For the user 'bn', the image is a 5G file called /home/bn.img. It is set up as loopback device /dev/loop1 then mapped to crypt-bn and mounted as /home/bn.

The problem is that the image file does not automatically resize when it runs out of space.

Resizing reiserfs crypt mounted with dm-crypt

This assumes that the device is in use. If not, just ignore the first 3 steps.

  1. Unmount the file system with umount.
  2. Remove the crypt device mapping with cryptsetup.
  3. Detach the loop device with losetup.
  4. Back up the image file!
  5. Add data to the end of the image file with dd.
  6. Reattach the loop device with losetup.
  7. Recreate the crypt device mapping with cryptsetup.
  8. Resize the reiserfs filesystem with resize_reiserfs.
  9. Remount the file system with mount.
  10. Verify new size with df.

Detail

To begin, I restarted my computer and entered the incorrect password for crypt-bn. Once logged in to the system (as a different user) I backed up image bn.img to a seperate computer. Then I did the steps outlined above, with a few tests in between to make sure everything was going to plan...

root@localhost home # umount /home/bn
umount: /home/bn: not mounted
root@localhost home # dmsetup ls
crypt-steph     (254, 3)
crypt-swap      (254, 0)
crypt-bn        (254, 2)
crypt-tmp       (254, 1)
root@localhost home # cryptsetup remove crypt-bn
root@localhost home # dmsetup ls
crypt-steph     (254, 3)
crypt-swap      (254, 0)
crypt-tmp       (254, 1)
root@localhost home # losetup -a
/dev/loop0: [0808]:942290 (/tmp.img)
/dev/loop1: [0808]:946234 (/home/bn.img)
/dev/loop2: [0808]:344097 (/home/steph.img)
/dev/loop/0: [0808]:942290 (/tmp.img)
/dev/loop/1: [0808]:946234 (/home/bn.img)
/dev/loop/2: [0808]:344097 (/home/steph.img)
root@localhost home # losetup -d /dev/loop1
root@localhost home # losetup -a
/dev/loop0: [0808]:942290 (/tmp.img)
/dev/loop2: [0808]:344097 (/home/steph.img)
/dev/loop/0: [0808]:942290 (/tmp.img)
/dev/loop/2: [0808]:344097 (/home/steph.img)
root@localhost home # dd if=/dev/urandom bs=1M count=3072 >> bn.img

I forgot to make note of the exact output here, but suffice to say the data was written to bn.img.

root@localhost home # losetup -f
/dev/loop1
root@localhost home # losetup /dev/loop1 /home/bn.img
root@localhost home # cryptsetup -y -c serpent -s 256 create crypt-bn /dev/loop1
Enter passphrase: 
Verify passphrase: 
root@localhost home # resize_reiserfs /dev/mapper/crypt-bn 
resize_reiserfs 3.6.19 (2003 www.namesys.com)

ReiserFS report:
blocksize             4096
block count           2066432 (1280000)
free blocks           803801 (17393)
bitmap block count    64 (40)

Syncing..done


resize_reiserfs: Resizing finished successfully.

root@localhost home # mount /dev/mapper/crypt-bn /home/bn
root@localhost home # df -lh /home/bn
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/crypt-bn  7.9G  4.9G  3.1G  62% /home/bn

Success! The new size is 7.9G, with 3.1G unused.

References

Unused related links

Tests

Some tests I did before resizing my important data.

Here I play with an image file called crypttest, which is set as loopback /dev/loop3, mapped to /dev/mapper/mycrypt and mounted as cryptmount.

Create crypt

root@localhost steph # dd if=/dev/urandom bs=1M count=2 > crypttest
2+0 records in
2+0 records out
2097152 bytes (2.1 MB) copied, 0.673763 s, 3.1 MB/s
root@localhost steph # ls -l crypttest 
-rw-r--r-- 1 steph users 2097152 May 30 14:13 crypttest
root@localhost steph # losetup -f
/dev/loop3
root@localhost steph # losetup /dev/loop3 crypttest
root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
Verify passphrase:
root@localhost steph # dmsetup ls
mycrypt (254, 4)
crypt-steph     (254, 3)
crypt-swap      (254, 0)
crypt-bn        (254, 2)
crypt-tmp       (254, 1)
root@localhost steph # mkreiserfs /dev/mapper/mycrypt 
mkreiserfs 3.6.19 (2003 www.namesys.com)

A pair of credits:
Yury Umanets  (aka Umka)  developed  libreiser4,  userspace  plugins,  and  all
userspace tools (reiser4progs) except of fsck.

Vladimir Saveliev started as the most junior programmer on the team, and became
the lead programmer.  He is now an experienced highly productive programmer. He
wrote the extent  handling code for Reiser4,  plus parts of  the balancing code 
and file write and file read.


Guessing about desired format.. Kernel 2.6.18-gentoo-r6 is running.
reiserfs_create_journal: cannot create a journal of 8193 blocks with 18 offset on 512 blocks

Too small! Recreate at over 32M (521/2 = 256. 8193/256 ~= 32). I'll do 100M

root@localhost steph # cryptsetup remove mycrypt
root@localhost steph # dmsetup ls
crypt-steph     (254, 3)
crypt-swap      (254, 0)
crypt-bn        (254, 2)
crypt-tmp       (254, 1)
root@localhost steph # losetup -d /dev/loop3
root@localhost steph # losetup -f
/dev/loop3
root@localhost steph # dd if=/dev/urandom bs=1M count=100 > crypttest
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 34.2838 s, 3.1 MB/s
root@localhost steph # ls -l crypttest 
-rw-r--r-- 1 steph users 104857600 May 30 14:38 crypttest
root@localhost steph # losetup /dev/loop3 crypttest
root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
Verify passphrase: 
root@localhost steph # dmsetup ls
mycrypt (254, 4)
crypt-steph     (254, 3)
crypt-swap      (254, 0)
crypt-bn        (254, 2)
crypt-tmp       (254, 1)
root@localhost steph # mkreiserfs /dev/mapper/mycrypt 
mkreiserfs 3.6.19 (2003 www.namesys.com)

A pair of credits:
Oleg Drokin was the debugger for  V3 during most of the time that  V4 was under
development,  and was quite  skilled and fast at it.  He wrote  the large write
optimization of V3.

Jeremy  Fitzhardinge  wrote  the  teahash.c  code  for  V3.  Colin  Plumb  also
contributed to that.


Guessing about desired format.. Kernel 2.6.18-gentoo-r6 is running.
Format 3.6 with standard journal
Count of blocks on the device: 25600
Number of blocks consumed by mkreiserfs formatting process: 8212
Blocksize: 4096
Hash function used to sort names: "r5"
Journal Size 8193 blocks (first block 18)
Journal Max transaction length 1024
inode generation number: 0
UUID: da6a44e2-f7f8-4e69-a5d3-7c9c70b8adaf
ATTENTION: YOU SHOULD REBOOT AFTER FDISK!
        ALL DATA WILL BE LOST ON '/dev/mapper/mycrypt'!
Continue (y/n):y
Initializing journal - 0%....20%....40%....60%....80%....100%
Syncing..ok

Tell your friends to use a kernel based on 2.4.18 or later, and especially not a
kernel based on 2.4.9, when you use reiserFS. Have fun.

ReiserFS is successfully created on /dev/mapper/mycrypt.
root@localhost steph # mount /dev/mapper/mycrypt cryptmount

Create test files

root@localhost steph # echo "testing testing 123" > cryptmount/test1.txt
root@localhost steph # mkdir cryptmount/testdir
root@localhost steph # echo "testing testing 234" > cryptmount/testdir/test2.txt
root@localhost steph # echo "testing testing 345" > cryptmount/testdir/test3.txt
root@localhost steph # cat cryptmount/test1.txt         
testing testing 123
root@localhost steph # cat cryptmount/testdir/test2.txt 
testing testing 234
root@localhost steph # cat cryptmount/testdir/test3.txt 
testing testing 345

Test unmount

root@localhost steph # umount cryptmount
root@localhost steph # cryptsetup remove mycrypt
root@localhost steph # losetup -d /dev/loop3
root@localhost steph # losetup -f
/dev/loop3
root@localhost steph # dmsetup ls
crypt-steph     (254, 3)
crypt-swap      (254, 0)
crypt-bn        (254, 2)
crypt-tmp       (254, 1)

Test remount

root@localhost steph # losetup /dev/loop3 crypttest
root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
Verify passphrase: 
root@localhost steph # mount /dev/mapper/mycrypt cryptmount 
root@localhost steph # ls cryptmount/
test1.txt  testdir
root@localhost steph # cat cryptmount/test1.txt 
testing testing 123
root@localhost steph # cat cryptmount/testdir/test2.txt 
testing testing 234
root@localhost steph # cat cryptmount/testdir/test3.txt 
testing testing 345

Test resize

root@localhost steph # umount cryptmount
root@localhost steph # cryptsetup remove mycrypt
root@localhost steph # losetup -d /dev/loop3
root@localhost steph # losetup -f
/dev/loop3
root@localhost steph # dmsetup ls
crypt-steph     (254, 3)
crypt-swap      (254, 0)
crypt-bn        (254, 2)
crypt-tmp       (254, 1)
root@localhost steph # dd if=/dev/urandom bs=1M count=50 >> crypttest
50+0 records in
50+0 records out
52428800 bytes (52 MB) copied, 15.263 s, 3.4 MB/s
root@localhost steph # ls -l crypttest
-rw-r--r-- 1 steph users 157286400 May 30 14:56 crypttest
root@localhost steph # losetup /dev/loop3 crypttest
root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
Verify passphrase: 
root@localhost steph # resize_reiserfs /dev/mapper/mycrypt 
resize_reiserfs 3.6.19 (2003 www.namesys.com)

ReiserFS report:
blocksize             4096
block count           38400 (25600)
free blocks           30187 (17388)
bitmap block count    2 (1)

Syncing..done


resize_reiserfs: Resizing finished successfully.

 root@localhost steph # mount /dev/mapper/mycrypt cryptmount 
root@localhost steph # ls cryptmount/
test1.txt  testdir
root@localhost steph # df cryptmount 
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/mycrypt     153588     32840    120748  22% /home/steph/cryptmount
root@localhost steph # df -h cryptmount
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/mycrypt   150M   33M  118M  22% /home/steph/cryptmount
root@localhost steph # cat cryptmount/test1.txt 
testing testing 123
root@localhost steph # cat cryptmount/testdir/test2.txt 
testing testing 234
root@localhost steph # cat cryptmount/testdir/test3.txt 
testing testing 345

Test password

root@localhost steph # losetup /dev/loop3 crypttest 
root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3 
Enter passphrase: (incorrect password entered)
root@localhost steph # mount /dev/mapper/mycrypt cryptmount/
mount: you must specify the filesystem type

Good, so an incorrect password results in a crypt that can't be accessed.

Test 'cryptsetup resize'

One thing was left unanswered... What is 'cryptsetup resize' for?

Perhaps for resizing a block device that has changed size whilst mapped. See Re: how to use cryptsetup resize?.

Time for some tests (spoiler: couldn't find any discernible changes made by 'cryptsetup resize')...

Clean start

root@localhost steph # cryptsetup remove mycrypt
root@localhost steph # losetup -d /dev/loop3
root@localhost steph # dd if=/dev/urandom bs=1M count=100 > crypttest 
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 33.7287 s, 3.1 MB/s
root@localhost steph # losetup /dev/loop3 crypttest
root@localhost steph # cryptsetup -y -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
Verify passphrase: 
root@localhost steph # mkreiserfs /dev/mapper/mycrypt 
mkreiserfs 3.6.19 (2003 www.namesys.com)

A pair of credits:
The  Defense  Advanced  Research  Projects Agency (DARPA, www.darpa.mil) is the
primary sponsor of Reiser4.  DARPA  does  not  endorse  this project; it merely 
sponsors it.

Vitaly Fertman wrote  fsck for V3 and  maintains the reiserfsprogs package now.
He wrote librepair,  userspace plugins repair code, fsck for V4,  and worked on
developing libreiser4 and userspace plugins with Umka.


Guessing about desired format.. Kernel 2.6.18-gentoo-r6 is running.
Format 3.6 with standard journal
Count of blocks on the device: 25600
Number of blocks consumed by mkreiserfs formatting process: 8212
Blocksize: 4096
Hash function used to sort names: "r5"
Journal Size 8193 blocks (first block 18)
Journal Max transaction length 1024
inode generation number: 0
UUID: 2e1b01ea-8376-4f07-8e95-7470abb4bc6d
ATTENTION: YOU SHOULD REBOOT AFTER FDISK!
        ALL DATA WILL BE LOST ON '/dev/mapper/mycrypt'!
Continue (y/n):y
Initializing journal - 0%....20%....40%....60%....80%....100%
Syncing..ok

Tell your friends to use a kernel based on 2.4.18 or later, and especially not a
kernel based on 2.4.9, when you use reiserFS. Have fun.

ReiserFS is successfully created on /dev/mapper/mycrypt.
root@localhost steph # mount /dev/mapper/mycrypt cryptmount 
root@localhost steph # dd if=/dev/zero > cryptmount/zeroes
dd: writing to `standard output': No space left on device
138961+0 records in
138960+0 records out
71147520 bytes (71 MB) copied, 2.78217 s, 25.6 MB/s
root@localhost steph # ls -l cryptmount/zeroes 
-rw-r--r-- 1 root root 71147520 Jun  2 00:19 cryptmount/zeroes
root@localhost steph # df cryptmount
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/mycrypt     102392    102392         0 100% /home/steph/cryptmount

Resize crypttest

root@localhost steph # dd if=/dev/urandom bs=1M count=100 >> crypttest 
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 30.4674 s, 3.4 MB/s
root@localhost steph # cryptsetup resize mycrypt
root@localhost steph # resize_reiserfs /dev/mapper/mycrypt
resize_reiserfs 3.6.19 (2003 www.namesys.com)

/dev/mapper/mycrypt already is of the needed size. Nothing to be done

Reiserfs doesn't think crypt size has changed. Perhaps 'cryptsetup resize' already resized the reiserfs filesystem...

root@localhost steph # umount cryptmount
root@localhost steph # mount /dev/mapper/mycrypt cryptmount
root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes
dd: writing to `standard output': No space left on device
1+0 records in
0+0 records out
0 bytes (0 B) copied, 0.0295515 s, 0.0 kB/s
root@localhost steph # ls -l cryptmount/zeroes 
-rw-r--r-- 1 root root 71147520 Jun  2 00:22 cryptmount/zeroes
root@localhost steph # df cryptmount
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/mycrypt     102392    102392         0 100% /home/steph/cryptmount

It didn't. Recreate crypt and try again...

root@localhost steph # umount cryptmount 
root@localhost steph # cryptsetup remove mycrypt
root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
root@localhost steph # mount /dev/mapper/mycrypt cryptmount 
root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes
dd: writing to `standard output': No space left on device
1+0 records in
0+0 records out
0 bytes (0 B) copied, 0.0294059 s, 0.0 kB/s
root@localhost steph # ls -l cryptmount/zeroes 
-rw-r--r-- 1 root root 71147520 Jun  2 00:24 cryptmount/zeroes
root@localhost steph # resize_reiserfs /dev/mapper/mycrypt
resize_reiserfs 3.6.19 (2003 www.namesys.com)

/dev/mapper/mycrypt already is of the needed size. Nothing to be done

Reiserfs still doesn't think crypt size has changed. Need to reset loop?...

root@localhost steph # umount cryptmount 
root@localhost steph # cryptsetup remove mycrypt
root@localhost steph # losetup -d /dev/loop3 
root@localhost steph # losetup /dev/loop3 crypttest
root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
root@localhost steph # mount /dev/mapper/mycrypt cryptmount
root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes
dd: writing to `standard output': No space left on device
1+0 records in
0+0 records out
0 bytes (0 B) copied, 0.00282065 s, 0.0 kB/s
root@localhost steph # ls -l cryptmount/zeroes 
-rw-r--r-- 1 root root 71147520 Jun  2 00:27 cryptmount/zeroes
root@localhost steph # umount cryptmount
root@localhost steph # resize_reiserfs /dev/mapper/mycrypt
resize_reiserfs 3.6.19 (2003 www.namesys.com)

ReiserFS report:
blocksize             4096
block count           51200 (25600)
free blocks           25599 (0)
bitmap block count    2 (1)

Syncing..done


resize_reiserfs: Resizing finished successfully.

root@localhost steph # mount /dev/mapper/mycrypt cryptmounts
root@localhost steph # dd if=/dev/zero >> cryptmount/zeroes
dd: writing to `standard output': No space left on device
204593+0 records in
204592+0 records out
104751104 bytes (105 MB) copied, 4.85683 s, 21.6 MB/s
root@localhost steph # ls -l cryptmount/zeroes 
-rw-r--r-- 1 root root 175898624 Jun  2 00:27 cryptmount/zeroes
root@localhost steph # df cryptmount        
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/mycrypt     204788    204788         0 100% /home/steph/cryptmount

Resetting loop works, as expected - no new information discovered.

Resize /dev/loop3

root@localhost steph # umount cryptmount         
root@localhost steph # dd if=/dev/urandom bs=1M count=100 >> /dev/loop3
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 28.5788 s, 3.7 MB/s
root@localhost steph # cryptsetup resize mycrypt
root@localhost steph # resize_reiserfs /dev/mapper/mycrypt 
resize_reiserfs 3.6.19 (2003 www.namesys.com)


reiserfs_open: the reiserfs superblock cannot be found on /dev/mapper/mycrypt.

Reiserfs can't find filesystem. Recreate crypt and try again...

root@localhost steph # cryptsetup remove mycrypt
root@localhost steph # cryptsetup -c serpent -s 256 create mycrypt /dev/loop3
Enter passphrase: 
root@localhost steph # mount /dev/mapper/mycrypt cryptmount 
mount: you must specify the filesystem type
root@localhost steph # resize_reiserfs /dev/mapper/mycrypt 
resize_reiserfs 3.6.19 (2003 www.namesys.com)


reiserfs_open: the reiserfs superblock cannot be found on /dev/mapper/mycrypt.

Filesystem lost. Resizing /dev/loop3 while active is a desctructive action.

Conclusion

Can't find any discernible changes made by 'cryptsetup resize'. Can't find way of resizing block device without recreateing loop hence recreating crypt (and we already know that resizing via this method already works). Must assume that 'cryptsetup resize' applies to block devices that can change size whilst being mapped. Perhaps partitions rather than files?

Last modified: 02/06/2008 Tags: (none)

This website is a personal resource. Nothing here is guaranteed correct or complete, so use at your own risk and try not to delete the Internet. -Stephan

Site Info

Privacy policy

Go to top