FD_DEVICE
This commit is contained in:
		
							parent
							
								
									46744c4a13
								
							
						
					
					
						commit
						a8305b7318
					
				
					 7 changed files with 42 additions and 43 deletions
				
			
		| 
						 | 
				
			
			@ -156,20 +156,18 @@ struct {
 | 
			
		|||
#define C(x)  ((x)-'@')  // Contro
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
consoleread(struct inode *ip, int user_dst, uint64 dst, int n)
 | 
			
		||||
consoleread(int user_dst, uint64 dst, int n)
 | 
			
		||||
{
 | 
			
		||||
  uint target;
 | 
			
		||||
  int c;
 | 
			
		||||
  char buf[1];
 | 
			
		||||
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
  target = n;
 | 
			
		||||
  acquire(&cons.lock);
 | 
			
		||||
  while(n > 0){
 | 
			
		||||
    while(input.r == input.w){
 | 
			
		||||
      if(myproc()->killed){
 | 
			
		||||
        release(&cons.lock);
 | 
			
		||||
        ilock(ip);
 | 
			
		||||
        return -1;
 | 
			
		||||
      }
 | 
			
		||||
      sleep(&input.r, &cons.lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -192,17 +190,15 @@ consoleread(struct inode *ip, int user_dst, uint64 dst, int n)
 | 
			
		|||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  release(&cons.lock);
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
 | 
			
		||||
  return target - n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
consolewrite(struct inode *ip, int user_src, uint64 src, int n)
 | 
			
		||||
consolewrite(int user_src, uint64 src, int n)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
  acquire(&cons.lock);
 | 
			
		||||
  for(i = 0; i < n; i++){
 | 
			
		||||
    char c;
 | 
			
		||||
| 
						 | 
				
			
			@ -211,7 +207,6 @@ consolewrite(struct inode *ip, int user_src, uint64 src, int n)
 | 
			
		|||
    consputc(c);
 | 
			
		||||
  }
 | 
			
		||||
  release(&cons.lock);
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
 | 
			
		||||
  return n;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,9 +73,9 @@ fileclose(struct file *f)
 | 
			
		|||
  f->type = FD_NONE;
 | 
			
		||||
  release(&ftable.lock);
 | 
			
		||||
 | 
			
		||||
  if(ff.type == FD_PIPE)
 | 
			
		||||
  if(ff.type == FD_PIPE){
 | 
			
		||||
    pipeclose(ff.pipe, ff.writable);
 | 
			
		||||
  else if(ff.type == FD_INODE){
 | 
			
		||||
  } else if(ff.type == FD_INODE || ff.type == FD_DEVICE){
 | 
			
		||||
    begin_op();
 | 
			
		||||
    iput(ff.ip);
 | 
			
		||||
    end_op();
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ filestat(struct file *f, uint64 addr)
 | 
			
		|||
  struct proc *p = myproc();
 | 
			
		||||
  struct stat st;
 | 
			
		||||
  
 | 
			
		||||
  if(f->type == FD_INODE){
 | 
			
		||||
  if(f->type == FD_INODE || f->type == FD_DEVICE){
 | 
			
		||||
    ilock(f->ip);
 | 
			
		||||
    stati(f->ip, &st);
 | 
			
		||||
    iunlock(f->ip);
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +113,8 @@ fileread(struct file *f, uint64 addr, int n)
 | 
			
		|||
 | 
			
		||||
  if(f->type == FD_PIPE){
 | 
			
		||||
    r = piperead(f->pipe, addr, n);
 | 
			
		||||
  } else if(f->type == FD_DEVICE){
 | 
			
		||||
    r = devsw[f->major].read(1, addr, n);
 | 
			
		||||
  } else if(f->type == FD_INODE){
 | 
			
		||||
    ilock(f->ip);
 | 
			
		||||
    if((r = readi(f->ip, 1, addr, f->off, n)) > 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +140,8 @@ filewrite(struct file *f, uint64 addr, int n)
 | 
			
		|||
 | 
			
		||||
  if(f->type == FD_PIPE){
 | 
			
		||||
    ret = pipewrite(f->pipe, addr, n);
 | 
			
		||||
  } else if(f->type == FD_DEVICE){
 | 
			
		||||
    ret = devsw[f->major].write(1, addr, n);
 | 
			
		||||
  } else if(f->type == FD_INODE){
 | 
			
		||||
    // write a few blocks at a time to avoid exceeding
 | 
			
		||||
    // the maximum log transaction size, including
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,12 @@
 | 
			
		|||
struct file {
 | 
			
		||||
  enum { FD_NONE, FD_PIPE, FD_INODE } type;
 | 
			
		||||
  enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE } type;
 | 
			
		||||
  int ref; // reference count
 | 
			
		||||
  char readable;
 | 
			
		||||
  char writable;
 | 
			
		||||
  struct pipe *pipe;
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
  uint off;
 | 
			
		||||
  struct pipe *pipe; // FD_PIPE
 | 
			
		||||
  struct inode *ip;  // FD_INODE and FD_DEVICE
 | 
			
		||||
  uint off;          // FD_INODE
 | 
			
		||||
  short major;       // FD_DEVICE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,11 +26,10 @@ struct inode {
 | 
			
		|||
  uint addrs[NDIRECT+1];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// table mapping major device number to
 | 
			
		||||
// device functions
 | 
			
		||||
// map major device number to device functions.
 | 
			
		||||
struct devsw {
 | 
			
		||||
  int (*read)(struct inode*, int, uint64, int);
 | 
			
		||||
  int (*write)(struct inode*, int, uint64, int);
 | 
			
		||||
  int (*read)(int, uint64, int);
 | 
			
		||||
  int (*write)(int, uint64, int);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct devsw devsw[];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								kernel/fs.c
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								kernel/fs.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -461,12 +461,6 @@ readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
 | 
			
		|||
  uint tot, m;
 | 
			
		||||
  struct buf *bp;
 | 
			
		||||
 | 
			
		||||
  if(ip->type == T_DEV){
 | 
			
		||||
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read)
 | 
			
		||||
      return -1;
 | 
			
		||||
    return devsw[ip->major].read(ip, user_dst, dst, n);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(off > ip->size || off + n < off)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(off + n > ip->size)
 | 
			
		||||
| 
						 | 
				
			
			@ -493,13 +487,6 @@ writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
 | 
			
		|||
  uint tot, m;
 | 
			
		||||
  struct buf *bp;
 | 
			
		||||
 | 
			
		||||
  if(ip->type == T_DEV){
 | 
			
		||||
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write){
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
    return devsw[ip->major].write(ip, user_src, src, n);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(off > ip->size || off + n < off)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(off + n > MAXFILE*BSIZE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,8 +31,8 @@ struct superblock {
 | 
			
		|||
// On-disk inode structure
 | 
			
		||||
struct dinode {
 | 
			
		||||
  short type;           // File type
 | 
			
		||||
  short major;          // Major device number (T_DEV only)
 | 
			
		||||
  short minor;          // Minor device number (T_DEV only)
 | 
			
		||||
  short major;          // Major device number (T_DEVICE only)
 | 
			
		||||
  short minor;          // Minor device number (T_DEVICE only)
 | 
			
		||||
  short nlink;          // Number of links to inode in file system
 | 
			
		||||
  uint size;            // Size of file (bytes)
 | 
			
		||||
  uint addrs[NDIRECT+1];   // Data block addresses
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
#define T_DIR  1   // Directory
 | 
			
		||||
#define T_FILE 2   // File
 | 
			
		||||
#define T_DEV  3   // Device
 | 
			
		||||
#define T_DIR     1   // Directory
 | 
			
		||||
#define T_FILE    2   // File
 | 
			
		||||
#define T_DEVICE  3   // Device
 | 
			
		||||
 | 
			
		||||
struct stat {
 | 
			
		||||
  short type;  // Type of file
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,7 +253,7 @@ create(char *path, short type, short major, short minor)
 | 
			
		|||
  if((ip = dirlookup(dp, name, &off)) != 0){
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
    ilock(ip);
 | 
			
		||||
    if(type == T_FILE && ip->type == T_FILE)
 | 
			
		||||
    if(type == T_FILE && (ip->type == T_FILE || ip->type == T_DEVICE))
 | 
			
		||||
      return ip;
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -316,6 +316,12 @@ sys_open(void)
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(ip->type == T_DEVICE && (ip->major < 0 || ip->major >= NDEV)){
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    end_op();
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){
 | 
			
		||||
    if(f)
 | 
			
		||||
      fileclose(f);
 | 
			
		||||
| 
						 | 
				
			
			@ -323,14 +329,21 @@ sys_open(void)
 | 
			
		|||
    end_op();
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(ip->type == T_DEVICE){
 | 
			
		||||
    f->type = FD_DEVICE;
 | 
			
		||||
    f->major = ip->major;
 | 
			
		||||
  } else {
 | 
			
		||||
    f->type = FD_INODE;
 | 
			
		||||
    f->off = 0;
 | 
			
		||||
  }
 | 
			
		||||
  f->ip = ip;
 | 
			
		||||
  f->readable = !(omode & O_WRONLY);
 | 
			
		||||
  f->writable = (omode & O_WRONLY) || (omode & O_RDWR);
 | 
			
		||||
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
  end_op();
 | 
			
		||||
 | 
			
		||||
  f->type = FD_INODE;
 | 
			
		||||
  f->ip = ip;
 | 
			
		||||
  f->off = 0;
 | 
			
		||||
  f->readable = !(omode & O_WRONLY);
 | 
			
		||||
  f->writable = (omode & O_WRONLY) || (omode & O_RDWR);
 | 
			
		||||
  return fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -361,7 +374,7 @@ sys_mknod(void)
 | 
			
		|||
  if((argstr(0, path, MAXPATH)) < 0 ||
 | 
			
		||||
     argint(1, &major) < 0 ||
 | 
			
		||||
     argint(2, &minor) < 0 ||
 | 
			
		||||
     (ip = create(path, T_DEV, major, minor)) == 0){
 | 
			
		||||
     (ip = create(path, T_DEVICE, major, minor)) == 0){
 | 
			
		||||
    end_op();
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue