(* clear file *)
  let trunc inode =
    assert (inode.stats.st_kind == S_REG);
    if inode.stats.st_size > max_file_size then
      raise (File_system_error "Inconsistant file system");
    let rec free_blocks n =
      if n != 0 then
        begin
          if inode.blocktbl.(n) != 0 then
            begin
              free_block inode.blocktbl.(n);
              inode.blocktbl.(n) <- 0
            end;
          free_blocks (n-1)
        end in
    free_blocks (inode.stats.st_size / D.block_size + 1);
    inode.stats.st_size <- 0;;

  let openfile name flags =
    let inode = namei name in
    if inode.stats.st_size > max_file_size then
      raise (File_system_error "Inconsistant file system");
    let block = ref 0 in
    let pos = ref 0 in
    let desc_flag = ref None in
    let rec read flags =
      match flags with
        O_RDONLY :: tail ->
          begin
            match !desc_flag with
              None -> desc_flag := Some O_RDONLY
            | _ -> raise (File_system_exception "Invalid open flags")
          end;
          read tail
      | O_WRONLY :: tail ->
          begin
            match !desc_flag with
              None -> desc_flag := Some O_WRONLY
            | _ -> raise (File_system_exception "Invalid open flags")
          end;
          read tail
      | O_RDWR :: tail ->
          begin
            match !desc_flag with
              None -> desc_flag := Some O_RDWR
            | _ -> raise (File_system_exception "Invalid open flags")
          end;
          read tail
      | O_APPEND :: tail ->
          block := inode.stats.st_size / D.block_size;
          pos :=  inode.stats.st_size mod D.block_size;
          read tail
      | O_TRUNC :: tail ->
          trunc inode;
          block := 0;
          pos :=  0;
          read tail
      | _ :: tail ->
           raise (File_system_exception "Not supported flag")
      | [] -> ()
    in
    read flags;
    let flag = match !desc_flag with
      None -> raise (File_system_exception "Invalid open flags")
    | Some mode -> mode in
    inode.reference_number <- inode.reference_number + 1;
    { inode = inodeblock = !blockpos = !posflag = flag };;