bfswhich/bfsinfo/recover can now run on Linux

* You can build them using the <build> prefix; their Jamfiles are below
  src/tools/ as with other host builds.

Change-Id: I9986b85ba0f758d8420f625873b5e37c3274e678
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10126
Reviewed-by: waddlesplash <[email protected]>
Reviewed-by: Axel Dörfler <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Axel Dörfler
2025-12-25 17:26:09 +00:00
parent 27512d20c7
commit b15cb7f6d0
12 changed files with 169 additions and 19 deletions
@@ -0,0 +1 @@
#include <../private/shared/StringForSize.h>
+11 -11
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2009 pinc Software. All Rights Reserved. * Copyright (c) 2002-2025 pinc Software. All Rights Reserved.
* Released under the terms of the MIT license. * Released under the terms of the MIT license.
*/ */
@@ -118,7 +118,7 @@ scanNode(Disk& disk, Inode* inode, const char* name,
const block_run& checkForRun) const block_run& checkForRun)
{ {
if (checkNode(disk, inode, checkForRun)) { if (checkNode(disk, inode, checkForRun)) {
printf("Inode at (%ld, %u, %u) \"%s\" intersects\n", printf("Inode at (%" B_PRIu32 ", %u, %u) \"%s\" intersects\n",
inode->BlockRun().allocation_group, inode->BlockRun().start, inode->BlockRun().allocation_group, inode->BlockRun().start,
inode->BlockRun().length, name); inode->BlockRun().length, name);
} }
@@ -154,7 +154,7 @@ scanNodes(Disk& disk, Directory* directory, const char* directoryName,
continue; continue;
if (++gCount % 50 == 0) if (++gCount % 50 == 0)
printf(" %7Ld%s1A\n", gCount, gEscape); printf(" %7" B_PRIdOFF "%s1A\n", gCount, gEscape);
Inode *inode = Inode::Factory(&disk, run); Inode *inode = Inode::Factory(&disk, run);
if (inode != NULL) { if (inode != NULL) {
@@ -167,10 +167,10 @@ scanNodes(Disk& disk, Directory* directory, const char* directoryName,
delete inode; delete inode;
} else { } else {
printf(" Directory \"%s\" (%ld, %d) points to corrupt inode \"%s\" " printf(" Directory \"%s\" (%" B_PRIu32 ", %d) points to corrupt inode \"%s\" "
"(%ld, %d)\n", directory->Name(), "(%" B_PRIu32 ", %d)\n", directory->Name(),
directory->BlockRun().allocation_group,directory directory->BlockRun().allocation_group,
->BlockRun().start, directory->BlockRun().start,
name, run.allocation_group, run.start); name, run.allocation_group, run.start);
} }
} }
@@ -203,7 +203,7 @@ scanNodes(Disk& disk, const block_run& checkForRun, bool scanAll)
delete indices; delete indices;
} }
printf(" %7Ld nodes found.\n", gCount); printf(" %7" B_PRIdOFF " nodes found.\n", gCount);
} }
@@ -217,7 +217,7 @@ testBitmap(Disk& disk, const block_run& run)
return; return;
} }
printf("Block bitmap sees block %lld as %s.\n", disk.ToBlock(run), printf("Block bitmap sees block %" B_PRIdOFF " as %s.\n", disk.ToBlock(run),
bitmap.UsedAt(disk.ToBlock(run)) ? "used" : "free"); bitmap.UsedAt(disk.ToBlock(run)) ? "used" : "free");
} }
@@ -304,13 +304,13 @@ main(int argc, char** argv)
testBitmap(disk, run); testBitmap(disk, run);
if (checkForBlockRunIntersection(disk.Log(), run)) { if (checkForBlockRunIntersection(disk.Log(), run)) {
printf("Log area (%lu.%u.%u) intersects\n", printf("Log area (%" B_PRIu32 ".%u.%u) intersects\n",
disk.Log().allocation_group, disk.Log().start, disk.Log().allocation_group, disk.Log().start,
disk.Log().length); disk.Log().length);
} else if (block < 1) { } else if (block < 1) {
printf("Superblock intersects\n"); printf("Superblock intersects\n");
} else if (block < 1 + disk.BitmapSize()) { } else if (block < 1 + disk.BitmapSize()) {
printf("Block bitmap intersects (start %d, end %lu)\n", 1, printf("Block bitmap intersects (start %d, end %" B_PRIu32 ")\n", 1,
disk.BitmapSize()); disk.BitmapSize());
} else } else
scanNodes(disk, run, scanAll); scanNodes(disk, run, scanAll);
+17 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2008 pinc Software. All Rights Reserved. * Copyright (c) 2001-2025 pinc Software. All Rights Reserved.
* Released under the terms of the MIT license. * Released under the terms of the MIT license.
*/ */
@@ -8,7 +8,6 @@
#include "Disk.h" #include "Disk.h"
#include "dump.h" #include "dump.h"
#include <Drivers.h>
#include <File.h> #include <File.h>
#include <Entry.h> #include <Entry.h>
#include <List.h> #include <List.h>
@@ -20,6 +19,12 @@
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#ifdef __HAIKU__
# include <Drivers.h>
#else
# include <sys/ioctl.h>
# include <linux/fs.h>
#endif
#define MIN_BLOCK_SIZE_INODES 50 #define MIN_BLOCK_SIZE_INODES 50
#define MAX_BLOCK_SIZE_INODES 500 #define MAX_BLOCK_SIZE_INODES 500
@@ -106,6 +111,7 @@ Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop)
fPath.SetTo(deviceName); fPath.SetTo(deviceName);
if (entry.IsDirectory()) { if (entry.IsDirectory()) {
#ifdef __HAIKU__
dev_t on = dev_for_path(deviceName); dev_t on = dev_for_path(deviceName);
fs_info info; fs_info info;
if (fs_stat_dev(on, &info) != B_OK) if (fs_stat_dev(on, &info) != B_OK)
@@ -113,6 +119,7 @@ Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop)
fPath.SetTo(info.device_name); fPath.SetTo(info.device_name);
deviceName = fPath.Path(); deviceName = fPath.Path();
#endif
} }
if (deviceName == NULL) { if (deviceName == NULL) {
@@ -136,6 +143,7 @@ Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop)
return; return;
} }
#ifdef __HAIKU__
partition_info partitionInfo; partition_info partitionInfo;
device_geometry geometry; device_geometry geometry;
if (ioctl(device, B_GET_PARTITION_INFO, &partitionInfo, if (ioctl(device, B_GET_PARTITION_INFO, &partitionInfo,
@@ -151,6 +159,13 @@ Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop)
fprintf(stderr,"Disk: Could not get partition info.\n Use file size as partition size\n"); fprintf(stderr,"Disk: Could not get partition info.\n Use file size as partition size\n");
fFile.GetSize(&fSize); fFile.GetSize(&fSize);
} }
#else
if (ioctl(device, BLKGETSIZE64, &fSize) == -1) {
struct stat st;
if (fstat(device, &st) != -1)
fSize = st.st_size;
}
#endif
close(device); close(device);
if (fSize == 0LL) { if (fSize == 0LL) {
+4
View File
@@ -174,6 +174,7 @@ Inode::CopyBuffer()
/*static*/ bool /*static*/ bool
Inode::_LowMemory() Inode::_LowMemory()
{ {
#ifdef __HAIKU__
static bigtime_t lastChecked; static bigtime_t lastChecked;
static int32 percentUsed; static int32 percentUsed;
@@ -184,6 +185,9 @@ Inode::_LowMemory()
} }
return percentUsed > 75; return percentUsed > 75;
#else
return false;
#endif
} }
+1 -5
View File
@@ -3,7 +3,7 @@
* Initial version by Axel Dörfler, [email protected] * Initial version by Axel Dörfler, [email protected]
* Parts of this code is based on work previously done by Marcus Overhagen * Parts of this code is based on work previously done by Marcus Overhagen
* *
* Copyright 2001-2008 pinc Software. All Rights Reserved. * Copyright 2001-2025 pinc Software. All Rights Reserved.
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
#ifndef BFS_H #ifndef BFS_H
@@ -12,10 +12,6 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#if !defined(BEOS_VERSION_DANO) && !defined(__HAIKU__)
# define B_BAD_DATA B_ERROR
#endif
// File types as used in BFS and stored in its inodes // File types as used in BFS and stored in its inodes
// (coincidentally the same as in Haiku's sys/stat.h) // (coincidentally the same as in Haiku's sys/stat.h)
+2 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2010, pinc Software. All Rights Reserved. * Copyright 2001-2025, pinc Software. All Rights Reserved.
* Released under the terms of the MIT license. * Released under the terms of the MIT license.
*/ */
@@ -14,6 +14,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h>
#define Print printf #define Print printf
+2
View File
@@ -804,6 +804,7 @@ main(int argc, char **argv)
return -1; return -1;
} }
#ifdef __HAIKU__
if (argv[1] != NULL) { if (argv[1] != NULL) {
dev_t device = dev_for_path(argv[1]); dev_t device = dev_for_path(argv[1]);
fs_info info; fs_info info;
@@ -824,6 +825,7 @@ main(int argc, char **argv)
} }
} }
} }
#endif
bool recreatedSuperBlock = false; bool recreatedSuperBlock = false;
+15
View File
@@ -219,6 +219,21 @@ BStatable::SetModificationTime(time_t mtime)
return set_stat(statData, B_STAT_MODIFICATION_TIME); return set_stat(statData, B_STAT_MODIFICATION_TIME);
} }
status_t
BStatable::GetCreationTime(time_t *ctime) const
{
return GetModificationTime(ctime);
}
status_t
BStatable::SetCreationTime(time_t ctime)
{
return B_ERROR;
}
/*! \brief Returns the time the node was accessed. /*! \brief Returns the time the node was accessed.
Not used. Not used.
\see GetModificationTime() \see GetModificationTime()
+1
View File
@@ -12,6 +12,7 @@ BuildPlatformStaticLibraryPIC libshared_build.a :
Keymap.cpp Keymap.cpp
NaturalCompare.cpp NaturalCompare.cpp
RegExp.cpp RegExp.cpp
StringForSize.cpp
: :
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2024 Haiku Inc. All rights reserved.
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "StringForSize.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
namespace BPrivate {
const char*
string_for_size(double size, char* string, size_t stringSize)
{
const char* kFormats[] = {
"%.0g B", "%.2g KiB", "%.2g MiB", "%.2g GiB", "%.2g TiB"
};
size_t index = 0;
while (index < B_COUNT_OF(kFormats) - 1 && size >= 1024.0) {
size /= 1024.0;
index++;
}
snprintf(string, stringSize, kFormats[index], size);
return string;
}
int64
parse_size(const char* sizeString)
{
int64 parsedSize = -1;
char* end;
parsedSize = strtoll(sizeString, &end, 0);
if (end != sizeString && parsedSize > 0) {
int64 rawSize = parsedSize;
switch (tolower(*end)) {
case 't':
parsedSize *= 1024;
case 'g':
parsedSize *= 1024;
case 'm':
parsedSize *= 1024;
case 'k':
parsedSize *= 1024;
end++;
break;
case '\0':
break;
default:
parsedSize = -1;
break;
}
// Check for overflow
if (parsedSize > 0 && rawSize > parsedSize)
parsedSize = -1;
}
return parsedSize;
}
} // namespace BPrivate
+1
View File
@@ -91,6 +91,7 @@ SEARCH on [ FGristFiles
SubInclude HAIKU_TOP src tools addattr ; SubInclude HAIKU_TOP src tools addattr ;
SubInclude HAIKU_TOP src tools anyboot ; SubInclude HAIKU_TOP src tools anyboot ;
SubInclude HAIKU_TOP src tools bfs_shell ; SubInclude HAIKU_TOP src tools bfs_shell ;
SubInclude HAIKU_TOP src tools bfs_tools ;
SubInclude HAIKU_TOP src tools fat_shell ; SubInclude HAIKU_TOP src tools fat_shell ;
SubInclude HAIKU_TOP src tools cppunit ; SubInclude HAIKU_TOP src tools cppunit ;
SubInclude HAIKU_TOP src tools create_repository_config ; SubInclude HAIKU_TOP src tools create_repository_config ;
+42
View File
@@ -0,0 +1,42 @@
SubDir HAIKU_TOP src tools bfs_tools ;
UsePrivateBuildHeaders libroot shared kernel storage support ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin bfs_tools ] ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin bfs_tools lib ] ;
USES_BE_API on <build>bfsinfo = true ;
USES_BE_API on <build>bfswhich = true ;
USES_BE_API on <build>recover = true ;
BFS_TOOLS_SOURCES =
bfs.cpp
Bitmap.cpp
BPlusTree.cpp
Disk.cpp
dump.cpp
Hashtable.cpp
Inode.cpp
;
BuildPlatformMain <build>bfswhich :
bfswhich.cpp
$(BFS_TOOLS_SOURCES)
:
$(HOST_LIBBE) $(HOST_LIBSUPC++)
;
BuildPlatformMain <build>bfsinfo :
bfsinfo.cpp
$(BFS_TOOLS_SOURCES)
:
$(HOST_LIBBE) $(HOST_LIBSUPC++) libshared_build.a
;
BuildPlatformMain <build>recover :
recover.cpp
$(BFS_TOOLS_SOURCES)
:
$(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) libshared_build.a
;