示例#1
0
文件: read.c 项目: boostsup/minix3
/*===========================================================================*
 *				fs_breadwrite_s				     *
 *===========================================================================*/
PUBLIC int fs_breadwrite_s(void)
{
  int r, rw_flag, chunk, block_size;
  cp_grant_id_t gid;
  int nrbytes;
  u64_t position;
  unsigned int off, cum_io;
  mode_t mode_word;
  int completed, r2 = OK;

  /* Pseudo inode for rw_chunk */
  struct inode rip;
  
  r = OK;
  
  /* Get the values from the request message */ 
  rw_flag = (fs_m_in.m_type == REQ_BREAD_S ? READING : WRITING);
  gid = fs_m_in.REQ_XFD_GID;
  position = make64(fs_m_in.REQ_XFD_POS_LO, fs_m_in.REQ_XFD_POS_HI);
  nrbytes = (unsigned) fs_m_in.REQ_XFD_NBYTES;
  
  block_size = get_block_size(fs_m_in.REQ_XFD_BDEV);

  rip.i_zone[0] = fs_m_in.REQ_XFD_BDEV;
  rip.i_mode = I_BLOCK_SPECIAL;
  rip.i_size = 0;

  rdwt_err = OK;		/* set to EIO if disk error occurs */
  
  cum_io = 0;
  /* Split the transfer into chunks that don't span two blocks. */
  while (nrbytes != 0) {
      off = rem64u(position, block_size);	/* offset in blk*/
        
      chunk = MIN(nrbytes, block_size - off);
      if (chunk < 0) chunk = block_size - off;

      /* Read or write 'chunk' bytes. */
      r = rw_chunk_s(&rip, position, off, chunk, (unsigned) nrbytes,
              rw_flag, gid, cum_io, block_size, &completed);

      if (r != OK) break;	/* EOF reached */
      if (rdwt_err < 0) break;

      /* Update counters and pointers. */
      nrbytes -= chunk;	        /* bytes yet to be read */
      cum_io += chunk;	        /* bytes read so far */
      position= add64ul(position, chunk);	/* position within the file */
  }
  
  fs_m_out.RES_XFD_POS_LO = ex64lo(position); 
  fs_m_out.RES_XFD_POS_HI = ex64hi(position); 
  
  if (rdwt_err != OK) r = rdwt_err;	/* check for disk error */
  if (rdwt_err == END_OF_FILE) r = OK;

  fs_m_out.RES_XFD_CUM_IO = cum_io;
  
  return(r);
}
示例#2
0
文件: read.c 项目: wieck/minix
/*===========================================================================*
 *				fs_breadwrite				     *
 *===========================================================================*/
int fs_breadwrite(void)
{
  int r, rw_flag, completed;
  cp_grant_id_t gid;
  u64_t position;
  unsigned int off, cum_io, chunk, block_size;
  size_t nrbytes;

  /* Pseudo inode for rw_chunk */
  struct inode rip;

  r = OK;

  /* Get the values from the request message */
  rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING);
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  position = make64((unsigned long) fs_m_in.REQ_SEEK_POS_LO,
                    (unsigned long) fs_m_in.REQ_SEEK_POS_HI);
  nrbytes = (size_t) fs_m_in.REQ_NBYTES;

  block_size = get_block_size( (dev_t) fs_m_in.REQ_DEV2);

  rip.i_block[0] = (block_t) fs_m_in.REQ_DEV2;
  rip.i_mode = I_BLOCK_SPECIAL;
  rip.i_size = 0;

  rdwt_err = OK;                /* set to EIO if disk error occurs */

  cum_io = 0;
  /* Split the transfer into chunks that don't span two blocks. */
  while (nrbytes > 0) {
	  off = rem64u(position, block_size);	/* offset in blk*/
	  chunk = min(nrbytes, block_size - off);

	  /* Read or write 'chunk' bytes. */
	  r = rw_chunk(&rip, position, off, chunk, nrbytes, rw_flag, gid,
		       cum_io, block_size, &completed);

	  if (r != OK) break;	/* EOF reached */
	  if (rdwt_err < 0) break;

	  /* Update counters and pointers. */
	  nrbytes -= chunk;	        /* bytes yet to be read */
	  cum_io += chunk;	        /* bytes read so far */
	  position = add64ul(position, chunk);	/* position within the file */
  }

  fs_m_out.RES_SEEK_POS_LO = ex64lo(position);
  fs_m_out.RES_SEEK_POS_HI = ex64hi(position);

  if (rdwt_err != OK) r = rdwt_err;     /* check for disk error */
  if (rdwt_err == END_OF_FILE) r = OK;

  fs_m_out.RES_NBYTES = cum_io;

  return(r);
}
示例#3
0
/*===========================================================================*
 *				do_lseek				     *
 *===========================================================================*/
