OK, so I finally fixed this!
This solution should also work for other filesystems if GParted does the same 'direct copy'. Obviously you'll need to use something other than chkdsk
at the end.
Anyway, here's the procedure for solving the problem for the benefit of anyone who's as unlucky/stupid* as me:
Before you start, relax - go get yourself some coffee or a mug of hot chocolate!
Your data is still on the disk, you just need to look for it. Spending time calmly checking things over won't harm you. Rushing and being impulsive might.
Read this through thoroughly and make sure you understand each step. If you then decide to follow these instructions it's probably a good idea to make a backup on a separate disk using dd
. It's easy to make mistakes and a backup would give you a safety net.
Make sure you make a note of any information about the last thing GParted was doing. You'll want to know how far the copy operation got (as precise as possible) and how far backwards/forwards it was copying things.
Work out the exact location where the copy finished. I've written two Python scripts to help with this but they've only been tested on ubuntu (definitely won't work in Windows) and need modification for your specific case.
Firstly use this to find a single matching sector on the disk: findDuplicateSector.py
Then use this to find the last matching sector (i.e. where the operation was interrupted): findCopyInterruptLocation.py
Read the code and make sure you understand it. I've tested it briefly but there may be bugs. All numbers given are absolute offsets from the start of the partition/file, i.e. offset 0 is the first sector in the partition and offset n is the n+1th sector.
Use dd
or something similar to complete the copy operation, taking care not to get the input and output offsets confused. Here's the syntax for dd
:
sudo dd bs=512 skip=<input_offset> if=<partition> seek=<output_offset> of=<partition> count=<num_sectors_to_copy>
This step will take a long time (it took me 8 hours). If you want to see how its progressing, run this in a separate terminal and dd
will give you an update on its progress in its own terminal window:
sudo kill -s USR1 <PID_of_dd>
Check the following and correct if necessary:
The Master Boot Record (MBR)'s partition table entries should match what you told GParted to do (see the wikipedia article, it's very informative). Specifically check the value for the LBA of the first sector of the partition and its total number of sectors.
The Partition Boot Record of the partition you're modifying should match MBR (in my case it didn't). For NTFS the total partition size in sectors should be at offset 40 from the start of the partition. I don't think NTFS records what the offset of the partition relative to the start of the disk is though.
Run chkdsk
in read-only mode, i.e. with no command line arguments other than the drive name to check that it can find all the files in the partition. If it fails to verify the file indexes then DO NOT continue. Don't worry if it complains about the $Bitmap file containing errors.
If, and only if step 5 succeeded, run chkdsk /f
to fix for example the $Bitmap file. If you run this while file indexes are still wrong it may end up deleting them, making things much more difficult for you.
You might want to run chkdsk
in read-only mode again to make sure it worked, just for peace of mind.
*Actually I'm too arrogant - we're not stupid. But seriously - make backups!