Keep going to show all errors.
[fsck.sofs09.git] / test_clusterused.c
blobe38147bce9d1af0ada191c0979b0eb19f205af89
1 #include "sofs09.h"
2 #include "fsck.h"
3 #include "fsck_helper.h"
5 static bool check_cluster(uint32_t pcn, uint32_t cn, uint32_t inodeidx)
7 bool ret;
8 uint32_t cidx;
9 uint32_t ciurefs[RPB];
10 cc_t ccstat;
11 SOSuperBlock *sb;
12 uint32_t clucount;
14 fetch_superblock(&sb);
15 ret = true;
16 clucount = 0;
18 if (pcn != NULL_BLOCK) {
19 clucount++;
21 /* check alignment */
22 if ((pcn-(sb->dzone_start))%(BLOCKS_PER_CLUSTER)) {
23 printf("Cluster number %d of inode number %d points to "
24 "unaligned block.\n", cn, inodeidx);
25 return false;
28 /* overflow is irrelevant here */
29 /* check if cluster address is in bounds */
30 cidx = (pcn-(sb->dzone_start))/(BLOCKS_PER_CLUSTER);
31 if (cidx >= sb->dzone_size) {
32 printf("Cluster number %d of inode number %d points to a place "
33 "outside data zone.\n", cn, inodeidx);
34 return false;
37 /* check CIUT */
38 soReadRawBlock(sb->ciutable_start+(cidx/RPB), ciurefs);
39 if (ciurefs[cidx%RPB] != inodeidx) {
40 printf("Entry in CIUT for cluster number %d points to inode "
41 "%d, bot it is used by inode %d.\n", cidx,
42 ciurefs[cidx%RPB], inodeidx);
43 return false;
46 /* check cctable */
47 cctable_get(cidx, &ccstat);
48 switch (ccstat) {
49 case bah:
50 cctable_set(cidx, busy);
51 break;
52 case idle:
53 printf("Cluster number %d is used by inode %d but is also "
54 "a free cluster.\n", cidx, inodeidx);
55 return false;
56 break;
57 case busy:
58 printf("Cluster %d is used several times by inode %d.\n",
59 cidx, inodeidx);
60 return false;
61 break;
62 default:
63 printf("BUM! parse_clusters: cctable is corrupt.\n");
64 return false;
65 break;
69 return ret;
71 bool parse_clusters(uint32_t inodeidx)
73 bool ret;
74 uint32_t cnmax;
75 uint32_t pcn;
76 uint32_t fret;
77 uint32_t irefs[RPC];
78 uint32_t iirefs[RPC];
79 int i1,i2;
80 SOSuperBlock *sb;
81 SOInode inode;
83 fetch_superblock(&sb);
84 ret = true;
86 fret = soReadInode(&inode, inodeidx);
87 if (fret < 0) FABORT(fret, "parse_cluster");
89 /* check data clusters */
90 cnmax = (inode.size + CLUSTER_SIZE - 1)/CLUSTER_SIZE;
91 for (i1 = 0; i1 < cnmax; i1++) {
92 fret = soHandleFileCluster(inodeidx, i1, OP_GET, &pcn);
93 if (fret < 0) FABORT(fret, "parse_cluster");
95 if (check_cluster(pcn, i1, inodeidx) == false) {
96 return false;
100 /* check reference clusters */
102 if (cnmax > N_DIRECT) {
103 if (check_cluster(inode.i1, -1, inodeidx) == false) {
104 return false;
106 fret = soReadCacheCluster(inode.i1, irefs);
107 if (fret < 0) FABORT(fret, "parse_cluster");
108 for (i1 = 0; (i1 < cnmax-N_DIRECT) && (i1 < RPC); ++i1) {
109 if (check_cluster(irefs[i1], -1, inodeidx) == false) {
110 return false;
115 if (cnmax > (N_DIRECT + RPC)) {
116 if (check_cluster(inode.i2, -1, inodeidx) == false) {
117 return false;
119 fret = soReadCacheCluster(inode.i2, iirefs);
120 if (fret < 0) FABORT(fret, "parse_cluster");
121 for (i2 = 0; (i2 < RPC) && (i2*RPC < cnmax-N_DIRECT-RPC); ++i2) {
122 if (check_cluster(iirefs[i2], -1, inodeidx) == false) {
123 return false;
125 fret = soReadCacheCluster(iirefs[i2], irefs);
126 if (fret < 0) FABORT(fret, "parse_cluster");
127 for (i1 = 0; (i1 < RPC) && (i2*RPC+i1 < cnmax-N_DIRECT-RPC); ++i1) {
128 if (check_cluster(irefs[i1], -1, inodeidx) == false) {
129 return false;
136 return ret;
139 /* assumes inodes are sane */
140 testresult_t test_clusterused(void)
142 testresult_t ret;
143 ic_t icstat;
144 SOSuperBlock *sb;
145 SOInode inode;
146 uint32_t r;
148 fetch_superblock(&sb);
149 ret = nice;
151 for (r = 0; (r < sb->itotal) && (ret != corrupt); ++r) {
152 ictable_get(r, &icstat);
153 soReadInode(&inode, r);
154 switch (icstat) {
155 case idle:
156 if ((inode.mode & INODE_TYPE_MASK & (!INODE_FREE)) != 0) {
157 /* inode is dirty - check */
158 if (parse_clusters(r) == false) ret = corrupt;
160 break;
161 case busy:
162 if (parse_clusters(r) == false) ret = corrupt;
163 break;
164 default:
165 printf("BUM! test_clusterused assumes inode control has "
166 "only idle and busy in it by now.\n");
167 ret = corrupt;
168 break;
172 return ret;