bfs_tools: add some extra checks to avoid crashes.

I'm not sure I'm fixing the root cause of problems here, but this avoids
some crashes and I could recover my files this way.
This commit is contained in:
Adrien Destugues 2015-07-13 18:09:18 +02:00
parent 10e6523159
commit 76e7f5688d
3 changed files with 23 additions and 11 deletions

View File

@ -108,7 +108,7 @@ Inode::SetTo(bfs_inode *inode)
status_t status_t
Inode::InitCheck() Inode::InitCheck() const
{ {
if (!fInode) if (!fInode)
return B_ERROR; return B_ERROR;
@ -304,6 +304,10 @@ Inode::SetName(const char *name)
const char * const char *
Inode::Name() const Inode::Name() const
{ {
if (InitCheck() != B_OK) {
puts("Not getting name because node is invalid");
return NULL;
}
small_data *data = fInode->small_data_start; small_data *data = fInode->small_data_start;
while (!data->IsLast(fInode)) { while (!data->IsLast(fInode)) {
if (data->type == FILE_NAME_TYPE if (data->type == FILE_NAME_TYPE
@ -929,7 +933,7 @@ File::~File()
status_t status_t
File::InitCheck() File::InitCheck() const
{ {
status_t status = DataStream::InitCheck(); status_t status = DataStream::InitCheck();
if (status == B_OK) if (status == B_OK)
@ -1006,7 +1010,7 @@ Attribute::~Attribute()
status_t status_t
Attribute::InitCheck() Attribute::InitCheck() const
{ {
status_t status = DataStream::InitCheck(); status_t status = DataStream::InitCheck();
if (status == B_OK) if (status == B_OK)
@ -1053,7 +1057,7 @@ Directory::~Directory()
status_t status_t
Directory::InitCheck() Directory::InitCheck() const
{ {
status_t status = DataStream::InitCheck(); status_t status = DataStream::InitCheck();
if (status == B_OK) if (status == B_OK)
@ -1322,7 +1326,7 @@ Symlink::~Symlink()
status_t status_t
Symlink::InitCheck() Symlink::InitCheck() const
{ {
status_t status = Inode::InitCheck(); status_t status = Inode::InitCheck();
if (status == B_OK) if (status == B_OK)

View File

@ -20,7 +20,7 @@ class Inode {
virtual ~Inode(); virtual ~Inode();
status_t SetTo(bfs_inode *inode); status_t SetTo(bfs_inode *inode);
virtual status_t InitCheck(); virtual status_t InitCheck() const;
bool IsFile() const { return S_ISREG(fInode->mode); } bool IsFile() const { return S_ISREG(fInode->mode); }
bool IsDirectory() const { return S_ISDIR(fInode->mode); } bool IsDirectory() const { return S_ISDIR(fInode->mode); }
@ -131,7 +131,7 @@ class File : public DataStream {
File(const Inode &inode); File(const Inode &inode);
~File(); ~File();
virtual status_t InitCheck(); virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true, virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL); Inode::Source *source = NULL);
}; };
@ -143,7 +143,7 @@ class Attribute : public File {
Attribute(const Inode &inode); Attribute(const Inode &inode);
~Attribute(); ~Attribute();
virtual status_t InitCheck(); virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true, virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL); Inode::Source *source = NULL);
@ -157,7 +157,7 @@ class Directory : public DataStream {
Directory(const Inode &inode); Directory(const Inode &inode);
~Directory(); ~Directory();
virtual status_t InitCheck(); virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true, virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL); Inode::Source *source = NULL);
@ -186,7 +186,7 @@ class Symlink : public Inode {
Symlink(const Inode &inode); Symlink(const Inode &inode);
~Symlink(); ~Symlink();
virtual status_t InitCheck(); virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath = true, virtual status_t CopyTo(const char *path, bool fullPath = true,
Inode::Source *source = NULL); Inode::Source *source = NULL);

View File

@ -440,7 +440,15 @@ checkStructure(Disk &disk)
if (node->IsDirectory() && !node->IsIndex()) { if (node->IsDirectory() && !node->IsIndex()) {
// check if all entries are in the hashtable // check if all entries are in the hashtable
checkDirectoryContents(disk, (Directory*)node); Directory* directory = dynamic_cast<Directory*>(node);
if (directory != NULL)
checkDirectoryContents(disk, directory);
else {
printf("Node \"%s\" at %" B_PRId32
",%d looks like a directory, but isn't.\n",
node->Name(), node->BlockRun().allocation_group,
node->BlockRun().start);
}
} }
// check for the parent directory // check for the parent directory