VFS, FSes: add REQ_PEEK request type
REQ_PEEK behaves just like REQ_READ except that it does not copy data anywhere, just obtains the blocks from the FS into the cache. To be used by the future mmap implementation. Change-Id: I1b56de304f0a7152b69a72c8962d04258adb44f9
This commit is contained in:
		
							parent
							
								
									1ba514e19c
								
							
						
					
					
						commit
						a9f55a2e46
					
				@ -72,6 +72,7 @@
 | 
				
			|||||||
#define BYTE            0377	/* mask for 8 bits */
 | 
					#define BYTE            0377	/* mask for 8 bits */
 | 
				
			||||||
#define READING            0	/* copy data to user */
 | 
					#define READING            0	/* copy data to user */
 | 
				
			||||||
#define WRITING            1	/* copy data from user */
 | 
					#define WRITING            1	/* copy data from user */
 | 
				
			||||||
 | 
					#define PEEKING            2	/* retrieve FS data without copying */
 | 
				
			||||||
#define HAVE_SCATTERED_IO  1	/* scattered I/O is now standard */
 | 
					#define HAVE_SCATTERED_IO  1	/* scattered I/O is now standard */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Memory is allocated in clicks. */
 | 
					/* Memory is allocated in clicks. */
 | 
				
			||||||
 | 
				
			|||||||
