Table printing changed. directory parsing corrected.
[fsck.sofs09.git] / test_clusterfree.c
blob0c385454a60539e10f5533e0966afd2eb48acfc9
1 #include <stdio.h>
3 #include "sofs09.h"
4 #include "fsck.h"
5 #include "fsck_helper.h"
7 static bool check_cluster(uint32_t cba)
9 uint32_t ci;
10 cc_t ccstat;
11 SOSuperBlock *sb;
13 fetch_superblock(&sb);
15 /* check if block address is inside data zone and if it is a valid
16 * cluster address (alignment) */
17 if (cba < (sb->dzone_start)\
18 || cba >= (sb->dzone_start) + (sb->dzone_size)*BLOCKS_PER_CLUSTER\
19 || ((cba-(sb->dzone_start))%BLOCKS_PER_CLUSTER) != 0)
21 printf("Member of free cluster list is not a valid cluster address.\n");
22 return false;
25 /* check if cluster was already marked */
26 ci = (cba-(sb->dzone_start))/BLOCKS_PER_CLUSTER;
27 cctable_get(ci, &ccstat);
28 if (ccstat != bah) {
29 printf("Cluster number %d is used multiple times.\n", ci);
30 return false;
33 /* mark cluster */
34 cctable_set(ci, idle);
36 return true;
39 testresult_t test_clusterfree (void)
41 testresult_t ret;
42 uint32_t fret;
43 uint32_t freeclusters;
44 uint32_t pos;
45 uint32_t fcrefs[RPB];
46 uint32_t cba; /* cluster block address */
47 SOSuperBlock *sb;
48 uint32_t cacheidx, cachecnt;
49 uint32_t r;
51 fetch_superblock(&sb);
53 ret = nice;
54 freeclusters = 0;
56 /* check fctable limits */
57 if ((sb->fctable_head) >= (sb->fctable_size)*RPB) {
58 printf("fctable_head is out of bounds.\n");
59 ret = corrupt;
61 if ((sb->fctable_tail) >= (sb->fctable_size)*RPB) {
62 printf("fctable_tail is out of bounds.\n");
63 ret = corrupt;
65 pos = sb->fctable_head;
66 while ((pos != sb->fctable_tail) && (ret != corrupt)) {
67 fret = soReadRawBlock((sb->fctable_start)+(pos/RPB), fcrefs);
68 if (fret < 0) FABORT(fret, "sbfreeclusters");
70 cba = fcrefs[pos%RPB];
71 if (check_cluster(cba) == true) {
72 freeclusters++;
73 } else {
74 ret = corrupt;
76 pos = (pos+1)%((sb->fctable_size)*RPB);
79 /* check head cache */
80 cacheidx = sb->dzone_head.cache_idx;
81 cachecnt = sb->dzone_head.cache_cnt;
82 if ((cacheidx + cachecnt > DZONE_CACHE_SIZE) && (ret != corrupt)) {
83 printf("Head cache has incorrect information.\n");
84 ret = corrupt;
86 for (r = cacheidx; (r < cacheidx + cachecnt) && (ret != corrupt); ++r) {
87 cba = (sb->dzone_head.cache)[r];
88 if (check_cluster(cba) == true) {
89 freeclusters++;
90 } else {
91 ret = corrupt;
95 /* check tail cache */
96 cacheidx = 0;
97 cachecnt = sb->dzone_tail.cache_cnt;
98 if ((cacheidx + cachecnt >= DZONE_CACHE_SIZE) && (ret != corrupt)) {
99 printf("Tail cache has incorrect information.\n");
100 ret = corrupt;
102 for (r = cacheidx; (r < cacheidx + cachecnt) && (ret != corrupt); ++r) {
103 cba = (sb->dzone_head.cache)[r];
104 if (check_cluster(cba) == true) {
105 freeclusters++;
106 } else {
107 ret = corrupt;
111 if ((ret != corrupt) && (freeclusters != sb->dzone_free)) {
112 printf("donze_free is not correct.\n");
113 ret = corrupt;
116 return ret;