Now that we have enough room in the message, remove these types. Change-Id: Ib734c6f0209b259a14a1189b3886b9c8474e1b9a
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "fs.h"
 | 
						|
#include "buf.h"
 | 
						|
#include "inode.h"
 | 
						|
#include <minix/com.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
 | 
						|
/*===========================================================================*
 | 
						|
 *				fs_readwrite				     *
 | 
						|
 *===========================================================================*/
 | 
						|
int fs_readwrite(message *fs_m_in, message *fs_m_out)
 | 
						|
{
 | 
						|
  int r, rw_flag;
 | 
						|
  struct buf *bp;
 | 
						|
  cp_grant_id_t gid;
 | 
						|
  off_t position, f_size;
 | 
						|
  size_t nrbytes, cum_io;
 | 
						|
  mode_t mode_word;
 | 
						|
  struct inode *rip;
 | 
						|
  ino_t inumb;
 | 
						|
 | 
						|
  r = OK;
 | 
						|
  cum_io = 0;
 | 
						|
  inumb = fs_m_in->m_vfs_fs_readwrite.inode;
 | 
						|
 | 
						|
  /* Find the inode referred */
 | 
						|
  if ((rip = find_inode(inumb)) == NULL) return(EINVAL);
 | 
						|
 | 
						|
  mode_word = rip->i_mode & I_TYPE;
 | 
						|
  if (mode_word != I_NAMED_PIPE) return(EIO);
 | 
						|
  f_size = rip->i_size;
 | 
						|
 | 
						|
  /* Get the values from the request message */
 | 
						|
  rw_flag = (fs_m_in->m_type == REQ_READ ? READING : WRITING);
 | 
						|
  gid = fs_m_in->m_vfs_fs_readwrite.grant;
 | 
						|
  nrbytes = fs_m_in->m_vfs_fs_readwrite.nbytes;
 | 
						|
 | 
						|
  /* We can't read beyond the max file position */
 | 
						|
  if (nrbytes > PIPE_BUF) return(EFBIG);
 | 
						|
 | 
						|
  /* Mark inode in use */
 | 
						|
  if ((get_inode(rip->i_dev, rip->i_num)) == NULL) return(err_code);
 | 
						|
  if ((bp = get_block(rip->i_dev, rip->i_num)) == NULL) return(err_code);
 | 
						|
 | 
						|
  if (rw_flag == WRITING) {
 | 
						|
	/* Check in advance to see if file will grow too big. */
 | 
						|
	/* Casting nrbytes to signed is safe, because it's guaranteed not to
 | 
						|
	 * be beyond max signed value (i.e., MAX_FILE_POS).
 | 
						|
	 */
 | 
						|
	position = rip->i_size;
 | 
						|
	if ((unsigned) position + nrbytes > PIPE_BUF) {
 | 
						|
		put_inode(rip);
 | 
						|
		put_block(rip->i_dev, rip->i_num);
 | 
						|
		return(EFBIG);
 | 
						|
	}
 | 
						|
  } else {
 | 
						|
	position = 0;
 | 
						|
	if (nrbytes > rip->i_size) {
 | 
						|
		/* There aren't that many bytes to read */
 | 
						|
		nrbytes = rip->i_size;
 | 
						|
	}
 | 
						|
  }
 | 
						|
 | 
						|
  if (rw_flag == READING) {
 | 
						|
	/* Copy a chunk from the block buffer to user space. */
 | 
						|
	r = sys_safecopyto(fs_m_in->m_source, gid, (vir_bytes) 0,
 | 
						|
		(vir_bytes) (bp->b_data+position), (size_t) nrbytes);
 | 
						|
  } else {
 | 
						|
	/* Copy a chunk from user space to the block buffer. */
 | 
						|
	r = sys_safecopyfrom(fs_m_in->m_source, gid, (vir_bytes) 0,
 | 
						|
		(vir_bytes) (bp->b_data+position), (size_t) nrbytes);
 | 
						|
  }
 | 
						|
 | 
						|
  if (r == OK) {
 | 
						|
	position += (signed) nrbytes; /* Update position */
 | 
						|
	cum_io += nrbytes;
 | 
						|
 | 
						|
	/* On write, update file size and access time. */
 | 
						|
	if (rw_flag == WRITING) {
 | 
						|
		rip->i_size = position;
 | 
						|
	} else {
 | 
						|
		memmove(bp->b_data, bp->b_data+nrbytes, rip->i_size - nrbytes);
 | 
						|
		rip->i_size -= nrbytes;
 | 
						|
	}
 | 
						|
 | 
						|
	if (rw_flag == READING) rip->i_update |= ATIME;
 | 
						|
	if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
 | 
						|
  }
 | 
						|
 | 
						|
  fs_m_out->m_fs_vfs_readwrite.nbytes = cum_io;
 | 
						|
  fs_m_out->m_fs_vfs_readwrite.seek_pos = rip->i_size;
 | 
						|
 | 
						|
  put_inode(rip);
 | 
						|
  put_block(rip->i_dev, rip->i_num);
 | 
						|
 | 
						|
  return(r);
 | 
						|
}
 |