5 #include "fsck_helper.h"
7 /* create function check_cluster and remove repeated code */
8 testresult_t
test_clusterfree (void)
12 uint32_t freeclusters
;
15 uint32_t cba
; /* cluster block address */
16 uint32_t ci
; /* cluster index */
19 uint32_t cacheidx
, cachecnt
;
22 fetch_superblock(&sb
);
28 if ((sb
->fctable_head
) >= (sb
->fctable_size
)*RPB
) {
29 printf("fctable_head is out of bounds.\n");
32 if ((sb
->fctable_tail
) >= (sb
->fctable_size
)*RPB
) {
33 printf("fctable_tail is out of bounds.\n");
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");
51 ci
= (cba
-(sb
->dzone_start
))/BLOCKS_PER_CLUSTER
;
52 cctable_get(ci
, &ccstat
);
54 cctable_set(ci
, idle
);
55 pos
= (pos
+1)%((sb
->fctable_size
)*RPB
);
58 printf("Cluster number %d is used multiple times.\n", ci
);
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");
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");
82 ci
= (cba
-(sb
->dzone_start
))/BLOCKS_PER_CLUSTER
;
83 cctable_get(ci
, &ccstat
);
85 cctable_set(ci
, idle
);
86 pos
= (pos
+1)%((sb
->fctable_size
)*RPB
);
89 printf("Cluster number %d is used multiple times.\n", ci
);
95 /* check tail cache */
97 cachecnt
= sb
->dzone_tail
.cache_cnt
;
98 if ((cacheidx
+ cachecnt
>= DZONE_CACHE_SIZE
) && (ret
!= corrupt
)) {
99 printf("Tail cache has incorrect information.\n");
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");
113 ci
= (cba
-(sb
->dzone_start
))/BLOCKS_PER_CLUSTER
;
114 cctable_get(ci
, &ccstat
);
116 cctable_set(ci
, idle
);
117 pos
= (pos
+1)%((sb
->fctable_size
)*RPB
);
120 printf("Cluster number %d is used multiple times.\n", ci
);
126 if ((ret
!= corrupt
) && (freeclusters
!= sb
->dzone_free
)) {
127 printf("donze_free is not correct.\n");