9 #include "fsck_helper.h"
11 /* usefull macro and function */
12 static void printError (int errcode
, char *cmd_name
)
14 fprintf(stderr
, "%s: error #%d: %s\n", cmd_name
, errcode
,\
20 printError(-(err), argv[0]);\
24 #define FABORT(err, fname) \
26 printError(-(err), fname);\
30 /* type definitions */
31 typedef enum {corrupt
, weird
, nice
} testresult_t
;
32 typedef testresult_t (*testfunction_t
)(void);
35 testfunction_t function
;
38 typedef struct test_s test_t
;
42 testresult_t
test_sbmagic (void)
47 fetch_superblock(&sb
);
49 if (sb
->magic
== MAGIC_NUMBER
) {
53 printf("This is not a valid SOFS09 filesystem.\n");
59 testresult_t
test_sbzones (void)
66 fetch_superblock(&sb
);
68 /* current position inside the disc, in blocks */
72 /* start position, in blocks, of this zone */
74 /* size, in blocks, of this zone */
79 struct zone_s zone
[] = {
80 {sb
->fctable_start
, sb
->fctable_size
, "FCT"},
81 {sb
->ciutable_start
, sb
->ciutable_size
, "CIUT"},
82 {sb
->itable_start
, sb
->itable_size
, "IT"},
83 {sb
->dzone_start
, sb
->dzone_size
*BLOCKS_PER_CLUSTER
, "DATA"},
85 struct zone_s tempzone
;
89 /* sort zones by start position (bouble sort) */
90 nzones
= sizeof(zone
)/sizeof(struct zone_s
);
91 for (r
= 0; r
< nzones
-1; ++r
) {
92 for (s
= r
; s
< nzones
-1-r
; ++s
) {
93 if (zone
[r
].start
> zone
[r
+1].start
) {
103 /* advance superblock */
106 for (r
= 0; (r
< nzones
) && (ret
!= corrupt
); ++r
) {
107 if (cpos
> zone
[r
].start
) {
108 printf("Zones overlap.\n");
111 if (cpos
!= zone
[r
].start
) {
112 printf("Zones are not contiguous.\n");
113 cpos
= zone
[r
].start
;
116 cpos
+= zone
[r
].size
;
117 if (cpos
> sb
->ntotal
) {
118 printf("Zones exceed disc size.\n");
124 printf("Detected structure: ZONE_NAME (start,end)\n");
125 printf("0: SB (0,1) : ");
126 for (r
= 0; r
< nzones
; ++r
) {
127 printf("%s (%d,%d): ", zone
[r
].name
, zone
[r
].start
,
128 zone
[r
].start
+ zone
[r
].size
);
130 printf("%d\n", sb
->ntotal
);
135 testresult_t
test_sbfctablesize (void)
140 fetch_superblock(&sb
);
142 /* ceil(a/b) = (a + b - 1)/b */
145 if (sb
->fctable_size
< ((sb
->dzone_size
-1)+RPB
-1)/RPB
) {
146 printf("FCT too small to hold references to all clusters (even"
147 "considering that the root directory block will never be"
152 if (sb
->fctable_size
< (sb
->dzone_size
+RPB
-1)/RPB
) {
153 printf("FCT too big.\n");
160 testresult_t
test_sbciutablesize (void)
165 fetch_superblock(&sb
);
167 /* ceil(a/b) = (a + b - 1)/b */
170 if (sb
->ciutable_size
< (sb
->dzone_size
+RPB
-1)/RPB
) {
171 printf("Cluster inode usage table too small.\n");
175 if (sb
->ciutable_size
< (sb
->dzone_size
+RPB
-1)/RPB
) {
176 printf("Cluster inode usage table too big.\n");
183 testresult_t
test_sbitotal (void)
188 fetch_superblock(&sb
);
190 /* ceil(a/b) = (a + b - 1)/b */
193 if (sb
->itable_size
< (sb
->itotal
+IPB
-1)/IPB
) {
194 printf("Inode table too small.\n");
197 if (sb
->itable_size
> (sb
->itotal
+IPB
-1)/IPB
) {
198 printf("Inode table too big.\n");
205 testresult_t
test_sbifree (void)
211 fetch_superblock(&sb
);
213 /* number of free inodes found in the free inode list */
219 /* index of the current inode */
222 /* inode status from ictable */
227 inodeidx
= sb
->ihead
;
228 while ((inodeidx
!= NULL_INODE
) && (ret
!= corrupt
)) {
229 if (inodeidx
< sb
->itotal
) {
230 ictable_get(inodeidx
, &icstat
);
232 ictable_set(inodeidx
, idle
);
233 fret
= soReadInode(&inode
, inodeidx
);
235 perror("soReadInode:");
240 printf("Free inode list is corrupted.\n");
244 printf("Free inode list is corrupted.\n");
247 inodeidx
= inode
.next
;
250 if ((ret
!= corrupt
) && (ifree
!= sb
->ifree
)) {
251 printf("ifree is incorrect.\n");
258 testresult_t
test_sbfreeclusters (void)
261 uint32_t freeclusters
;
264 fetch_superblock(&sb
);
268 if ((sb
->fctable_head
>= sb
->fctable_size
*RPB
) || (sb
->fctable_tail
>= sb
->fctable_size
*RPB
)) {
269 printf("fctable head or tail out of bounds.\n");
272 if (sb
->fctable_tail
< sb
->fctable_head
) {
273 freeclusters
= (sb
->fctable_tail
+ sb
->fctable_size
*RPB
) - sb
->fctable_head
;
275 freeclusters
= sb
->fctable_tail
- sb
->fctable_head
;
277 freeclusters
+= sb
->dzone_head
.cache_cnt
;
278 freeclusters
+= sb
->dzone_tail
.cache_cnt
;
280 if (freeclusters
!= sb
->dzone_free
) {
281 printf("donze_free is not correct.\n");
289 void main (int argc
, char *argv
[])
293 testresult_t testres
;
297 /* functions containing the tests to be made */
300 {test_sbmagic
, "sbmagic"},
301 {test_sbzones
, "sbzones"},
302 {test_sbfctablesize
, "sbfctablesize"},
303 {test_sbciutablesize
, "sbciutablesize"},
304 {test_sbitotal
, "sbitotal"},
305 {test_sbifree
, "sbifree"},
306 {test_sbfreeclusters
, "sbfreeclusters"},
309 if (argc
!= 2) ABORT(-EINVAL
);
310 nfuncs
= sizeof(test
)/sizeof(test_t
);
313 printf("Opening file %s as disc.\n", disc_path
);
314 ret
= soOpenDevice(disc_path
);
315 if (ret
< 0) ABORT(ret
);
316 atexit((void *)soCloseDevice
);
318 for (r
= 0; r
< nfuncs
; ++r
) {
319 testres
= test
[r
].function();
322 printf("System file corrupted.\n");
326 printf("System file is weird.\n");
329 printf("Test %s passed with success.\n", test
[r
].name
);