17 * - check hash table index
18 * - clear extents from free bitmap and make sure free bitmap is null
19 * - sanity check block size, sys block size, mirrors, etc
20 * - check that extent count is valid
21 * - check that terminator matches
22 * - make sure file sizes match up
25 int check_crc(u8
*blk
)
28 size_t hdr_size
= sizeof(struct omfs_header
);
29 struct omfs_inode
*oi
;
31 oi
= (struct omfs_inode
*) blk
;
33 crc
= crc_ccitt_msb(0, blk
+ hdr_size
,
34 swap_be32(oi
->i_head
.h_body_size
));
36 return (crc
== swap_be16(oi
->i_head
.h_crc
));
39 int check_header(u8
*blk
)
43 struct omfs_inode
*oi
;
45 oi
= (struct omfs_inode
*) blk
;
48 for (i
= 1; i
< OMFS_XOR_COUNT
; i
++)
51 return (xor == oi
->i_head
.h_check_xor
);
54 int check_sanity(check_context_t
*ctx
)
56 omfs_inode_t
*inode
= ctx
->current_inode
;
57 if (swap_be32(inode
->i_head
.h_body_size
) >
58 swap_be32(ctx
->omfs_info
->super
->s_sys_blocksize
))
61 // check device size here too.
65 int check_bitmap(check_context_t
*ctx
)
70 omfs_super_t
*super
= ctx
->omfs_info
->super
;
71 omfs_root_t
*root
= ctx
->omfs_info
->root
;
76 bsize
= (swap_be64(super
->s_num_blocks
) + 7) / 8;
77 first_blk
= swap_be64(root
->r_bitmap
) + (bsize
+
78 swap_be32(super
->s_blocksize
)-1) /
79 swap_be32(super
->s_blocksize
);
81 for (i
=0; i
< first_blk
; i
++)
82 set_bit(ctx
->visited
, i
);
84 for (i
=0; i
< bsize
; i
++)
86 if (ctx
->bitmap
[i
] != ctx
->visited
[i
])
89 if (!ctx
->config
->is_quiet
)
91 printf("Wrong bitmap byte at %d (%02x,%02x)\n",
92 i
, ctx
->bitmap
[i
], ctx
->visited
[i
]);
98 fix_problem(E_BITMAP
, ctx
);
103 void visit_extents(check_context_t
*ctx
)
105 struct omfs_extent
*oe
;
106 struct omfs_extent_entry
*entry
;
112 buf
= omfs_get_block(ctx
->omfs_info
, next
);
116 oe
= (struct omfs_extent
*) &buf
[OMFS_EXTENT_START
];
120 extent_count
= swap_be32(oe
->e_extent_count
);
122 next
= swap_be64(oe
->e_next
);
123 entry
= &oe
->e_entry
;
125 // ignore last entry as it is the terminator
126 for (; extent_count
> 1; extent_count
--)
128 u64 start
= swap_be64(entry
->e_cluster
);
130 for (i
=0; i
<swap_be64(entry
->e_blocks
); i
++)
131 set_bit(ctx
->visited
, start
+ i
);
136 set_bit(ctx
->visited
, last
);
137 set_bit(ctx
->visited
, last
+1);
143 buf
= omfs_get_block(ctx
->omfs_info
, next
);
146 oe
= (struct omfs_extent
*) &buf
[OMFS_EXTENT_CONT
];
153 int check_inode(check_context_t
*ctx
)
157 omfs_inode_t
*inode
= ctx
->current_inode
;
159 if (test_bit(ctx
->visited
, ctx
->block
))
161 fix_problem(E_LOOP
, ctx
);
164 for (i
=0; i
< swap_be32(ctx
->omfs_info
->super
->s_mirrors
); i
++)
165 set_bit(ctx
->visited
, ctx
->block
+ i
);
167 if (!check_sanity(ctx
))
169 fix_problem(E_INSANE
, ctx
);
172 if (!check_header((u8
*)inode
))
174 fix_problem(E_HEADER_XOR
, ctx
);
177 if (!check_crc((u8
*)inode
))
179 fix_problem(E_HEADER_CRC
, ctx
);
182 if (swap_be64(inode
->i_head
.h_self
) != ctx
->block
)
184 fix_problem(E_SELF_PTR
, ctx
);
187 if (swap_be64(inode
->i_parent
) != ctx
->parent
)
189 fix_problem(E_PARENT_PTR
, ctx
);
192 if (omfs_compute_hash(ctx
->omfs_info
, inode
->i_name
) != ctx
->hash
)
194 fix_problem(E_HASH_WRONG
, ctx
);
197 if (inode
->i_type
== OMFS_FILE
)
205 static int on_node(dirscan_t
*d
, dirscan_entry_t
*entry
, void *user
)
207 check_context_t
*ctx
= (check_context_t
*) user
;
209 ctx
->current_inode
= entry
->inode
;
210 ctx
->block
= entry
->block
;
211 ctx
->parent
= entry
->parent
;
212 ctx
->hash
= entry
->hindex
;
213 return check_inode(ctx
);
216 int check_fs(FILE *fp
, check_fs_config_t
*config
)
231 if (omfs_read_super(&info
))
233 fix_problem(E_READ_SUPER
, &ctx
);
236 if (omfs_read_root_block(&info
))
238 fix_problem(E_READ_ROOT
, &ctx
);
242 ctx
.omfs_info
= &info
;
243 omfs_load_bitmap(&info
);
244 ctx
.bitmap
= info
.bitmap
->bmap
;
245 bsize
= (swap_be64(info
.super
->s_num_blocks
) + 7) / 8;
246 ctx
.visited
= calloc(1, bsize
);
248 /* FIXME error codes are all over the place. */
249 res
= dirscan_begin(&info
, on_node
, &ctx
);
253 fix_problem(E_SCAN
, &ctx
);
259 res
= check_bitmap(&ctx
);