hrev43807 adds 2 changesets to branch 'master' old head: 360a6446506d9316265df77c0f89804e3de11412 new head: e9091262c5c012254c4f2cb1ff8a604cfdaddf5e ---------------------------------------------------------------------------- 29ecf7b: command_ioctl() leaked the root directory's file descriptor. e909126: Added "checkfs" as additional command for the bfs_shell. [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 5 files changed, 184 insertions(+), 1 deletions(-) src/tools/bfs_shell/Jamfile | 11 ++- src/tools/bfs_shell/additional_commands.cpp | 24 +++++ src/tools/bfs_shell/command_checkfs.cpp | 126 +++++++++++++++++++++++ src/tools/bfs_shell/command_checkfs.h | 21 ++++ src/tools/fs_shell/fssh.cpp | 3 + ############################################################################ Commit: 29ecf7b04e49987dfdd0dbb78a280ba6b54a3a6a URL: http://cgit.haiku-os.org/haiku/commit/?id=29ecf7b Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Wed Feb 29 22:27:46 2012 UTC command_ioctl() leaked the root directory's file descriptor. ---------------------------------------------------------------------------- diff --git a/src/tools/fs_shell/fssh.cpp b/src/tools/fs_shell/fssh.cpp index 58b51d3..bcff629 100644 --- a/src/tools/fs_shell/fssh.cpp +++ b/src/tools/fs_shell/fssh.cpp @@ -1195,6 +1195,9 @@ command_ioctl(int argc, const char* const* argv) return rootDir; fssh_status_t status = _kern_ioctl(rootDir, atoi(argv[1]), NULL, 0); + + _kern_close(rootDir); + if (status != FSSH_B_OK) { fprintf(stderr, "Error: ioctl failed: %s\n", fssh_strerror(status)); return status; ############################################################################ Revision: hrev43807 Commit: e9091262c5c012254c4f2cb1ff8a604cfdaddf5e URL: http://cgit.haiku-os.org/haiku/commit/?id=e909126 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Wed Feb 29 22:28:54 2012 UTC Added "checkfs" as additional command for the bfs_shell. ---------------------------------------------------------------------------- diff --git a/src/tools/bfs_shell/Jamfile b/src/tools/bfs_shell/Jamfile index 4de4f26..1b04be7 100644 --- a/src/tools/bfs_shell/Jamfile +++ b/src/tools/bfs_shell/Jamfile @@ -33,9 +33,16 @@ if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) { fsShellCommandLibs = $(HOST_NETWORK_LIBS) ; } -UsePrivateHeaders storage ; +UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ; +if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) { + UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ; + UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ; +} + +UsePrivateHeaders shared storage ; UsePrivateHeaders fs_shell ; +UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ; local bfsSource = bfs_disk_system.cpp @@ -57,6 +64,8 @@ BuildPlatformMergeObject <build>bfs.o : $(bfsSource) ; BuildPlatformMain <build>bfs_shell : + additional_commands.cpp + command_checkfs.cpp : <build>bfs.o <build>fs_shell.a $(libHaikuCompat) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++) diff --git a/src/tools/bfs_shell/additional_commands.cpp b/src/tools/bfs_shell/additional_commands.cpp new file mode 100644 index 0000000..df7d7ad --- /dev/null +++ b/src/tools/bfs_shell/additional_commands.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "fssh.h" + +#include "command_checkfs.h" + + +namespace FSShell { + + +void +register_additional_commands() +{ + puts("************************ HERE I AM!!!!!!!!!!!!!!!!!"); + CommandManager::Default()->AddCommand(command_checkfs, "checkfs", + "check file system"); +} + + +} // namespace FSShell diff --git a/src/tools/bfs_shell/command_checkfs.cpp b/src/tools/bfs_shell/command_checkfs.cpp new file mode 100644 index 0000000..709d4bf --- /dev/null +++ b/src/tools/bfs_shell/command_checkfs.cpp @@ -0,0 +1,126 @@ +/* + * Copyright 2008-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "fssh_stdio.h" +#include "syscalls.h" + +#include "bfs.h" +#include "bfs_control.h" + + +namespace FSShell { + + +fssh_status_t +command_checkfs(int argc, const char* const* argv) +{ + if (argc == 2 && !strcmp(argv[1], "--help")) { + fssh_dprintf("Usage: %s [-c]\n" + " -c Check only; don't perform any changes\n", argv[0]); + return B_OK; + } + + bool checkOnly = false; + if (argc == 2 && !strcmp(argv[1], "-c")) + checkOnly = true; + + int rootDir = _kern_open_dir(-1, "/myfs"); + if (rootDir < 0) + return rootDir; + + struct check_control result; + memset(&result, 0, sizeof(result)); + result.magic = BFS_IOCTL_CHECK_MAGIC; + result.flags = 0; + if (!checkOnly) { + result.flags |= BFS_FIX_BITMAP_ERRORS | BFS_REMOVE_WRONG_TYPES + | BFS_REMOVE_INVALID | BFS_FIX_NAME_MISMATCHES | BFS_FIX_BPLUSTREES; + } + + // start checking + fssh_status_t status = _kern_ioctl(rootDir, BFS_IOCTL_START_CHECKING, + &result, sizeof(result)); + if (status != B_OK) + return status; + + uint64 attributeDirectories = 0, attributes = 0; + uint64 files = 0, directories = 0, indices = 0; + uint64 counter = 0; + + // check all files and report errors + while (_kern_ioctl(rootDir, BFS_IOCTL_CHECK_NEXT_NODE, &result, + sizeof(result)) == B_OK) { + if (++counter % 50 == 0) + fssh_dprintf("%9Ld nodes processed\x1b[1A\n", counter); + + if (result.errors) { + fssh_dprintf("%s (inode = %lld)", result.name, result.inode); + if ((result.errors & BFS_MISSING_BLOCKS) != 0) + fssh_dprintf(", some blocks weren't allocated"); + if ((result.errors & BFS_BLOCKS_ALREADY_SET) != 0) + fssh_dprintf(", has blocks already set"); + if ((result.errors & BFS_INVALID_BLOCK_RUN) != 0) + fssh_dprintf(", has invalid block run(s)"); + if ((result.errors & BFS_COULD_NOT_OPEN) != 0) + fssh_dprintf(", could not be opened"); + if ((result.errors & BFS_WRONG_TYPE) != 0) + fssh_dprintf(", has wrong type"); + if ((result.errors & BFS_NAMES_DONT_MATCH) != 0) + fssh_dprintf(", names don't match"); + if ((result.errors & BFS_INVALID_BPLUSTREE) != 0) + fssh_dprintf(", invalid b+tree"); + fssh_dprintf("\n"); + } + if ((result.mode & (S_INDEX_DIR | 0777)) == S_INDEX_DIR) + indices++; + else if (result.mode & S_ATTR_DIR) + attributeDirectories++; + else if (result.mode & S_ATTR) + attributes++; + else if (S_ISDIR(result.mode)) + directories++; + else + files++; + } + + // stop checking + if (_kern_ioctl(rootDir, BFS_IOCTL_STOP_CHECKING, &result, sizeof(result)) + != B_OK) { + _kern_close(rootDir); + return errno; + } + + _kern_close(rootDir); + + fssh_dprintf("\t%" B_PRIu64 " nodes checked,\n\t%" B_PRIu64 " blocks not " + "allocated,\n\t%" B_PRIu64 " blocks already set,\n\t%" B_PRIu64 + " blocks could be freed\n\n", counter, result.stats.missing, + result.stats.already_set, result.stats.freed); + fssh_dprintf("\tfiles\t\t%" B_PRIu64 "\n\tdirectories\t%" B_PRIu64 "\n" + "\tattributes\t%" B_PRIu64 "\n\tattr. dirs\t%" B_PRIu64 "\n" + "\tindices\t\t%" B_PRIu64 "\n", files, directories, attributes, + attributeDirectories, indices); + + fssh_dprintf("\n\tdirect block runs\t\t%" B_PRIu64 " (%lld)\n", + result.stats.direct_block_runs, + result.stats.blocks_in_direct * result.stats.block_size); + fssh_dprintf("\tindirect block runs\t\t%" B_PRIu64 " (in %" B_PRIu64 + " array blocks, %lld)\n", result.stats.indirect_block_runs, + result.stats.indirect_array_blocks, + result.stats.blocks_in_indirect * result.stats.block_size); + fssh_dprintf("\tdouble indirect block runs\t%" B_PRIu64 " (in %" B_PRIu64 + " array blocks, %lld)\n", result.stats.double_indirect_block_runs, + result.stats.double_indirect_array_blocks, + result.stats.blocks_in_double_indirect * result.stats.block_size); + + if (result.status == B_ENTRY_NOT_FOUND) + result.status = B_OK; + + return result.status; +} + + +} // namespace FSShell diff --git a/src/tools/bfs_shell/command_checkfs.h b/src/tools/bfs_shell/command_checkfs.h new file mode 100644 index 0000000..881e5f3 --- /dev/null +++ b/src/tools/bfs_shell/command_checkfs.h @@ -0,0 +1,21 @@ +/* + * Copyright 2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef CHECKFS_H +#define CHECKFS_H + + +#include "fssh_types.h" + + +namespace FSShell { + + +fssh_status_t command_checkfs(int argc, const char* const* argv); + + +} // namespace FSShell + + +#endif // CHECKFS_H