Beginnings of a buildable bfs userland shell (Jamfile is missing).
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2963 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,100 @@
|
|||||||
|
#ifndef DEBUG_H
|
||||||
|
#define DEBUG_H
|
||||||
|
/* Debug - debug stuff
|
||||||
|
**
|
||||||
|
** Initial version by Axel Dörfler, [email protected]
|
||||||
|
** This file may be used under the terms of the OpenBeOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
# include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USER
|
||||||
|
# include <stdio.h>
|
||||||
|
# define __out printf
|
||||||
|
#else
|
||||||
|
# define __out dprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Which debugger should be used when?
|
||||||
|
// The DEBUGGER() macro actually has no effect if DEBUG is not defined,
|
||||||
|
// use the DIE() macro if you really want to die.
|
||||||
|
#ifdef DEBUG
|
||||||
|
# ifdef USER
|
||||||
|
# define DEBUGGER(x) debugger x
|
||||||
|
# else
|
||||||
|
# define DEBUGGER(x) kernel_debugger x
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define DEBUGGER(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USER
|
||||||
|
# define DIE(x) debugger x
|
||||||
|
#else
|
||||||
|
# define DIE(x) kernel_debugger x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Short overview over the debug output macros:
|
||||||
|
// PRINT()
|
||||||
|
// is for general messages that very unlikely should appear in a release build
|
||||||
|
// FATAL()
|
||||||
|
// this is for fatal messages, when something has really gone wrong
|
||||||
|
// INFORM()
|
||||||
|
// general information, as disk size, etc.
|
||||||
|
// REPORT_ERROR(status_t)
|
||||||
|
// prints out error information
|
||||||
|
// RETURN_ERROR(status_t)
|
||||||
|
// calls REPORT_ERROR() and return the value
|
||||||
|
// D()
|
||||||
|
// the statements in D() are only included if DEBUG is defined
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
#define kprintf printf
|
||||||
|
#define dprintf printf
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define PRINT(x) { __out("bfs: "); __out x; }
|
||||||
|
#define REPORT_ERROR(status) __out("bfs: %s:%s:%ld: %s\n", __FILE__, __FUNCTION__, __LINE__, strerror(status));
|
||||||
|
#define RETURN_ERROR(err) { status_t _status = err; if (_status < B_OK) REPORT_ERROR(_status); return _status;}
|
||||||
|
#define FATAL(x) { __out("bfs: "); __out x; }
|
||||||
|
#define INFORM(x) { __out("bfs: "); __out x; }
|
||||||
|
#define FUNCTION() __out("bfs: %s()\n",__FUNCTION__);
|
||||||
|
#define FUNCTION_START(x) { __out("bfs: %s() ",__FUNCTION__); __out x; }
|
||||||
|
// #define FUNCTION() ;
|
||||||
|
// #define FUNCTION_START(x) ;
|
||||||
|
#define D(x) {x;};
|
||||||
|
#define ASSERT(x) { if (!(x)) DEBUGGER(("bfs: assert failed: " #x "\n")); }
|
||||||
|
#else
|
||||||
|
#define PRINT(x) ;
|
||||||
|
#define REPORT_ERROR(status) ;
|
||||||
|
#define RETURN_ERROR(status) return status;
|
||||||
|
#define FATAL(x) { __out("bfs: "); __out x; }
|
||||||
|
#define INFORM(x) { __out("bfs: "); __out x; }
|
||||||
|
#define FUNCTION() ;
|
||||||
|
#define FUNCTION_START(x) ;
|
||||||
|
#define D(x) ;
|
||||||
|
#define ASSERT(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
struct block_run;
|
||||||
|
struct bplustree_header;
|
||||||
|
struct bplustree_node;
|
||||||
|
struct data_stream;
|
||||||
|
struct bfs_inode;
|
||||||
|
struct disk_super_block;
|
||||||
|
class Volume;
|
||||||
|
|
||||||
|
// some structure dump functions
|
||||||
|
extern void dump_block_run(const char *prefix, block_run &run);
|
||||||
|
extern void dump_super_block(disk_super_block *superBlock);
|
||||||
|
extern void dump_data_stream(data_stream *stream);
|
||||||
|
extern void dump_inode(bfs_inode *inode);
|
||||||
|
extern void dump_bplustree_header(bplustree_header *header);
|
||||||
|
extern void dump_bplustree_node(bplustree_node *node,bplustree_header *header = NULL,Volume *volume = NULL);
|
||||||
|
extern void dump_block(const char *buffer, int size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DEBUG_H */
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/* This file is included in fs_shell:fsh.c
|
||||||
|
* Insert your implementation of additional commands in here
|
||||||
|
*
|
||||||
|
* Format:
|
||||||
|
*
|
||||||
|
* static void
|
||||||
|
* function(int argc, char **argv)
|
||||||
|
* {
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "bfs_control.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_chkbfs(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct check_control result;
|
||||||
|
off_t files = 0, directories = 0, indices = 0, attributeDirectories = 0, attributes = 0;
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
int fd = sys_open(1, -1, "/myfs/.", O_RDONLY, S_IFREG, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
printf("chkbfs: error opening '.'\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&result, 0, sizeof(result));
|
||||||
|
result.flags = argc > 1 ? BFS_FIX_BITMAP_ERRORS : 0;
|
||||||
|
if (argc > 2) {
|
||||||
|
printf("will fix any severe errors!\n");
|
||||||
|
result.flags |= BFS_REMOVE_WRONG_TYPES | BFS_REMOVE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start checking
|
||||||
|
if ((sys_ioctl(1, fd, BFS_IOCTL_START_CHECKING, &result, sizeof(result))) < 0) {
|
||||||
|
printf("chkbfs: error starting!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check all files and report errors
|
||||||
|
while (sys_ioctl(1, fd, BFS_IOCTL_CHECK_NEXT_NODE, &result, sizeof(result)) == B_OK) {
|
||||||
|
if (++counter % 50 == 0)
|
||||||
|
printf(" %7ld nodes processed\x1b[1A\n", counter);
|
||||||
|
|
||||||
|
if (result.errors) {
|
||||||
|
printf("%s (inode = %Ld)", result.name, result.inode);
|
||||||
|
if (result.errors & BFS_MISSING_BLOCKS)
|
||||||
|
printf(", some blocks weren't allocated");
|
||||||
|
if (result.errors & BFS_BLOCKS_ALREADY_SET)
|
||||||
|
printf(", has blocks already set");
|
||||||
|
if (result.errors & BFS_INVALID_BLOCK_RUN)
|
||||||
|
printf(", has invalid block run(s)");
|
||||||
|
if (result.errors & BFS_COULD_NOT_OPEN)
|
||||||
|
printf(", could not be opened");
|
||||||
|
if (result.errors & BFS_WRONG_TYPE)
|
||||||
|
printf(", has wrong type");
|
||||||
|
if (result.errors & BFS_NAMES_DONT_MATCH)
|
||||||
|
printf(", names don't match");
|
||||||
|
putchar('\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 (result.mode & S_IFDIR)
|
||||||
|
directories++;
|
||||||
|
else
|
||||||
|
files++;
|
||||||
|
}
|
||||||
|
if (result.status != B_ENTRY_NOT_FOUND)
|
||||||
|
printf("chkbfs: error occured during scan: %s\n", strerror(result.status));
|
||||||
|
|
||||||
|
// stop checking
|
||||||
|
if ((sys_ioctl(1, fd, BFS_IOCTL_STOP_CHECKING, &result, sizeof(result))) < 0) {
|
||||||
|
printf("chkbfs: error stopping!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("checked %ld nodes, %Ld blocks not allocated, %Ld blocks already set, %Ld blocks could be freed\n",
|
||||||
|
counter, result.stats.missing, result.stats.already_set, result.stats.freed);
|
||||||
|
printf("\tfiles\t\t%Ld\n\tdirectories\t%Ld\n\tattributes\t%Ld\n\tattr. dirs\t%Ld\n\tindices\t\t%Ld\n",
|
||||||
|
files, directories, attributes, attributeDirectories, indices);
|
||||||
|
if (result.flags & BFS_FIX_BITMAP_ERRORS)
|
||||||
|
printf("errors have been fixed\n");
|
||||||
|
|
||||||
|
sys_close(1, fd);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/* This file is included in fs_shell:fsh.c
|
||||||
|
* Insert your definition of additional commands here
|
||||||
|
*
|
||||||
|
* Format:
|
||||||
|
* { commandName, functionName, commandDescription },
|
||||||
|
*
|
||||||
|
* And don't forget the comma after the line :-)
|
||||||
|
*/
|
||||||
|
|
||||||
|
{ "chkbfs", do_chkbfs, "does a chkbfs on the volume" },
|
||||||
Reference in New Issue
Block a user