1
2#include "compat.h"
3
4#include <stdio.h>
5#include <StorageDefs.h>
6
7#include "fsproto.h"
8#include "kprotos.h"
9#include "bfs_control.h"
10
11#include "additional_commands.h"
12
13
14static int
15do_chkbfs(int argc, char **argv)
16{
17	struct check_control result;
18	fs_off_t files = 0, directories = 0, indices = 0, attributeDirectories = 0, attributes = 0;
19	int counter = 0;
20
21	int fd = sys_open(1, -1, "/myfs/.", O_RDONLY, S_IFREG, 0);
22	if (fd < 0) {
23	    printf("chkbfs: error opening '.'\n");
24	    return fd;
25	}
26
27	memset(&result, 0, sizeof(result));
28	result.magic = BFS_IOCTL_CHECK_MAGIC;
29	result.flags = argc > 1 ? BFS_FIX_BITMAP_ERRORS : 0;
30	if (argc > 2) {
31		printf("will fix any severe errors!\n");
32		result.flags |= BFS_REMOVE_WRONG_TYPES | BFS_REMOVE_INVALID;
33	}
34
35	// start checking
36	if ((sys_ioctl(1, fd, BFS_IOCTL_START_CHECKING, &result, sizeof(result))) < 0) {
37	    printf("chkbfs: error starting!\n");
38	}
39
40	// check all files and report errors
41	while (sys_ioctl(1, fd, BFS_IOCTL_CHECK_NEXT_NODE, &result, sizeof(result)) == FS_OK) {
42		if (++counter % 50 == 0)
43			printf("  %7d nodes processed\x1b[1A\n", counter);
44
45		if (result.errors) {
46			printf("%s (inode = %Ld)", result.name, result.inode);
47			if (result.errors & BFS_MISSING_BLOCKS)
48				printf(", some blocks weren't allocated");
49			if (result.errors & BFS_BLOCKS_ALREADY_SET)
50				printf(", has blocks already set");
51			if (result.errors & BFS_INVALID_BLOCK_RUN)
52				printf(", has invalid block run(s)");
53			if (result.errors & BFS_COULD_NOT_OPEN)
54				printf(", could not be opened");
55			if (result.errors & BFS_WRONG_TYPE)
56				printf(", has wrong type");
57			if (result.errors & BFS_NAMES_DONT_MATCH)
58				printf(", names don't match");
59			putchar('\n');
60		}
61		if ((result.mode & (MY_S_INDEX_DIR | 0777)) == MY_S_INDEX_DIR)
62			indices++;
63		else if (result.mode & MY_S_ATTR_DIR)
64			attributeDirectories++;
65		else if (result.mode & MY_S_ATTR)
66			attributes++;
67		else if (result.mode & MY_S_IFDIR)
68			directories++;
69		else
70			files++;
71	}
72	if (result.status != FS_ENTRY_NOT_FOUND)
73		printf("chkbfs: error occured during scan: %s\n", strerror(result.status));
74
75	// stop checking
76	if ((sys_ioctl(1, fd, BFS_IOCTL_STOP_CHECKING, &result, sizeof(result))) < 0) {
77	    printf("chkbfs: error stopping!\n");
78	}
79
80	printf("checked %d nodes, %Ld blocks not allocated, %Ld blocks already set, %Ld blocks could be freed\n",
81		counter, result.stats.missing, result.stats.already_set, result.stats.freed);
82	printf("\tfiles\t\t%Ld\n\tdirectories\t%Ld\n\tattributes\t%Ld\n\tattr. dirs\t%Ld\n\tindices\t\t%Ld\n",
83		files, directories, attributes, attributeDirectories, indices);
84	if (result.flags & BFS_FIX_BITMAP_ERRORS)
85		printf("errors have been fixed\n");
86
87	sys_close(1, fd);
88
89	return 0;
90}
91
92cmd_entry additional_commands[] = {
93	{ "chkbfs",	 do_chkbfs, "does a chkbfs on the volume" },
94    { NULL, NULL }
95};
96