Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HOW-TO : undelete linux files (ext2fs/debugfs)

20 views
Skip to first unread message

Robin Glover

unread,
Jan 31, 1996, 3:00:00 AM1/31/96
to
I posted here a little while ago asking for information on this subject,
and ended up with lots of 'hey, I'd like to know too!' emails. A little
digging through source code of debugfs / ext2fs etc came up with some of the
answers, so here goes.

HOWTO undelete a file under linux ext2fs

The first answer is don't delete it in the first place, this isn't as easy
as using an undeletion tool under dos. You could do something like writing
a shell script round rm that actually moves the file to a subdirectory like
.deleted-files. There are probably utilities around to do this.

Okay, that wasn't much of an answer, so here's how to really undelete a file:

1) Stop any further damage to the file you've deleted.

I seem to recall that recently deleted blocks are likely to be used
first under ext2fs, but I can't remember where I saw it. Even if that's not
true, it's best to stop anything else from trying to overwrite your
precious data. Anyway, you're not going to mess around with a read/write
mounted filesystem are you?

-> unmount the filesystem, or remount it read-only

if /dev/hdb5 is mounted on /home, use

$ umount /dev/hda5

or

$ mount -r -o remount /home

I'm not sure how you do this if it's on the root filesystem (suggestions
please). NOTE - you must do this as soon as possible after you rm the file.


2) Run debugfs on the filesystem

$ debugfs /dev/hda5

or (for the brave or experienced)

$ debugfs -w /dev/hda5

which enables write access.


3) List the deleted files in the filesystem using lsdel in debugfs

debugfs: lsdel

as far as I know, the files are listed in order of deletion, so your
treasured data should be near the bottom of the list. No filenames listed I'm
afraid, so you'll have to recognize the file by size, deleteion time,
ownership and attributes. Note down the inode number, which is the left hand
column.

4) Find the info on that inode, using

debugfs: stat <inode_number>

i.e. stat <20557> (yes, use the <>'s)

5) Now comes the interesting bit...

the ext2fs stores the position of the data blocks of the file in a list. It
has 12 entries in the inode for direct blocks, one for an indirect block,
which points to a block full of block numbers, one for a doubly indirect
block which points to a block full of block numbers for more indirect blocks.
And a treble indirect block. You get the idea. Trouble is, when you delete
a file the indirect blocks (of all flavours) seem to be overwritten with
zeros. I don't know why ext2fs does this, or even if it's really necessary.
Its a pain anyway. The upshot of this is:

if your file is 12 blocks or less, (<12K usually), you have the block numbers
in the inode. You can set the in use flags for those blocks (setb block_no),
set the in use flag for the inode (seti <inode_number>), modify the inode
(using mi <inode_number>) to set its dtime to zero, and increase its link
count to one. Then create a link from some directory on that fs to the inode
using link <inode_number> new_file_name. Quit debugfs and run e2fsck -f on
the system to fix the summary information. You should have your file back.

If your file is more than 12 blocks, or you don't fancy mucking about with
debugfs too much, you can try this...

i) hope the file isn't fragmented - if it is, you're stuffed

ii) work out where the data blocks are, and write them down somewhere. The
first 12 blocks are listed in the inode, the next 256 (hopefully) follow
the block the first indirect entry points to, then (this is starting to
get speculative) a double indirect block, followed by a single indirect
block (which would have been pointed to by the first index in the double
one), follower by 256 data blocks, another single, 256 data and so on.

iii) Get a rescue filesystem handy, a floppy or another partition.

iv) use dd:

if you want to see what's in block 1244, use

$ dd if=/dev/hda5 bsize=1024 skip=1244 count=1 | od

piping the output to od gives you a chance to see it (in octal with no
options on od) without the control characters doing nasty things to your
terminal. Indirect blocks are full of zeros, others should contain your
data. Used carefully, you should be able to confirm your suspicions about
positions of data and indirect blocks.

v) recover data with dd

to get the first 12 blocks, you could use

$ dd if=/dev/hda5 bsize=1024 skip=1244 count=1 of=/other_partition/recover

you can append more blocks to the end of your recover file using the >>
operator from other dd commands, ie

$ dd if=/dev/hda5 bsize=1024 skip=1257 count=256 >> /other_partition/recover

You (may) have recovered your file...

Well, thats that. It's only an outline, and not too well written, and for all
those people with lawyers out there - remember:

I disclaim any responsibility for any damage, direct or indirect, caused
by the use of the information contained in this post, or by any errors,
factual or otherwise, contained therein. Those using this information do
so entirely at their own risk.

"Undelete utilities can help preserve sanity only when used with a carefully
organised backup schedule"


Any further comments, hints, tips or corrections welcome.

Robin

0 new messages