summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-06-13 10:29:27 -0400
committerRobert Morris <[email protected]>2019-06-13 10:29:27 -0400
commita8305b7318e66eb33e7789072e8b91dffa0e4b93 (patch)
tree080bae6010159b083d86411fcd05438e19ca5515
parent46744c4a13ec21e0818a49f31dbc3ad6ad592eed (diff)
downloadxv6-labs-a8305b7318e66eb33e7789072e8b91dffa0e4b93.tar.gz
xv6-labs-a8305b7318e66eb33e7789072e8b91dffa0e4b93.tar.bz2
xv6-labs-a8305b7318e66eb33e7789072e8b91dffa0e4b93.zip
FD_DEVICE
-rw-r--r--kernel/console.c9
-rw-r--r--kernel/file.c10
-rw-r--r--kernel/file.h16
-rw-r--r--kernel/fs.c13
-rw-r--r--kernel/fs.h4
-rw-r--r--kernel/stat.h6
-rw-r--r--kernel/sysfile.c25
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;
}