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