[Android Q&A, Help & Troubleshooting] hello_world.c:
Ok so this took me a long time to figure out, and I didn't find this exact procedure anywhere so I thought to post it here for safekeeping. May it be useful to others. Say thanks if you think so.

The problem: You use adoptable storage in MM or up, but

you're running out of space, OR

you don't trust your sdcard anymore and would like to replace it

But, you have tons of apps and data on there, and want to keep it exactly as it was. You have already figured out that Android offers no tools to migrate adoptable storage to a new card, and actually makes it quite hard to do so. It is possible, albeit involved. But first...

Disclaimer: This is decidedly a 'pro' tutorial. If you've not used adb and Linux shell or don't know what root access is, this is not for you. Making mistakes following this, or even following this without fully understanding what you're doing may cause you to lose all your precious data, destroy your sdcards, lose your nerves and all hopes for mankind. I am not responsible for any damages to your hardware or social life. Don't blame me. You've been warned.

Read on? Good. Hold on to your hats and bear with me. This is what you'll need:

A new sdcard to replace the old one, of equal or bigger size (duh)

Root access to your Android device, adb shell

Two USB sdcard readers

A Linux board or PC (Linux live distro is fine) with at least two USB slots and root shell access. The Linux kernel version must be recent in order to have latest f2fs file system support and tools. I have used the latest Xubuntu ISO (live distro, booted from USB) for this.

With all of the above readily in place, these are the steps:

First, on your Android device, go to Settings - Storage, open the sdcard that is your adoptable storage, open the context menu and choose "eject". This may at a different spot in your device or Android version, look around until you find it.

Physically remove the card

Make sure that USB debugging is enabled and working on your Android and open an adb shell on your PC. Enter 'su' to become root and confirm on the Android device is SuperSU or similar asks for it.

In adb shell, enter the following 'ls' command and observe the output, e.g.:

root@:/ # cd /data/misc/vold
root@:/ # ls -al
total 32
drwx------ 3 root root 4096 2018-10-10 16:55 .
drwxrwx--t 26 system misc 4096 1970-01-01 15:24 ..
drwx------ 2 root root 4096 2018-10-10 15:42 bench
-rw------- 1 root root 16 2018-07-04 21:29 expand_961cbadcafe15c25ac1234294afdfa0c.key
root@:/ #

There may be more than one "expand.... .key" file in there. If you're not sure which one is the one for your card, you'll have to try all of them to figure it out. Sorry, don't know of a better way, if anybody does, leave it in the comments. Now let's look at the binary key in that file and output it in hex:

root@:/ # xxd -g 1 expand_961cbadcafe15c25ac1234294afdfa0c.key
00000000: 1a 74 4d 9f 4e ce e4 64 bb d4 5a 5e 6c 15 35 b0 .tM.N..d..[^l.5.

Make note of the key as we'll need it later - in this example, it is

1a744d9f4ecee464bbd45a5e6c1535b0

While you're here, if you have multiple key files, do the above for all of them and write down all possible keys.

You may close adb.

Now, put your old sdcard and the new sdcard in USB readers and plug the readers into the Linux PC's or board's USB ports. Open up a root shell and enter 'fdisk -l'. The card with the adoptable storage should be easy to spot as it will have two partitions where the first one will be a small 16M one, like this example from a 16GB card:

Disk /dev/sdb: 14.9 GiB, 15962472448 bytes, 31176704 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: C7C77E9E-3C20-409C-CE45-5E6E60B8717C

Device Start End Sectors Size Type
/dev/sdb1 2048 34815 32768 16M unknown
/dev/sdb2 34816 31176670 31141855 14.9G unknown

For the remainder of this tutorial, we will assume that the source card with the adoptable storage is '/dev/sdb' and the target, new card is '/dev/sdc'. If your devices look differently, please replace these accordingly.

Now we clone the source card with the following command (THIS WILL OVERWRITE EVERYTHING IN THE 'of=...' DEVICE!):

dd if=/dev/sdb of=/dev/sdc bs=64k status=progress

Now test the encryption key with the source card:

dmsetup create crypt1 --table "0 `blockdev --getsize /dev/sdb2` crypt aes-cbc-essiv:sha256 1a744d9f4ecee464bbd45a5e6c1535b0 0 /dev/sdb2 0"
mkdir /mnt/as_src
mount -t f2fs /dev/mapper/crypt1 /mnt/as_src
ls /mnt/as_src

If you get errors, the key is wrong and you should do 'umount /mnt/as_src', then 'dmsetup remove crypt1', then repeat the above with the next key (not the 'mkdir' of course) until you succeed.

This only if the new card is bigger: We expand the second partition on the target card (here: /dev/sdc) using parted:

# parted /dev/sdc
GNU Parted 3.2
Using /dev/sdc
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted)

Enter "print" to list the partitions - they should look the same as in the fdisk -l command above for the source card. After all, this is a clone. But the card size should be bigger. Now enter

resizepart 2 100%
quit

Now we have made the second partition bigger, but the encrypted file system still doesn't know about it. We now have to create the encrypted device and expand the file system (needs the package f2fs-tools):

dmsetup create crypt2 --table "0 `blockdev --getsize /dev/sdc2` crypt aes-cbc-essiv:sha256 1a744d9f4ecee464bbd45a5e6c1535b0 0 /dev/sdc2 0"
resize.f2fs /dev/mapper/crypt2

This should run through ok but will take a while. Go grab a coffee. After it has finished, verify that the encrypted storage is available by mounting it:

mkdir /mnt/as_dst
mount -t f2fs /dev/mapper/crypt2 /mnt/as_dst
ls /mnt/as_dst

No errors but you see the list of files and directories? Congrats - you are almost there! Now let's get outta here:

umount /mnt/as_src
umount /mnt/as_dst
dmsetup remove_all
eject /dev/sdc
eject /dev/sdb

Remove the card readers and insert the new card in your Android device. It should detect it as the original, do "checking" for a while and then see it normally, just with more space in case you migrated to a bigger card.

You did it! :good: