Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Oct 1997 17:37:15 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        grog@lemis.com (Greg Lehey)
Cc:        james@reef.com, freebsd-hackers@FreeBSD.ORG
Subject:   Re: Recovering Lost Inode?
Message-ID:  <199710281737.KAA27459@usr06.primenet.com>
In-Reply-To: <19971028153059.20678@lemis.com> from "Greg Lehey" at Oct 28, 97 03:30:59 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> > Thanks for the response.  I'm sure it's too late now, with inode
> > recycling, etc.  However, if I had been unable to umount the
> > filesystem... (we now enter the theoretical zone)
> > *could* I have been able to use somekindof Norton's Utilities-esque
> > package for UNIX which could check inodes and look for ones that
> > were 'file starters', and maybe check the that if all of the inodes
> > pointed to by that starter inode (it was big file so I excect
> > a level or two of inode redirection) were still intact it could
> > pull it back?  Kinda like an 'un-delete' fsck?  Ever hear of
> > such a thing?
> 
> Good question.  I don't have a good answer.  The first big problem is
> identifying the inode.  You could have literally millions to check.

After deleting some important code, I immediately hit the power switch.


With a daemon holding the reference, you could have sync'ed your system
and flipped the switch, and the inode would be unreferenced by a directory,
but present.

A boot to single user mode (assuming the inode wasn't on / -- you'd
need a floppy boot for that) and an fsck without "-y" (the default if
you don't run it manually), and you could force the inode to come
back in lost+found by saying "no" to a "clear?" prompt.

If you delete the reference, hitting the power without a sync is the
best bet to prevent the file's blocks being reused.



The following assumes that you are not mounted "async", and you are
using FFS (if you are mounting "async", you should probably change
every occurance of "async" to "I_dont_care_if_you_eat_my_files" in
the code to be more accurate about its function).


Now it is time to grovel the disk.

If you knew the previous location of the file, and it was not the
first entry in a directory block, then the space used by the dirent
was recovered by concatenating the space to the entry immediately
previous to it.  This will have the inode number in it (check here
first).

If the entry was compacted by a subsequent create (create/rename/link)
operation, then it was destroyed.  If the entry was the first entry
in the directory block, it could not be compacted.  Because FFS does
not use a "deleted" flag bit, it indicated the deleted entry by
zeroing the inode number (this is bogus, but I can't commit a fix).
In either case, the inode number information is lost.


If the inode number information is lost, you can look for the inode
by inverse masking.  You do this by finding all the inodes with a
non-zero reference count.  When you find these... these aren't the
onces you're looking for.

If you have lost either the inode or direct or indirect block
mappings, the problem gets harder.

Again you can use inverse masking: blocks which are allocated in
the allocation bitmap.... aren't the ones you're looking for.

At this point, you have only reduced the search space.  Now you
have to go through the block contents looking for something you
recognize as the correct file contents.  Clearly, this is pretty
useless with executables.

However, if you find file contents, you can find the inode or
indirect block that refers to the identified content block.  If you
can do this, you can traverse the chain and find some or all of the
rest of the file.

It is useful to build an "unallocated block contents grepper" and
supply it with a string you know is in the file, but unlikely to
be found in other files.

Generally, if the disk is not overfull already, you will find the
file data in write clusters (most blocks will be physically contiguous
to previous blocks).  This won't work for frags, but frags will
either start at the start of the block, or they will be a member of
a frag block.

Finally, it is useful to build a "block list assembly editor"; it's
purpose is to make it easier to recognize candidate blocks.  Say you
have a block ending with "We hold these truths to be self evi".  The
next block in sequence will have a high probability of starting
with "dent".  This relies on you, the human syntactic pattern recognizer.

With a couple of home-grown tools (FS's are generally different enough
in layout that the tools must be home grown, since you must have order
of operation clues to make some of the above assumptions) and a little
patience, you can usually recover most if not all of your data.


On the other hand, you could just keep reasonable backups.  8-) 8-).


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199710281737.KAA27459>