int do_lseek()
{
/* Perform the lseek(ls_fd, offset, whence) system call. */
  register struct filp *rfilp;
  int r = OK, seekfd, seekwhence;
  off_t offset;
  u64_t pos, newpos;

  seekfd = job_m_in.ls_fd;
  seekwhence = job_m_in.whence;
  offset = (off_t) job_m_in.offset_lo;

  /* Check to see if the file descriptor is valid. */
  if ( (rfilp = get_filp(seekfd, VNODE_READ)) == NULL) return(err_code);

  /* No lseek on pipes. */
  if (S_ISFIFO(rfilp->filp_vno->v_mode)) {
	unlock_filp(rfilp);
	return(ESPIPE);
  }

  /* The value of 'whence' determines the start position to use. */
  switch(seekwhence) {
    case SEEK_SET: pos = cvu64(0);	break;
    case SEEK_CUR: pos = rfilp->filp_pos;	break;
    case SEEK_END: pos = cvul64(rfilp->filp_vno->v_size);	break;
    default: unlock_filp(rfilp); return(EINVAL);
  }

  if (offset >= 0)
	newpos = add64ul(pos, offset);
  else
	newpos = sub64ul(pos, -offset);

  /* Check for overflow. */
  if (ex64hi(newpos) != 0) {
	r = EOVERFLOW;
  } else if ((off_t) ex64lo(newpos) < 0) { /* no negative file size */
	r = EOVERFLOW;
  } else {
	/* insert the new position into the output message */
	m_out.reply_l1 = ex64lo(newpos);

	if (cmp64(newpos, rfilp->filp_pos) != 0) {
		rfilp->filp_pos = newpos;

		/* Inhibit read ahead request */
		r = req_inhibread(rfilp->filp_vno->v_fs_e,
				  rfilp->filp_vno->v_inode_nr);
	}
  }

  unlock_filp(rfilp);
  return(r);
}
示例#4
0
/*===========================================================================*
 *				scall_lseek				     *
 *===========================================================================*/
int scall_lseek()
{
	/* Perform the lseek(ls_fd, offset, whence) system call. */
	register struct filp *rfilp;
	int r;
	long offset;
	u64_t pos, newpos;

	/* Check to see if the file descriptor is valid. */
	if ( (rfilp = get_filp(m_in.ls_fd)) == NIL_FILP)
		return(err_code);

	/* No lseek on pipes. */
	if (rfilp->filp_vno->v_pipe == I_PIPE)
		return -ESPIPE;

	/* The value of 'whence' determines the start position to use. */
	switch(m_in.whence) {
	case SEEK_SET:
		pos = cvu64(0);
		break;

	case SEEK_CUR:
		pos = rfilp->filp_pos;
		break;

	case SEEK_END:
		pos = cvul64(rfilp->filp_vno->v_size);
		break;

	default:
		return(-EINVAL);
	}

	offset= m_in.offset_lo;
	if (offset >= 0)
		newpos= add64ul(pos, offset);
	else
		newpos= sub64ul(pos, -offset);

	/* Check for overflow. */
	if (ex64hi(newpos) != 0)
		return -EINVAL;

	if (cmp64(newpos, rfilp->filp_pos) != 0) { /* Inhibit read ahead request */
		r = req_inhibread(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr);

		if (r != 0)
			return r;
	}

	rfilp->filp_pos = newpos;

	return ex64lo(newpos);
}
示例#5
0
文件: read.c 项目: 0xenvision/minix
/*===========================================================================*
 *				fs_bread				     *
 *===========================================================================*/
int fs_bread(void)
{
    int r, rw_flag, chunk, block_size;
    cp_grant_id_t gid;
    int nrbytes;
    u64_t position;
    unsigned int off, cum_io;
    int completed;
    struct dir_record *dir;

    r = OK;

    rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING);
    gid = fs_m_in.REQ_GRANT;
    position = make64(fs_m_in.REQ_SEEK_POS_LO, fs_m_in.REQ_SEEK_POS_HI);
    nrbytes = (unsigned) fs_m_in.REQ_NBYTES;
    block_size = v_pri.logical_block_size_l;
    dir = v_pri.dir_rec_root;

    if(rw_flag == WRITING) return (EIO);	/* Not supported */
    rdwt_err = OK;		/* set to EIO if disk error occurs */

    cum_io = 0;
    /* Split the transfer into chunks that don't span two blocks. */
    while (nrbytes != 0) {
        off = rem64u(position, block_size);	/* offset in blk*/

        chunk = MIN(nrbytes, block_size - off);
        if (chunk < 0) chunk = block_size - off;

        /* Read 'chunk' bytes. */
        r = read_chunk(dir, position, off, chunk, (unsigned) nrbytes,
                       gid, cum_io, block_size, &completed);

        if (r != OK) break;	/* EOF reached */
        if (rdwt_err < 0) break;

        /* Update counters and pointers. */
        nrbytes -= chunk;	        /* bytes yet to be read */
        cum_io += chunk;	        /* bytes read so far */
        position= add64ul(position, chunk);	/* position within the file */
    }

    fs_m_out.RES_SEEK_POS_LO = ex64lo(position);
    fs_m_out.RES_SEEK_POS_HI = ex64hi(position);

    if (rdwt_err != OK) r = rdwt_err;	/* check for disk error */
    if (rdwt_err == END_OF_FILE) r = OK;

    fs_m_out.RES_NBYTES = cum_io;

    return(r);
}