(* lecture sur un descripteur *)
let read desc buffer from len =
  let p = desc.inode.partition in
  if desc.closed then system_error EINVAL "read" "closed descr";
  if desc.inode.stats.st_size > p.max_file_size then
    system_error EIO "read" "Inconsistent file system";
  if len <= 0 || from + len > String.length buffer then
    system_error EINVAL "read" "negative length";
  let len = min len (desc.inode.stats.st_size - desc.posin
  let rec read start len ret =
    if len > 0 then
      let block = desc.pos / p.block_size in
      let pos' = desc.pos mod p.block_size in
      let len' = min len (p.block_size - pos') in
      let bid = desc.inode.blocktbl.(blockin
      if bid > 0 then
        let b = read_block p bid in
        String.blit b posbuffer start len';
      else
        String.fill buffer start len' '\000';
      desc.pos <- desc.pos + len';
      read (start + len') (len - len') (ret + len')
    else ret in
  read from len 0