Added test_clusterlost.
[fsck.sofs09.git] / test_clusterfree.c
blobdd21b0feb65fe27e527f14a292afca9d5da4c9fb
1 #include <stdio.h>
3 #include "sofs09.h"
4 #include "fsck.h"
5 #include "fsck_helper.h"
7 /* create function check_cluster and remove repeated code */
8 testresult_t test_clusterfree (void)
10 testresult_t ret;
11 uint32_t fret;
12 uint32_t freeclusters;
13 uint32_t pos;
14 uint32_t fcrefs[RPB];
15 uint32_t cba; /* cluster block address */
16 uint32_t ci; /* cluster index */
17 cc_t ccstat;
18 SOSuperBlock *sb;
19 uint32_t cacheidx, cachecnt;
20 uint32_t r;
22 fetch_superblock(&sb);
24 ret = nice;
25 freeclusters = 0;
27 /* check fctable */
28 if ((sb->fctable_head) >= (sb->fctable_size)*RPB) {
29 printf("fctable_head is out of bounds.\n");
30 ret = corrupt;
32 if ((sb->fctable_tail) >= (sb->fctable_size)*RPB) {
33 printf("fctable_tail is out of bounds.\n");
34 ret = corrupt;
36 pos = sb->fctable_head;
37 while ((pos != sb->fctable_tail) && (ret != corrupt)) {
38 fret = soReadRawBlock((sb->fctable_start)+(pos/RPB), fcrefs);
39 if (fret < 0) FABORT(fret, "sbfreeclusters");
41 cba = fcrefs[pos%RPB];
42 /* check if block address is inside data zone and if it is a valid
43 * cluster address (alignment) */
44 if (cba < (sb->dzone_start)\
45 || cba >= (sb->dzone_start) + (sb->dzone_size)*BLOCKS_PER_CLUSTER\
46 || ((cba-(sb->dzone_start))%BLOCKS_PER_CLUSTER) != 0)
48 printf("Member of free cluster list is not a valid cluster address.\n");
49 ret = corrupt;
50 } else {
51 ci = (cba-(sb->dzone_start))/BLOCKS_PER_CLUSTER;
52 cctable_get(ci, &ccstat);
53 if (ccstat == bah) {
54 cctable_set(ci, idle);
55 pos = (pos+1)%((sb->fctable_size)*RPB);
56 freeclusters++;
57 } else {
58 printf("Cluster number %d is used multiple times.\n", ci);
59 ret = corrupt;
64 /* check head cache */
65 cacheidx = sb->dzone_head.cache_idx;
66 cachecnt = sb->dzone_head.cache_cnt;
67 if ((cacheidx + cachecnt >= DZONE_CACHE_SIZE) && (ret != corrupt)) {
68 printf("Head cache has incorrect information.\n");
69 ret = corrupt;
71 for (r = cacheidx; (r < cacheidx + cachecnt) && (ret != corrupt); ++r) {
72 cba = (sb->dzone_head.cache)[r];
73 /* check if block address is inside data zone and if it is a valid
74 * cluster address (alignment) */
75 if (cba < (sb->dzone_start)\
76 || cba >= (sb->dzone_start) + (sb->dzone_size)*BLOCKS_PER_CLUSTER\
77 || ((cba-(sb->dzone_start))%BLOCKS_PER_CLUSTER) != 0)
79 printf("Member of head cache is not a valid cluster address.\n");
80 ret = corrupt;
81 } else {
82 ci = (cba-(sb->dzone_start))/BLOCKS_PER_CLUSTER;
83 cctable_get(ci, &ccstat);
84 if (ccstat == bah) {
85 cctable_set(ci, idle);
86 pos = (pos+1)%((sb->fctable_size)*RPB);
87 freeclusters++;
88 } else {
89 printf("Cluster number %d is used multiple times.\n", ci);
90 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 /* check if block address is inside data zone and if it is a valid
105 * cluster address (alignment) */
106 if (cba < (sb->dzone_start)\
107 || cba >= (sb->dzone_start) + (sb->dzone_size)*BLOCKS_PER_CLUSTER\
108 || ((cba-(sb->dzone_start))%BLOCKS_PER_CLUSTER) != 0)
110 printf("Member of tail cache is not a valid cluster address.\n");
111 ret = corrupt;
112 } else {
113 ci = (cba-(sb->dzone_start))/BLOCKS_PER_CLUSTER;
114 cctable_get(ci, &ccstat);
115 if (ccstat == bah) {
116 cctable_set(ci, idle);
117 pos = (pos+1)%((sb->fctable_size)*RPB);
118 freeclusters++;
119 } else {
120 printf("Cluster number %d is used multiple times.\n", ci);
121 ret = corrupt;
126 if ((ret != corrupt) && (freeclusters != sb->dzone_free)) {
127 printf("donze_free is not correct.\n");
128 ret = corrupt;
131 return ret;