@ -114,8 +114,9 @@ typedef struct {
 | 
				
			|||||||
#define REQ_RDLINK	(VFS_BASE + 30)
 | 
					#define REQ_RDLINK	(VFS_BASE + 30)
 | 
				
			||||||
#define REQ_GETDENTS	(VFS_BASE + 31)
 | 
					#define REQ_GETDENTS	(VFS_BASE + 31)
 | 
				
			||||||
#define REQ_STATVFS	(VFS_BASE + 32)
 | 
					#define REQ_STATVFS	(VFS_BASE + 32)
 | 
				
			||||||
 | 
					#define REQ_PEEK	(VFS_BASE + 33)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NREQS			    33
 | 
					#define NREQS			    34
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IS_VFS_RQ(type) (((type) & ~0xff) == VFS_BASE)
 | 
					#define IS_VFS_RQ(type) (((type) & ~0xff) == VFS_BASE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -41,6 +41,7 @@ int (*call_vec[])(void) = {
 | 
				
			|||||||
	no_sys,		/* 30 rdlink		*/
 | 
						no_sys,		/* 30 rdlink		*/
 | 
				
			||||||
	do_getdents,	/* 31 getdents		*/
 | 
						do_getdents,	/* 31 getdents		*/
 | 
				
			||||||
	do_statvfs,	/* 32 statvfs		*/
 | 
						do_statvfs,	/* 32 statvfs		*/
 | 
				
			||||||
 | 
						no_sys,		/* 33 peek		*/
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This should not fail with "array size is negative": */
 | 
					/* This should not fail with "array size is negative": */
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,7 @@ int (*fs_call_vec[])(void) = {
 | 
				
			|||||||
	fs_rdlink,	/* 30	rdlink		*/
 | 
						fs_rdlink,	/* 30	rdlink		*/
 | 
				
			||||||
	fs_getdents,	/* 31	getdents	*/
 | 
						fs_getdents,	/* 31	getdents	*/
 | 
				
			||||||
	fs_statvfs,	/* 32	statvfs		*/
 | 
						fs_statvfs,	/* 32	statvfs		*/
 | 
				
			||||||
 | 
						no_sys,		/* 33   peek            */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This should not fail with "array size is negative": */
 | 
					/* This should not fail with "array size is negative": */
 | 
				
			||||||
 | 
				
			|||||||
@ -60,8 +60,13 @@ int fs_readwrite(void)
 | 
				
			|||||||
	if (f_size < 0) f_size = MAX_FILE_POS;
 | 
						if (f_size < 0) f_size = MAX_FILE_POS;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 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);
 | 
				
			||||||
 | 
					  switch(fs_m_in.m_type) {
 | 
				
			||||||
 | 
					       case REQ_READ: rw_flag = READING; break;
 | 
				
			||||||
 | 
					       case REQ_WRITE: rw_flag = WRITING; break;
 | 
				
			||||||
 | 
					       case REQ_PEEK: rw_flag = PEEKING; break;
 | 
				
			||||||
 | 
					       default: panic("odd request");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
 | 
					  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
 | 
				
			||||||
  position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
 | 
					  position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
 | 
				
			||||||
  nrbytes = (size_t) fs_m_in.REQ_NBYTES;
 | 
					  nrbytes = (size_t) fs_m_in.REQ_NBYTES;
 | 
				
			||||||
@ -206,7 +211,7 @@ u64_t position;                 /* position within file to read or write */
 | 
				
			|||||||
unsigned off;                   /* off within the current block */
 | 
					unsigned off;                   /* off within the current block */
 | 
				
			||||||
unsigned int chunk;             /* number of bytes to read or write */
 | 
					unsigned int chunk;             /* number of bytes to read or write */
 | 
				
			||||||
unsigned left;                  /* max number of bytes wanted after position */
 | 
					unsigned left;                  /* max number of bytes wanted after position */
 | 
				
			||||||
int rw_flag;                    /* READING or WRITING */
 | 
					int rw_flag;                    /* READING, WRITING or PEEKING */
 | 
				
			||||||
cp_grant_id_t gid;              /* grant */
 | 
					cp_grant_id_t gid;              /* grant */
 | 
				
			||||||
unsigned buf_off;               /* offset in grant */
 | 
					unsigned buf_off;               /* offset in grant */
 | 
				
			||||||
unsigned int block_size;        /* block size of FS operating on */
 | 
					unsigned int block_size;        /* block size of FS operating on */
 | 
				
			||||||
@ -214,12 +219,18 @@ int *completed;                 /* number of bytes copied */
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
/* Read or write (part of) a block. */
 | 
					/* Read or write (part of) a block. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  register struct buf *bp;
 | 
					  register struct buf *bp = NULL;
 | 
				
			||||||
  register int r = OK;
 | 
					  register int r = OK;
 | 
				
			||||||
  int n, block_spec;
 | 
					  int n, block_spec;
 | 
				
			||||||
  block_t b;
 | 
					  block_t b;
 | 
				
			||||||
  dev_t dev;
 | 
					  dev_t dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* rw_flag:
 | 
				
			||||||
 | 
					   *   READING: read from FS, copy to user
 | 
				
			||||||
 | 
					   *   WRITING: copy from user, write to FS
 | 
				
			||||||
 | 
					   *   PEEKING: try to get all the blocks into the cache, no copying
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  *completed = 0;
 | 
					  *completed = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
 | 
					  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
 | 
				
			||||||
@ -244,11 +255,13 @@ int *completed;                 /* number of bytes copied */
 | 
				
			|||||||
               }
 | 
					               }
 | 
				
			||||||
               return r;
 | 
					               return r;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Writing to a nonexistent block. Create and enter in inode.*/
 | 
					               /* Writing to or peeking a nonexistent block.
 | 
				
			||||||
 | 
					                * Create and enter in inode.
 | 
				
			||||||
 | 
					                */
 | 
				
			||||||
		if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL)
 | 
							if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL)
 | 
				
			||||||
			return(err_code);
 | 
								return(err_code);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
  } else if (rw_flag == READING) {
 | 
					  } else if (rw_flag == READING || rw_flag == PEEKING) {
 | 
				
			||||||
	/* Read and read ahead if convenient. */
 | 
						/* Read and read ahead if convenient. */
 | 
				
			||||||
	bp = rahead(rip, b, position, left);
 | 
						bp = rahead(rip, b, position, left);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
@ -275,7 +288,7 @@ int *completed;                 /* number of bytes copied */
 | 
				
			|||||||
	/* 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) buf_off,
 | 
						r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) buf_off,
 | 
				
			||||||
			   (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
								   (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
				
			||||||
  } else {
 | 
					  } else if(rw_flag == WRITING) {
 | 
				
			||||||
	/* Copy a chunk from user space to the block buffer. */
 | 
						/* Copy a chunk from user space to the block buffer. */
 | 
				
			||||||
	r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) buf_off,
 | 
						r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) buf_off,
 | 
				
			||||||
			     (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
								     (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
				
			||||||
 | 
				
			|||||||
@ -46,4 +46,5 @@ int (*fs_call_vec[])(void) = {
 | 
				
			|||||||
    fs_rdlink,          /* 30  */
 | 
					    fs_rdlink,          /* 30  */
 | 
				
			||||||
    fs_getdents,        /* 31  */
 | 
					    fs_getdents,        /* 31  */
 | 
				
			||||||
    fs_statvfs,		/* 32  */
 | 
					    fs_statvfs,		/* 32  */
 | 
				
			||||||
 | 
					    fs_readwrite,       /* 33  */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -50,7 +50,7 @@ int fs_bread(void);
 | 
				
			|||||||
int fs_getdents(void);
 | 
					int fs_getdents(void);
 | 
				
			||||||
int read_chunk(struct dir_record *rip, u64_t position, unsigned off, int
 | 
					int read_chunk(struct dir_record *rip, u64_t position, unsigned off, int
 | 
				
			||||||
	chunk, unsigned left, cp_grant_id_t gid, unsigned buf_off, int
 | 
						chunk, unsigned left, cp_grant_id_t gid, unsigned buf_off, int
 | 
				
			||||||
	block_size, int *completed);
 | 
						block_size, int *completed, int rw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* stadir.c */
 | 
					/* stadir.c */
 | 
				
			||||||
int fs_stat(void);
 | 
					int fs_stat(void);
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,13 @@ int fs_read(void) {
 | 
				
			|||||||
  unsigned int off, cum_io;
 | 
					  unsigned int off, cum_io;
 | 
				
			||||||
  int completed;
 | 
					  int completed;
 | 
				
			||||||
  struct dir_record *dir;
 | 
					  struct dir_record *dir;
 | 
				
			||||||
 | 
					  int rw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch(fs_m_in.m_type) {
 | 
				
			||||||
 | 
					  	case REQ_READ: rw = READING;
 | 
				
			||||||
 | 
						case REQ_PEEK: rw = PEEKING;
 | 
				
			||||||
 | 
						default: panic("odd m_type");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  r = OK;
 | 
					  r = OK;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@ -48,7 +55,7 @@ int fs_read(void) {
 | 
				
			|||||||
      
 | 
					      
 | 
				
			||||||
	/* Read or write 'chunk' bytes. */
 | 
						/* Read or write 'chunk' bytes. */
 | 
				
			||||||
	r = read_chunk(dir, cvul64(position), off, chunk, (unsigned) nrbytes, 
 | 
						r = read_chunk(dir, cvul64(position), off, chunk, (unsigned) nrbytes, 
 | 
				
			||||||
		       gid, cum_io, block_size, &completed);
 | 
							       gid, cum_io, block_size, &completed, rw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (r != OK) break;	/* EOF reached */
 | 
						if (r != OK) break;	/* EOF reached */
 | 
				
			||||||
	if (rdwt_err < 0) break;
 | 
						if (rdwt_err < 0) break;
 | 
				
			||||||
@ -106,7 +113,7 @@ int fs_bread(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Read 'chunk' bytes. */
 | 
						/* Read 'chunk' bytes. */
 | 
				
			||||||
    r = read_chunk(dir, position, off, chunk, (unsigned) nrbytes, 
 | 
					    r = read_chunk(dir, position, off, chunk, (unsigned) nrbytes, 
 | 
				
			||||||
		   gid, cum_io, block_size, &completed);
 | 
							   gid, cum_io, block_size, &completed, READING);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (r != OK) break;	/* EOF reached */
 | 
					    if (r != OK) break;	/* EOF reached */
 | 
				
			||||||
    if (rdwt_err < 0) break;
 | 
					    if (rdwt_err < 0) break;
 | 
				
			||||||
@ -280,7 +287,7 @@ int fs_getdents(void) {
 | 
				
			|||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
 *				read_chunk				     *
 | 
					 *				read_chunk				     *
 | 
				
			||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
int read_chunk(dir, position, off, chunk, left, gid, buf_off, block_size, completed)
 | 
					int read_chunk(dir, position, off, chunk, left, gid, buf_off, block_size, completed, rw)
 | 
				
			||||||
register struct dir_record *dir;/* pointer to inode for file to be rd/wr */
 | 
					register struct dir_record *dir;/* pointer to inode for file to be rd/wr */
 | 
				
			||||||
u64_t position;			/* position within file to read or write */
 | 
					u64_t position;			/* position within file to read or write */
 | 
				
			||||||
unsigned off;			/* off within the current block */
 | 
					unsigned off;			/* off within the current block */
 | 
				
			||||||
@ -290,6 +297,7 @@ cp_grant_id_t gid;		/* grant */
 | 
				
			|||||||
unsigned buf_off;		/* offset in grant */
 | 
					unsigned buf_off;		/* offset in grant */
 | 
				
			||||||
int block_size;			/* block size of FS operating on */
 | 
					int block_size;			/* block size of FS operating on */
 | 
				
			||||||
int *completed;			/* number of bytes copied */
 | 
					int *completed;			/* number of bytes copied */
 | 
				
			||||||
 | 
					int rw;				/* READING or PEEKING */
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  register struct buf *bp;
 | 
					  register struct buf *bp;
 | 
				
			||||||
@ -325,8 +333,10 @@ int *completed;			/* number of bytes copied */
 | 
				
			|||||||
    panic("bp not valid in rw_chunk; this can't happen");
 | 
					    panic("bp not valid in rw_chunk; this can't happen");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  r = sys_safecopyto(VFS_PROC_NR, gid, buf_off,
 | 
					  if(rw == READING) {
 | 
				
			||||||
 | 
					 	 r = sys_safecopyto(VFS_PROC_NR, gid, buf_off,
 | 
				
			||||||
		     (vir_bytes) (b_data(bp)+off), (phys_bytes) chunk);
 | 
							     (vir_bytes) (b_data(bp)+off), (phys_bytes) chunk);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  put_block(bp);
 | 
					  put_block(bp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -41,4 +41,5 @@ int (*fs_call_vec[])(void) = {
 | 
				
			|||||||
  no_sys,			/* 30: not used */
 | 
					  no_sys,			/* 30: not used */
 | 
				
			||||||
  fs_getdents,			/* 31 */
 | 
					  fs_getdents,			/* 31 */
 | 
				
			||||||
  fs_statvfs,			/* 32 */
 | 
					  fs_statvfs,			/* 32 */
 | 
				
			||||||
 | 
					  fs_read			/* 33 */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -53,7 +53,12 @@ int fs_readwrite(void)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 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);
 | 
					  switch(fs_m_in.m_type) {
 | 
				
			||||||
 | 
					  	case REQ_READ: rw_flag = READING; break;
 | 
				
			||||||
 | 
					  	case REQ_WRITE: rw_flag = WRITING; break;
 | 
				
			||||||
 | 
					  	case REQ_PEEK: rw_flag = PEEKING; break;
 | 
				
			||||||
 | 
						default: panic("odd request");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
 | 
					  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
 | 
				
			||||||
  position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
 | 
					  position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
 | 
				
			||||||
  nrbytes = (size_t) fs_m_in.REQ_NBYTES;
 | 
					  nrbytes = (size_t) fs_m_in.REQ_NBYTES;
 | 
				
			||||||
@ -215,7 +220,7 @@ u64_t position;			/* position within file to read or write */
 | 
				
			|||||||
unsigned off;			/* off within the current block */
 | 
					unsigned off;			/* off within the current block */
 | 
				
			||||||
unsigned int chunk;		/* number of bytes to read or write */
 | 
					unsigned int chunk;		/* number of bytes to read or write */
 | 
				
			||||||
unsigned left;			/* max number of bytes wanted after position */
 | 
					unsigned left;			/* max number of bytes wanted after position */
 | 
				
			||||||
int rw_flag;			/* READING or WRITING */
 | 
					int rw_flag;			/* READING, WRITING or PEEKING */
 | 
				
			||||||
cp_grant_id_t gid;		/* grant */
 | 
					cp_grant_id_t gid;		/* grant */
 | 
				
			||||||
unsigned buf_off;		/* offset in grant */
 | 
					unsigned buf_off;		/* offset in grant */
 | 
				
			||||||
unsigned int block_size;	/* block size of FS operating on */
 | 
					unsigned int block_size;	/* block size of FS operating on */
 | 
				
			||||||
@ -223,12 +228,18 @@ int *completed;			/* number of bytes copied */
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
/* Read or write (part of) a block. */
 | 
					/* Read or write (part of) a block. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  register struct buf *bp;
 | 
					  register struct buf *bp = NULL;
 | 
				
			||||||
  register int r = OK;
 | 
					  register int r = OK;
 | 
				
			||||||
  int n, block_spec;
 | 
					  int n, block_spec;
 | 
				
			||||||
  block_t b;
 | 
					  block_t b;
 | 
				
			||||||
  dev_t dev;
 | 
					  dev_t dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* rw_flag:
 | 
				
			||||||
 | 
					   *   READING: read from FS, copy to user
 | 
				
			||||||
 | 
					   *   WRITING: copy from user, write to FS
 | 
				
			||||||
 | 
					   *   PEEKING: try to get all the blocks into the cache, no copying
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  *completed = 0;
 | 
					  *completed = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
 | 
					  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
 | 
				
			||||||
@ -253,11 +264,13 @@ int *completed;			/* number of bytes copied */
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return r;
 | 
							return r;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Writing to a nonexistent block. Create and enter in inode.*/
 | 
							/* Writing to or peeking a nonexistent block.
 | 
				
			||||||
 | 
							 * Create and enter in inode.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
		if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL)
 | 
							if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL)
 | 
				
			||||||
			return(err_code);
 | 
								return(err_code);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
  } else if (rw_flag == READING) {
 | 
					  } else if (rw_flag == READING || rw_flag == PEEKING) {
 | 
				
			||||||
	/* Read and read ahead if convenient. */
 | 
						/* Read and read ahead if convenient. */
 | 
				
			||||||
	bp = rahead(rip, b, position, left);
 | 
						bp = rahead(rip, b, position, left);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
@ -272,8 +285,7 @@ int *completed;			/* number of bytes copied */
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* In all cases, bp now points to a valid buffer. */
 | 
					  /* In all cases, bp now points to a valid buffer. */
 | 
				
			||||||
  if (bp == NULL) 
 | 
					  assert(bp);
 | 
				
			||||||
  	panic("bp not valid in rw_chunk; this can't happen");
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (rw_flag == WRITING && chunk != block_size && !block_spec &&
 | 
					  if (rw_flag == WRITING && chunk != block_size && !block_spec &&
 | 
				
			||||||
      (off_t) ex64lo(position) >= rip->i_size && off == 0) {
 | 
					      (off_t) ex64lo(position) >= rip->i_size && off == 0) {
 | 
				
			||||||
@ -284,7 +296,7 @@ int *completed;			/* number of bytes copied */
 | 
				
			|||||||
	/* 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) buf_off,
 | 
						r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) buf_off,
 | 
				
			||||||
			   (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
								   (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
				
			||||||
  } else {
 | 
					  } else if(rw_flag == WRITING) {
 | 
				
			||||||
	/* Copy a chunk from user space to the block buffer. */
 | 
						/* Copy a chunk from user space to the block buffer. */
 | 
				
			||||||
	r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) buf_off,
 | 
						r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) buf_off,
 | 
				
			||||||
			     (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
								     (vir_bytes) (b_data(bp)+off), (size_t) chunk);
 | 
				
			||||||
 | 
				
			|||||||
@ -44,5 +44,6 @@ int (*fs_call_vec[])(void) = {
 | 
				
			|||||||
        fs_rdlink,	    /* 30  */
 | 
					        fs_rdlink,	    /* 30  */
 | 
				
			||||||
        fs_getdents,	    /* 31  */
 | 
					        fs_getdents,	    /* 31  */
 | 
				
			||||||
        fs_statvfs,         /* 32  */
 | 
					        fs_statvfs,         /* 32  */
 | 
				
			||||||
 | 
					        fs_readwrite,       /* 33  */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -210,7 +210,7 @@ int do_getdents(void);
 | 
				
			|||||||
void lock_bsf(void);
 | 
					void lock_bsf(void);
 | 
				
			||||||
void unlock_bsf(void);
 | 
					void unlock_bsf(void);
 | 
				
			||||||
void check_bsf_lock(void);
 | 
					void check_bsf_lock(void);
 | 
				
			||||||
int do_read_write(int rw_flag);
 | 
					int do_read_write_peek(int rw_flag, int fd, char *buf, size_t bytes);
 | 
				
			||||||
int read_write(int rw_flag, struct filp *f, char *buffer, size_t nbytes,
 | 
					int read_write(int rw_flag, struct filp *f, char *buffer, size_t nbytes,
 | 
				
			||||||
	endpoint_t for_e);
 | 
						endpoint_t for_e);
 | 
				
			||||||
int rw_pipe(int rw_flag, endpoint_t usr, struct filp *f, char *buf,
 | 
					int rw_pipe(int rw_flag, endpoint_t usr, struct filp *f, char *buf,
 | 
				
			||||||
 | 
				
			|||||||
@ -31,7 +31,8 @@
 | 
				
			|||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
int do_read()
 | 
					int do_read()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return(do_read_write(READING));
 | 
					  return(do_read_write_peek(READING, job_m_in.fd,
 | 
				
			||||||
 | 
					          job_m_in.buffer, (size_t) job_m_in.nbytes));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -82,24 +83,26 @@ void check_bsf_lock(void)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
 *				do_read_write				     *
 | 
					 *				do_read_write_peek			     *
 | 
				
			||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
int do_read_write(rw_flag)
 | 
					int do_read_write_peek(int rw_flag, int io_fd, char *io_buf, size_t io_nbytes)
 | 
				
			||||||
int rw_flag;			/* READING or WRITING */
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
/* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
 | 
					/* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
 | 
				
			||||||
  struct filp *f;
 | 
					  struct filp *f;
 | 
				
			||||||
  tll_access_t locktype;
 | 
					  tll_access_t locktype;
 | 
				
			||||||
  int r;
 | 
					  int r;
 | 
				
			||||||
 | 
					  int ro = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  scratch(fp).file.fd_nr = job_m_in.fd;
 | 
					  if(rw_flag == WRITING) ro = 0;
 | 
				
			||||||
  scratch(fp).io.io_buffer = job_m_in.buffer;
 | 
					 | 
				
			||||||
  scratch(fp).io.io_nbytes = (size_t) job_m_in.nbytes;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  locktype = (rw_flag == READING) ? VNODE_READ : VNODE_WRITE;
 | 
					  scratch(fp).file.fd_nr = io_fd;
 | 
				
			||||||
 | 
					  scratch(fp).io.io_buffer = io_buf;
 | 
				
			||||||
 | 
					  scratch(fp).io.io_nbytes = io_nbytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  locktype = ro ? VNODE_READ : VNODE_WRITE;
 | 
				
			||||||
  if ((f = get_filp(scratch(fp).file.fd_nr, locktype)) == NULL)
 | 
					  if ((f = get_filp(scratch(fp).file.fd_nr, locktype)) == NULL)
 | 
				
			||||||
	return(err_code);
 | 
						return(err_code);
 | 
				
			||||||
  if (((f->filp_mode) & (rw_flag == READING ? R_BIT : W_BIT)) == 0) {
 | 
					  if (((f->filp_mode) & (ro ? R_BIT : W_BIT)) == 0) {
 | 
				
			||||||
	unlock_filp(f);
 | 
						unlock_filp(f);
 | 
				
			||||||
	return(f->filp_mode == FILP_CLOSED ? EIO : EBADF);
 | 
						return(f->filp_mode == FILP_CLOSED ? EIO : EBADF);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -131,6 +134,8 @@ int read_write(int rw_flag, struct filp *f, char *buf, size_t size,
 | 
				
			|||||||
  r = OK;
 | 
					  r = OK;
 | 
				
			||||||
  cum_io = 0;
 | 
					  cum_io = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(rw_flag == READING || rw_flag == WRITING || rw_flag == PEEKING);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (size > SSIZE_MAX) return(EINVAL);
 | 
					  if (size > SSIZE_MAX) return(EINVAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  op = (rw_flag == READING ? VFS_DEV_READ : VFS_DEV_WRITE);
 | 
					  op = (rw_flag == READING ? VFS_DEV_READ : VFS_DEV_WRITE);
 | 
				
			||||||
@ -139,10 +144,14 @@ int read_write(int rw_flag, struct filp *f, char *buf, size_t size,
 | 
				
			|||||||
	if (fp->fp_cum_io_partial != 0) {
 | 
						if (fp->fp_cum_io_partial != 0) {
 | 
				
			||||||
		panic("VFS: read_write: fp_cum_io_partial not clear");
 | 
							panic("VFS: read_write: fp_cum_io_partial not clear");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if(rw_flag == PEEKING) return EINVAL;
 | 
				
			||||||
	r = rw_pipe(rw_flag, for_e, f, buf, size);
 | 
						r = rw_pipe(rw_flag, for_e, f, buf, size);
 | 
				
			||||||
  } else if (S_ISCHR(vp->v_mode)) {	/* Character special files. */
 | 
					  } else if (S_ISCHR(vp->v_mode)) {	/* Character special files. */
 | 
				
			||||||
	dev_t dev;
 | 
						dev_t dev;
 | 
				
			||||||
	int suspend_reopen;
 | 
						int suspend_reopen;
 | 
				
			||||||
 | 
						int op = (rw_flag == READING ? VFS_DEV_READ : VFS_DEV_WRITE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(rw_flag == PEEKING) return EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (vp->v_sdev == NO_DEV)
 | 
						if (vp->v_sdev == NO_DEV)
 | 
				
			||||||
		panic("VFS: read_write tries to access char dev NO_DEV");
 | 
							panic("VFS: read_write tries to access char dev NO_DEV");
 | 
				
			||||||
@ -161,6 +170,8 @@ int read_write(int rw_flag, struct filp *f, char *buf, size_t size,
 | 
				
			|||||||
	if (vp->v_sdev == NO_DEV)
 | 
						if (vp->v_sdev == NO_DEV)
 | 
				
			||||||
		panic("VFS: read_write tries to access block dev NO_DEV");
 | 
							panic("VFS: read_write tries to access block dev NO_DEV");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(rw_flag == PEEKING) return EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lock_bsf();
 | 
						lock_bsf();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r = req_breadwrite(vp->v_bfs_e, for_e, vp->v_sdev, position, size,
 | 
						r = req_breadwrite(vp->v_bfs_e, for_e, vp->v_sdev, position, size,
 | 
				
			||||||
 | 
				
			|||||||
@ -762,19 +762,43 @@ u64_t *new_posp;
 | 
				
			|||||||
unsigned int *cum_iop;
 | 
					unsigned int *cum_iop;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int r;
 | 
					  int r;
 | 
				
			||||||
  cp_grant_id_t grant_id;
 | 
					  cp_grant_id_t grant_id = -1;
 | 
				
			||||||
  message m;
 | 
					  message m;
 | 
				
			||||||
 | 
					  int type = -1;
 | 
				
			||||||
 | 
					  int grantflag = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* rw_flag:
 | 
				
			||||||
 | 
					   *  READING: do i/o from FS, copy into userspace
 | 
				
			||||||
 | 
					   *  WRITING: do i/o from userspace, copy into FS
 | 
				
			||||||
 | 
					   *  PEEKING: do i/o in FS, just get the blocks into the cache, no copy
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ex64hi(pos) != 0)
 | 
					  if (ex64hi(pos) != 0)
 | 
				
			||||||
	  panic("req_readwrite: pos too large");
 | 
						  panic("req_readwrite: pos too large");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
 | 
					  assert(rw_flag == READING || rw_flag == WRITING || rw_flag == PEEKING);
 | 
				
			||||||
			     (rw_flag==READING ? CPF_WRITE:CPF_READ));
 | 
					
 | 
				
			||||||
  if (grant_id == -1)
 | 
					  switch(rw_flag) {
 | 
				
			||||||
	  panic("req_readwrite: cpf_grant_magic failed");
 | 
					  	case READING:
 | 
				
			||||||
 | 
							type = REQ_READ;
 | 
				
			||||||
 | 
							grantflag = CPF_WRITE;
 | 
				
			||||||
 | 
							/* fallthrough */
 | 
				
			||||||
 | 
						case WRITING:
 | 
				
			||||||
 | 
							if(type < 0) { type = REQ_WRITE; grantflag = CPF_READ; }
 | 
				
			||||||
 | 
					  		grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr,
 | 
				
			||||||
 | 
								num_of_bytes, grantflag);
 | 
				
			||||||
 | 
						  	if (grant_id == -1)
 | 
				
			||||||
 | 
						  		panic("req_readwrite: cpf_grant_magic failed");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PEEKING:
 | 
				
			||||||
 | 
							type = REQ_PEEK;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							panic("odd rw_flag");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Fill in request message */
 | 
					  /* Fill in request message */
 | 
				
			||||||
  m.m_type = rw_flag == READING ? REQ_READ : REQ_WRITE;
 | 
					  m.m_type = type;
 | 
				
			||||||
  m.REQ_INODE_NR = inode_nr;
 | 
					  m.REQ_INODE_NR = inode_nr;
 | 
				
			||||||
  m.REQ_GRANT = grant_id;
 | 
					  m.REQ_GRANT = grant_id;
 | 
				
			||||||
  m.REQ_SEEK_POS_LO = ex64lo(pos);
 | 
					  m.REQ_SEEK_POS_LO = ex64lo(pos);
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "fs.h"
 | 
					#include "fs.h"
 | 
				
			||||||
#include "file.h"
 | 
					#include "file.h"
 | 
				
			||||||
 | 
					#include "param.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
@ -15,5 +16,6 @@
 | 
				
			|||||||
int do_write()
 | 
					int do_write()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
/* Perform the write(fd, buffer, nbytes) system call. */
 | 
					/* Perform the write(fd, buffer, nbytes) system call. */
 | 
				
			||||||
  return(do_read_write(WRITING));
 | 
					  return(do_read_write_peek(WRITING, job_m_in.fd,
 | 
				
			||||||
 | 
					  	job_m_in.buffer, (size_t) job_m_in.nbytes));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user