hrev49396 adds 2 changesets to branch 'master'
old head: e5e3ac7f7028125602cd86679e171a4c59e0bb06
new head: 76e7f5688dcd7dd36cad23f75701a8b2299580b3
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=76e7f5688dcd+%5Ee5e3ac7f7028
----------------------------------------------------------------------------
10e652315921: bfs_tools: some more structs needed packing.
76e7f5688dcd: 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.
[ Adrien Destugues <pulkomandy@xxxxxxxxx> ]
----------------------------------------------------------------------------
5 files changed, 44 insertions(+), 32 deletions(-)
src/bin/bfs_tools/lib/BPlusTree.h | 26 +++++++++++++-------------
src/bin/bfs_tools/lib/Inode.cpp | 14 +++++++++-----
src/bin/bfs_tools/lib/Inode.h | 10 +++++-----
src/bin/bfs_tools/lib/bfs.h | 16 ++++++++--------
src/bin/bfs_tools/recover.cpp | 10 +++++++++-
############################################################################
Commit: 10e652315921d90b1791ef09935ce438557c7f30
URL: http://cgit.haiku-os.org/haiku/commit/?id=10e652315921
Author: Adrien Destugues <pulkomandy@xxxxxxxxx>
Date: Mon Jul 13 16:08:53 2015 UTC
bfs_tools: some more structs needed packing.
----------------------------------------------------------------------------
diff --git a/src/bin/bfs_tools/lib/BPlusTree.h
b/src/bin/bfs_tools/lib/BPlusTree.h
index 5a53683..d294dc7 100644
--- a/src/bin/bfs_tools/lib/BPlusTree.h
+++ b/src/bin/bfs_tools/lib/BPlusTree.h
@@ -16,12 +16,12 @@
class BPositionIO;
-//****************** on-disk structures ********************
+// ****************** on-disk structures ********************
#define BPLUSTREE_NULL -1LL
#define BPLUSTREE_FREE -2LL
-struct bplustree_header
+struct __attribute__((packed)) bplustree_header
{
uint32 magic;
uint32 node_size;
@@ -30,7 +30,7 @@ struct bplustree_header
off_t root_node_pointer;
off_t free_node_pointer;
off_t maximum_size;
-
+
inline bool IsValidLink(off_t link);
};
@@ -49,21 +49,21 @@ enum bplustree_types {
BPLUSTREE_DOUBLE_TYPE = 6
};
-struct bplustree_node {
+struct __attribute((packed)) bplustree_node {
off_t left_link;
off_t right_link;
off_t overflow_link;
uint16 all_key_count;
uint16 all_key_length;
-
+
inline uint16 *KeyLengths() const;
inline off_t *Values() const;
inline uint8 *Keys() const;
inline int32 Used() const;
- uint8 *KeyAt(int32 index,uint16 *keyLength) const;
-
- uint8 CountDuplicates(off_t offset,bool isFragment) const;
- off_t DuplicateAt(off_t offset,bool isFragment,int8 index) const;
+ uint8 *KeyAt(int32 index, uint16 *keyLength) const;
+
+ uint8 CountDuplicates(off_t offset, bool isFragment) const;
+ off_t DuplicateAt(off_t offset, bool isFragment, int8 index) const;
static inline uint8 LinkType(off_t link);
static inline off_t FragmentOffset(off_t link);
@@ -73,12 +73,12 @@ struct bplustree_node {
#define BPLUSTREE_DUPLICATE_NODE 2
#define BPLUSTREE_DUPLICATE_FRAGMENT 3
-//**************************************
+// **************************************
enum bplustree_traversing {
BPLUSTREE_FORWARD = 1,
BPLUSTREE_BACKWARD = -1,
-
+
BPLUSTREE_BEGIN = 0,
BPLUSTREE_END = 1
};
@@ -89,10 +89,10 @@ class BPlusTree;
class NodeCache : public Cache<off_t> {
public:
NodeCache(BPlusTree *);
-
+
virtual Cacheable *NewCacheable(off_t offset);
bplustree_node *Get(off_t offset);
-// void SetOffset(bplustree_node *,off_t offset);
+// void SetOffset(bplustree_node *, off_t offset);
protected:
BPlusTree *fTree;
diff --git a/src/bin/bfs_tools/lib/bfs.h b/src/bin/bfs_tools/lib/bfs.h
index 490c90d..0d9dff9 100644
--- a/src/bin/bfs_tools/lib/bfs.h
+++ b/src/bin/bfs_tools/lib/bfs.h
@@ -85,7 +85,7 @@ struct __attribute__((packed)) data_stream
int64 size;
};
-//**************************************
+// **************************************
struct bfs_inode;
@@ -95,7 +95,7 @@ struct __attribute__((packed)) small_data
uint16 name_size;
uint16 data_size;
char name[0]; // name_size long, followed by data
-
+
inline char *Name();
inline uint8 *Data();
inline small_data *Next();
@@ -104,10 +104,10 @@ struct __attribute__((packed)) small_data
// the file name is part of the small_data structure
#define FILE_NAME_TYPE 'CSTR'
-#define FILE_NAME_NAME 0x13
-#define FILE_NAME_NAME_LENGTH 1
+#define FILE_NAME_NAME 0x13
+#define FILE_NAME_NAME_LENGTH 1
-//**************************************
+// **************************************
#define SHORT_SYMLINK_NAME_LENGTH 144 // length incl. terminating '\0'
@@ -124,17 +124,17 @@ struct __attribute__((packed)) bfs_inode
inode_addr parent;
inode_addr attributes;
uint32 type; // attribute type
-
+
int32 inode_size;
uint32 etc; // for in-memory
structures (unused in OpenBeOS' fs)
- union {
+ union __attribute__((packed)) {
data_stream data;
char
short_symlink[SHORT_SYMLINK_NAME_LENGTH];
};
int32 pad[4];
small_data small_data_start[0];
-};
+};
#define INODE_MAGIC1 0x3bbe0ad9
#define INODE_TIME_SHIFT 16
############################################################################
Revision: hrev49396
Commit: 76e7f5688dcd7dd36cad23f75701a8b2299580b3
URL: http://cgit.haiku-os.org/haiku/commit/?id=76e7f5688dcd
Author: Adrien Destugues <pulkomandy@xxxxxxxxx>
Date: Mon Jul 13 16:09:18 2015 UTC
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.
----------------------------------------------------------------------------
diff --git a/src/bin/bfs_tools/lib/Inode.cpp b/src/bin/bfs_tools/lib/Inode.cpp
index 9f4634f..eaaf691 100644
--- a/src/bin/bfs_tools/lib/Inode.cpp
+++ b/src/bin/bfs_tools/lib/Inode.cpp
@@ -108,7 +108,7 @@ Inode::SetTo(bfs_inode *inode)
status_t
-Inode::InitCheck()
+Inode::InitCheck() const
{
if (!fInode)
return B_ERROR;
@@ -304,6 +304,10 @@ Inode::SetName(const char *name)
const char *
Inode::Name() const
{
+ if (InitCheck() != B_OK) {
+ puts("Not getting name because node is invalid");
+ return NULL;
+ }
small_data *data = fInode->small_data_start;
while (!data->IsLast(fInode)) {
if (data->type == FILE_NAME_TYPE
@@ -929,7 +933,7 @@ File::~File()
status_t
-File::InitCheck()
+File::InitCheck() const
{
status_t status = DataStream::InitCheck();
if (status == B_OK)
@@ -1006,7 +1010,7 @@ Attribute::~Attribute()
status_t
-Attribute::InitCheck()
+Attribute::InitCheck() const
{
status_t status = DataStream::InitCheck();
if (status == B_OK)
@@ -1053,7 +1057,7 @@ Directory::~Directory()
status_t
-Directory::InitCheck()
+Directory::InitCheck() const
{
status_t status = DataStream::InitCheck();
if (status == B_OK)
@@ -1322,7 +1326,7 @@ Symlink::~Symlink()
status_t
-Symlink::InitCheck()
+Symlink::InitCheck() const
{
status_t status = Inode::InitCheck();
if (status == B_OK)
diff --git a/src/bin/bfs_tools/lib/Inode.h b/src/bin/bfs_tools/lib/Inode.h
index f06e758..67ff22f 100644
--- a/src/bin/bfs_tools/lib/Inode.h
+++ b/src/bin/bfs_tools/lib/Inode.h
@@ -20,7 +20,7 @@ class Inode {
virtual ~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 IsDirectory() const { return
S_ISDIR(fInode->mode); }
@@ -131,7 +131,7 @@ class File : public DataStream {
File(const Inode &inode);
~File();
- virtual status_t InitCheck();
+ virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath
= true,
Inode::Source
*source = NULL);
};
@@ -143,7 +143,7 @@ class Attribute : public File {
Attribute(const Inode &inode);
~Attribute();
- virtual status_t InitCheck();
+ virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath
= true,
Inode::Source
*source = NULL);
@@ -157,7 +157,7 @@ class Directory : public DataStream {
Directory(const Inode &inode);
~Directory();
- virtual status_t InitCheck();
+ virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath
= true,
Inode::Source
*source = NULL);
@@ -186,7 +186,7 @@ class Symlink : public Inode {
Symlink(const Inode &inode);
~Symlink();
- virtual status_t InitCheck();
+ virtual status_t InitCheck() const;
virtual status_t CopyTo(const char *path, bool fullPath
= true,
Inode::Source
*source = NULL);
diff --git a/src/bin/bfs_tools/recover.cpp b/src/bin/bfs_tools/recover.cpp
index 50ed650..1988a3d 100644
--- a/src/bin/bfs_tools/recover.cpp
+++ b/src/bin/bfs_tools/recover.cpp
@@ -440,7 +440,15 @@ checkStructure(Disk &disk)
if (node->IsDirectory() && !node->IsIndex()) {
// 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