[ ] Unify lowmem and original mode into one mode. We should be able to do this fast and without using all the memory.
[ ] Easily undo our work. We currently pin all of the blocks before we repair, so we could get back to normal. The problem is we commit the transaction any time we change something, so we'll burn through our backups. Add the ability to save the original super block, pin all the blocks, do the repair. Then redo the check, and if there are any errors after we've done the repair then we need to revert back to the original file system. This will allow us to use --repair safely in the case that --repair doesn't fix anything.
[ ] We need to handle hard corruption cases properly. Things like a missed write so we've lost a whole leaf or a whole node means that fsck stops. We could potentially rebuild that information from other metadata, so add a initial pass that validates all the trees, and repairs anything like transid mismatches, or simply removes links to corrupt leaf/nodes, and then follow through with the rest of the repair code to see what can be rebuilt.
[ ] Detect bitflips better. Sometimes a single bitflip can be easily reconciled. This could be handled in the tree validation step. If we have a btrfs_item for example that has a bogus len, but it's a bitflip, then we should be able to infer the correct len and fix the item directly.
Loads of work that needs to be done here