diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2019-06-13 10:29:27 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2019-06-13 10:29:27 -0400 | 
| commit | a8305b7318e66eb33e7789072e8b91dffa0e4b93 (patch) | |
| tree | 080bae6010159b083d86411fcd05438e19ca5515 | |
| parent | 46744c4a13ec21e0818a49f31dbc3ad6ad592eed (diff) | |
| download | xv6-labs-a8305b7318e66eb33e7789072e8b91dffa0e4b93.tar.gz xv6-labs-a8305b7318e66eb33e7789072e8b91dffa0e4b93.tar.bz2 xv6-labs-a8305b7318e66eb33e7789072e8b91dffa0e4b93.zip | |
FD_DEVICE
| -rw-r--r-- | kernel/console.c | 9 | ||||
| -rw-r--r-- | kernel/file.c | 10 | ||||
| -rw-r--r-- | kernel/file.h | 16 | ||||
| -rw-r--r-- | kernel/fs.c | 13 | ||||
| -rw-r--r-- | kernel/fs.h | 4 | ||||
| -rw-r--r-- | kernel/stat.h | 6 | ||||
| -rw-r--r-- | kernel/sysfile.c | 25 | 
7 files changed, 41 insertions, 42 deletions
| diff --git a/kernel/console.c b/kernel/console.c index b20d4a9..736d96a 100644 --- a/kernel/console.c +++ b/kernel/console.c @@ -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;  } diff --git a/kernel/file.c b/kernel/file.c index 6f27f22..f330cf1 100644 --- a/kernel/file.c +++ b/kernel/file.c @@ -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 diff --git a/kernel/file.h b/kernel/file.h index f28018f..5cf15a2 100644 --- a/kernel/file.h +++ b/kernel/file.h @@ -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[]; diff --git a/kernel/fs.c b/kernel/fs.c index ebe377a..ebd8f7a 100644 --- a/kernel/fs.c +++ b/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) diff --git a/kernel/fs.h b/kernel/fs.h index bc0805f..139dcc9 100644 --- a/kernel/fs.h +++ b/kernel/fs.h @@ -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 diff --git a/kernel/stat.h b/kernel/stat.h index 8a80933..a498321 100644 --- a/kernel/stat.h +++ b/kernel/stat.h @@ -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 diff --git a/kernel/sysfile.c b/kernel/sysfile.c index 83bb1ed..7788de3 100644 --- a/kernel/sysfile.c +++ b/kernel/sysfile.c @@ -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;    } -  iunlock(ip); -  end_op(); -  f->type = FD_INODE; +  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->off = 0;    f->readable = !(omode & O_WRONLY);    f->writable = (omode & O_WRONLY) || (omode & O_RDWR); + +  iunlock(ip); +  end_op(); +    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;    } | 
