let fsck p = (* init the table of blocks *) let t = Array.create p.block_nb (Block false) in t.(0) <- Supernode; for i = 1 to p.inode_nb do t.(i) <- Inode 0 done; (* iter on the directories *) Printf.printf "Scanning directory tree\n"; let rec fsck_inode inode = Printf.printf "."; match t.(inode) with Inode 0 -> begin t.(inode) <- Inode 1; let i = read_inode p inode in for n = 0 to p.blocktbl_size - 1 do let b = i.blocktbl.(n) in match t.(b) with Block false -> if p.block_size * n > i.stats.st_size then failwith (Printf.sprintf "Inode %d uses a block after its size" inode); t.(b) <- Block true | Supernode -> () | _ -> failwith (Printf.sprintf "Inode %d uses block %d %s" inode b (string_of_block t.(b))) done; match i.stats.st_kind with S_REG -> () | S_DIR -> let fd = open_inode i in try while true do let (inode, name) = read_dirent fd in fsck_inode inode done with End_of_file -> () end | Inode n -> t.(inode) <- Inode (n+1) | _ -> failwith (Printf.sprintf "Inode %d is not an inode !" inode) in fsck_inode p.root_inode; Printf.printf "\n"; (* iter on the free block list *) Printf.printf "Scanning free block list\n"; let rec iter block nb = if block <> 0 then match t.(block) with Block false -> Printf.printf "(%d)" nb; t.(block) <- IndexBlock; let buffer = read_block p block in let next = read_int buffer 0 in for i = 1 to nb - 1 do let b = read_int buffer (i * 4) in match t.(b) with | Block false -> t.(b) <- FreeBlock | _ -> failwith (Printf.sprintf "Free Block %d has type %s" b (string_of_block t.(b))) done; iter next (p.block_word_size - 1) | _ -> failwith (Printf.sprintf "Block %d is not an index block !" block) in iter p.free_block_list ( (p.free_block_nb - 1) mod p.block_word_size); Printf.printf "\n"; (* scan inodes *) for n = 1 to p.inode_nb do let i = read_inode p n in match t.(n) with Inode x -> assert (x = i.stats.st_nlink) | _ -> failwith (Printf.sprintf "%d shoudl be an inode !" n) done; for n = p.inode_nb +1 to p.block_nb - 1 do match t.(n) with Block false -> Printf.printf "Forgotten block %d\n" n | _ -> () done; Printf.printf "Scan done\n"; () |