let fsck p =

(* init the table of blocks *)
  let t = Array.create p.block_nb (Block falsein
  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.(inodewith
      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.(nin
            match t.(bwith
              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 (inodename) = 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.(blockwith
        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.(bwith
            | 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.(nwith
      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.(nwith
      Block false -> Printf.printf "Forgotten block %d\n" n
    | _ -> ()
  done;

  Printf.printf "Scan done\n";
  ()