VFS/PFS: remove notion of position in pipes
Because pipes have no file position. VFS maintained (file) offsets into a buffer internal to PFS and stored them in vnodes for simplicity, mixing the responsibilities of filp and vnode objects. With this patch PFS ignores the position field in REQ_READ and REQ_WRITE requests making VFS' job a lot simpler.
This commit is contained in:
		
							parent
							
								
									7c8b3ddfed
								
							
						
					
					
						commit
						3de8d1cf6e
					
				@ -32,23 +32,34 @@ int fs_readwrite(message *fs_m_in, message *fs_m_out)
 | 
				
			|||||||
  /* Get the values from the request message */
 | 
					  /* Get the values from the request message */
 | 
				
			||||||
  rw_flag = (fs_m_in->m_type == REQ_READ ? READING : WRITING);
 | 
					  rw_flag = (fs_m_in->m_type == REQ_READ ? READING : WRITING);
 | 
				
			||||||
  gid = (cp_grant_id_t) fs_m_in->REQ_GRANT;
 | 
					  gid = (cp_grant_id_t) fs_m_in->REQ_GRANT;
 | 
				
			||||||
  position = fs_m_in->REQ_SEEK_POS_LO;
 | 
					 | 
				
			||||||
  nrbytes = (unsigned) fs_m_in->REQ_NBYTES;
 | 
					  nrbytes = (unsigned) fs_m_in->REQ_NBYTES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* We can't read beyond the max file position */
 | 
					  /* We can't read beyond the max file position */
 | 
				
			||||||
  if (nrbytes > MAX_FILE_POS) return(EFBIG);
 | 
					  if (nrbytes > MAX_FILE_POS) return(EFBIG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  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). */
 | 
					 | 
				
			||||||
	  if (position > PIPE_BUF - (signed) nrbytes) return(EFBIG);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Mark inode in use */
 | 
					  /* Mark inode in use */
 | 
				
			||||||
  if ((get_inode(rip->i_dev, rip->i_num)) == NULL) return(err_code);
 | 
					  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 ((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 (position > PIPE_BUF - (signed) nrbytes) {
 | 
				
			||||||
 | 
							put_inode(rip);
 | 
				
			||||||
 | 
							put_block(rip->i_dev, rip->i_num);
 | 
				
			||||||
 | 
							return(EFBIG);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
						position = bp->b_bytes;
 | 
				
			||||||
 | 
						if (nrbytes > rip->i_size - position) {
 | 
				
			||||||
 | 
							/* There aren't that many bytes to read */
 | 
				
			||||||
 | 
							nrbytes = rip->i_size - position;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (rw_flag == READING) {
 | 
					  if (rw_flag == READING) {
 | 
				
			||||||
	/* Copy a chunk from the block buffer to user space. */
 | 
						/* Copy a chunk from the block buffer to user space. */
 | 
				
			||||||
	r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0,
 | 
						r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0,
 | 
				
			||||||
@ -78,10 +89,12 @@ int fs_readwrite(message *fs_m_in, message *fs_m_out)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bp->b_bytes = position;
 | 
					  if (rw_flag == READING)
 | 
				
			||||||
 | 
						bp->b_bytes = position;
 | 
				
			||||||
  if (rw_flag == READING) rip->i_update |= ATIME;
 | 
					  if (rw_flag == READING) rip->i_update |= ATIME;
 | 
				
			||||||
  if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
 | 
					  if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
 | 
				
			||||||
  fs_m_out->RES_NBYTES = (size_t) cum_io;
 | 
					  fs_m_out->RES_NBYTES = (size_t) cum_io;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  put_inode(rip);
 | 
					  put_inode(rip);
 | 
				
			||||||
  put_block(rip->i_dev, rip->i_num);
 | 
					  put_block(rip->i_dev, rip->i_num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -248,8 +248,6 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode)
 | 
				
			|||||||
			r = map_vnode(vp, PFS_PROC_NR);
 | 
								r = map_vnode(vp, PFS_PROC_NR);
 | 
				
			||||||
			if (r == OK) {
 | 
								if (r == OK) {
 | 
				
			||||||
				if (vp->v_ref_count == 1) {
 | 
									if (vp->v_ref_count == 1) {
 | 
				
			||||||
					vp->v_pipe_rd_pos = 0;
 | 
					 | 
				
			||||||
					vp->v_pipe_wr_pos = 0;
 | 
					 | 
				
			||||||
					if (vp->v_size != 0)
 | 
										if (vp->v_size != 0)
 | 
				
			||||||
						r = truncate_vnode(vp, 0);
 | 
											r = truncate_vnode(vp, 0);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
				
			|||||||
@ -108,8 +108,6 @@ int do_pipe()
 | 
				
			|||||||
  vp->v_inode_nr = res.inode_nr;
 | 
					  vp->v_inode_nr = res.inode_nr;
 | 
				
			||||||
  vp->v_mapinode_nr = res.inode_nr;
 | 
					  vp->v_mapinode_nr = res.inode_nr;
 | 
				
			||||||
  vp->v_mode = res.fmode;
 | 
					  vp->v_mode = res.fmode;
 | 
				
			||||||
  vp->v_pipe_rd_pos= 0;
 | 
					 | 
				
			||||||
  vp->v_pipe_wr_pos= 0;
 | 
					 | 
				
			||||||
  vp->v_fs_count = 1;
 | 
					  vp->v_fs_count = 1;
 | 
				
			||||||
  vp->v_mapfs_count = 1;
 | 
					  vp->v_mapfs_count = 1;
 | 
				
			||||||
  vp->v_ref_count = 1;
 | 
					  vp->v_ref_count = 1;
 | 
				
			||||||
@ -175,13 +173,13 @@ endpoint_t map_to_fs_e;
 | 
				
			|||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
 *				pipe_check				     *
 | 
					 *				pipe_check				     *
 | 
				
			||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
int pipe_check(vp, rw_flag, oflags, bytes, position, notouch)
 | 
					int pipe_check(
 | 
				
			||||||
register struct vnode *vp;	/* the inode of the pipe */
 | 
					struct vnode *vp,	/* the inode of the pipe */
 | 
				
			||||||
int rw_flag;			/* READING or WRITING */
 | 
					int rw_flag,		/* READING or WRITING */
 | 
				
			||||||
int oflags;			/* flags set by open or fcntl */
 | 
					int oflags,		/* flags set by open or fcntl */
 | 
				
			||||||
register int bytes;		/* bytes to be read or written (all chunks) */
 | 
					int bytes,		/* bytes to be read or written (all chunks) */
 | 
				
			||||||
u64_t position;			/* current file position */
 | 
					int notouch		/* check only */
 | 
				
			||||||
int notouch;			/* check only */
 | 
					)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
/* Pipes are a little different.  If a process reads from an empty pipe for
 | 
					/* Pipes are a little different.  If a process reads from an empty pipe for
 | 
				
			||||||
 * which a writer still exists, suspend the reader.  If the pipe is empty
 | 
					 * which a writer still exists, suspend the reader.  If the pipe is empty
 | 
				
			||||||
@ -191,13 +189,15 @@ int notouch;			/* check only */
 | 
				
			|||||||
  off_t pos;
 | 
					  off_t pos;
 | 
				
			||||||
  int r = OK;
 | 
					  int r = OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ex64hi(position) != 0)
 | 
					  /* Reads start at the beginning; writes append to pipes */
 | 
				
			||||||
	panic("pipe_check: position too large in pipe");
 | 
					  if (rw_flag == READING)
 | 
				
			||||||
  pos = ex64lo(position);
 | 
						pos = 0;
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
						pos = vp->v_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* If reading, check for empty pipe. */
 | 
					  /* If reading, check for empty pipe. */
 | 
				
			||||||
  if (rw_flag == READING) {
 | 
					  if (rw_flag == READING) {
 | 
				
			||||||
	if (pos >= vp->v_size) {
 | 
						if (vp->v_size == 0) {
 | 
				
			||||||
		/* Process is reading from an empty pipe. */
 | 
							/* Process is reading from an empty pipe. */
 | 
				
			||||||
		if (find_filp(vp, W_BIT) != NULL) {
 | 
							if (find_filp(vp, W_BIT) != NULL) {
 | 
				
			||||||
			/* Writer exists */
 | 
								/* Writer exists */
 | 
				
			||||||
 | 
				
			|||||||
@ -187,7 +187,7 @@ int do_pipe(void);
 | 
				
			|||||||
int map_vnode(struct vnode *vp, endpoint_t fs_e);
 | 
					int map_vnode(struct vnode *vp, endpoint_t fs_e);
 | 
				
			||||||
void unpause(endpoint_t proc_e);
 | 
					void unpause(endpoint_t proc_e);
 | 
				
			||||||
int pipe_check(struct vnode *vp, int rw_flag, int oflags, int bytes,
 | 
					int pipe_check(struct vnode *vp, int rw_flag, int oflags, int bytes,
 | 
				
			||||||
	u64_t position, int notouch);
 | 
						int notouch);
 | 
				
			||||||
void release(struct vnode *vp, int op, int count);
 | 
					void release(struct vnode *vp, int op, int count);
 | 
				
			||||||
void revive(endpoint_t proc_e, int returned);
 | 
					void revive(endpoint_t proc_e, int returned);
 | 
				
			||||||
void suspend(int why);
 | 
					void suspend(int why);
 | 
				
			||||||
 | 
				
			|||||||
@ -264,7 +264,7 @@ size_t req_size;
 | 
				
			|||||||
  int r, oflags, partial_pipe = 0;
 | 
					  int r, oflags, partial_pipe = 0;
 | 
				
			||||||
  size_t size, cum_io, cum_io_incr;
 | 
					  size_t size, cum_io, cum_io_incr;
 | 
				
			||||||
  struct vnode *vp;
 | 
					  struct vnode *vp;
 | 
				
			||||||
  u64_t position, new_pos;
 | 
					  u64_t  position, new_pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Must make sure we're operating on locked filp and vnode */
 | 
					  /* Must make sure we're operating on locked filp and vnode */
 | 
				
			||||||
  assert(tll_locked_by_me(&f->filp_vno->v_lock));
 | 
					  assert(tll_locked_by_me(&f->filp_vno->v_lock));
 | 
				
			||||||
@ -272,12 +272,12 @@ size_t req_size;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  oflags = f->filp_flags;
 | 
					  oflags = f->filp_flags;
 | 
				
			||||||
  vp = f->filp_vno;
 | 
					  vp = f->filp_vno;
 | 
				
			||||||
  position = cvu64((rw_flag == READING) ? vp->v_pipe_rd_pos :
 | 
					  position = cvu64(0);	/* Not actually used */
 | 
				
			||||||
							vp->v_pipe_wr_pos);
 | 
					
 | 
				
			||||||
  /* fp->fp_cum_io_partial is only nonzero when doing partial writes */
 | 
					  /* fp->fp_cum_io_partial is only nonzero when doing partial writes */
 | 
				
			||||||
  cum_io = fp->fp_cum_io_partial;
 | 
					  cum_io = fp->fp_cum_io_partial;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  r = pipe_check(vp, rw_flag, oflags, req_size, position, 0);
 | 
					  r = pipe_check(vp, rw_flag, oflags, req_size, 0);
 | 
				
			||||||
  if (r <= 0) {
 | 
					  if (r <= 0) {
 | 
				
			||||||
	if (r == SUSPEND) pipe_suspend(f, buf, req_size);
 | 
						if (r == SUSPEND) pipe_suspend(f, buf, req_size);
 | 
				
			||||||
	return(r);
 | 
						return(r);
 | 
				
			||||||
@ -287,16 +287,8 @@ size_t req_size;
 | 
				
			|||||||
  if (size < req_size) partial_pipe = 1;
 | 
					  if (size < req_size) partial_pipe = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Truncate read request at size. */
 | 
					  /* Truncate read request at size. */
 | 
				
			||||||
  if((rw_flag == READING) &&
 | 
					  if (rw_flag == READING && size > vp->v_size) {
 | 
				
			||||||
	cmp64ul(add64ul(position, size), vp->v_size) > 0) {
 | 
						size = vp->v_size;
 | 
				
			||||||
	/* Position always should fit in an off_t (LONG_MAX). */
 | 
					 | 
				
			||||||
	off_t pos32;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	assert(cmp64ul(position, LONG_MAX) <= 0);
 | 
					 | 
				
			||||||
	pos32 = cv64ul(position);
 | 
					 | 
				
			||||||
	assert(pos32 >= 0);
 | 
					 | 
				
			||||||
	assert(pos32 <= LONG_MAX);
 | 
					 | 
				
			||||||
	size = vp->v_size - pos32;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (vp->v_mapfs_e == 0)
 | 
					  if (vp->v_mapfs_e == 0)
 | 
				
			||||||
@ -309,7 +301,6 @@ size_t req_size;
 | 
				
			|||||||
	if (ex64hi(new_pos))
 | 
						if (ex64hi(new_pos))
 | 
				
			||||||
		panic("rw_pipe: bad new pos");
 | 
							panic("rw_pipe: bad new pos");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	position = new_pos;
 | 
					 | 
				
			||||||
	cum_io += cum_io_incr;
 | 
						cum_io += cum_io_incr;
 | 
				
			||||||
	buf += cum_io_incr;
 | 
						buf += cum_io_incr;
 | 
				
			||||||
	req_size -= cum_io_incr;
 | 
						req_size -= cum_io_incr;
 | 
				
			||||||
@ -317,27 +308,19 @@ size_t req_size;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* On write, update file size and access time. */
 | 
					  /* On write, update file size and access time. */
 | 
				
			||||||
  if (rw_flag == WRITING) {
 | 
					  if (rw_flag == WRITING) {
 | 
				
			||||||
	if (cmp64ul(position, vp->v_size) > 0) {
 | 
						if (cmp64ul(new_pos, vp->v_size) > 0) {
 | 
				
			||||||
		if (ex64hi(position) != 0) {
 | 
							if (ex64hi(new_pos) != 0) {
 | 
				
			||||||
			panic("read_write: file size too big for v_size");
 | 
								panic("read_write: file size too big for v_size");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		vp->v_size = ex64lo(position);
 | 
							vp->v_size = ex64lo(new_pos);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
	if (cmp64ul(position, vp->v_size) >= 0) {
 | 
						if (cmp64ul(new_pos, vp->v_size) >= 0) {
 | 
				
			||||||
		/* Reset pipe pointers */
 | 
							/* Pipe emtpy; reset size */
 | 
				
			||||||
		vp->v_size = 0;
 | 
							vp->v_size = 0;
 | 
				
			||||||
		vp->v_pipe_rd_pos= 0;
 | 
					 | 
				
			||||||
		vp->v_pipe_wr_pos= 0;
 | 
					 | 
				
			||||||
		position = cvu64(0);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (rw_flag == READING)
 | 
					 | 
				
			||||||
	vp->v_pipe_rd_pos= cv64ul(position);
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
	vp->v_pipe_wr_pos= cv64ul(position);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (r == OK) {
 | 
					  if (r == OK) {
 | 
				
			||||||
	if (partial_pipe) {
 | 
						if (partial_pipe) {
 | 
				
			||||||
		/* partial write on pipe with */
 | 
							/* partial write on pipe with */
 | 
				
			||||||
 | 
				
			|||||||
@ -451,7 +451,8 @@ static int select_request_pipe(struct filp *f, int *ops, int block)
 | 
				
			|||||||
  orig_ops = *ops;
 | 
					  orig_ops = *ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((*ops & (SEL_RD|SEL_ERR))) {
 | 
					  if ((*ops & (SEL_RD|SEL_ERR))) {
 | 
				
			||||||
	err = pipe_check(f->filp_vno, READING, 0, 1, f->filp_pos, 1);
 | 
						/* Check if we can read 1 byte */
 | 
				
			||||||
 | 
						err = pipe_check(f->filp_vno, READING, 0, 1, 1 /* Check only */);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (err != SUSPEND)
 | 
						if (err != SUSPEND)
 | 
				
			||||||
		r |= SEL_RD;
 | 
							r |= SEL_RD;
 | 
				
			||||||
@ -466,7 +467,8 @@ static int select_request_pipe(struct filp *f, int *ops, int block)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((*ops & (SEL_WR|SEL_ERR))) {
 | 
					  if ((*ops & (SEL_WR|SEL_ERR))) {
 | 
				
			||||||
	err = pipe_check(f->filp_vno, WRITING, 0, 1, f->filp_pos, 1);
 | 
						/* Check if we can write 1 byte */
 | 
				
			||||||
 | 
						err = pipe_check(f->filp_vno, WRITING, 0, 1, 1 /* Check only */);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (err != SUSPEND)
 | 
						if (err != SUSPEND)
 | 
				
			||||||
		r |= SEL_WR;
 | 
							r |= SEL_WR;
 | 
				
			||||||
 | 
				
			|||||||
@ -16,8 +16,6 @@ EXTERN struct vnode {
 | 
				
			|||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
  int v_ref_check;		/* for consistency checks */
 | 
					  int v_ref_check;		/* for consistency checks */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  off_t v_pipe_rd_pos;
 | 
					 | 
				
			||||||
  off_t v_pipe_wr_pos;
 | 
					 | 
				
			||||||
  endpoint_t v_bfs_e;		/* endpoint number for the FS proces in case
 | 
					  endpoint_t v_bfs_e;		/* endpoint number for the FS proces in case
 | 
				
			||||||
				   of a block special file */
 | 
									   of a block special file */
 | 
				
			||||||
  dev_t v_dev;                  /* device number on which the corresponding
 | 
					  dev_t v_dev;                  /* device number on which the corresponding
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user