open()
This commit is contained in:
parent
e46fb46fcf
commit
32630628a9
17 changed files with 89 additions and 13 deletions
2
bio.c
2
bio.c
|
@ -8,7 +8,7 @@
|
|||
#include "buf.h"
|
||||
|
||||
struct buf buf[NBUF];
|
||||
struct spinlock buf_table_lock;
|
||||
struct spinlock buf_table_lock = { "buf_table" };
|
||||
|
||||
struct buf *
|
||||
getblk()
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "defs.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
struct spinlock console_lock;
|
||||
struct spinlock console_lock = { "console" };
|
||||
int panicked = 0;
|
||||
int use_console_lock = 0;
|
||||
|
||||
|
|
2
defs.h
2
defs.h
|
@ -99,7 +99,7 @@ void brelse(struct buf *);
|
|||
struct inode * iget(uint dev, uint inum);
|
||||
void ilock(struct inode *ip);
|
||||
void iunlock(struct inode *ip);
|
||||
void iincref(struct inode *ip);
|
||||
void idecref(struct inode *ip);
|
||||
void iput(struct inode *ip);
|
||||
struct inode * namei(char *path);
|
||||
int readi(struct inode *ip, void *xdst, uint off, uint n);
|
||||
|
|
2
fd.c
2
fd.c
|
@ -86,6 +86,8 @@ fd_close(struct fd *fd)
|
|||
if(--fd->ref == 0){
|
||||
if(fd->type == FD_PIPE){
|
||||
pipe_close(fd->pipe, fd->writeable);
|
||||
} else if(fd->type == FD_FILE){
|
||||
idecref(fd->ip);
|
||||
} else {
|
||||
panic("fd_close");
|
||||
}
|
||||
|
|
3
fd.h
3
fd.h
|
@ -1,9 +1,10 @@
|
|||
struct fd {
|
||||
enum { FD_CLOSED, FD_NONE, FD_PIPE } type;
|
||||
enum { FD_CLOSED, FD_NONE, FD_PIPE, FD_FILE } type;
|
||||
int ref; // reference count
|
||||
char readable;
|
||||
char writeable;
|
||||
struct pipe *pipe;
|
||||
struct inode *ip;
|
||||
};
|
||||
|
||||
extern struct fd fds[NFD];
|
||||
|
|
9
fs.c
9
fs.c
|
@ -12,7 +12,7 @@
|
|||
// these are inodes currently in use
|
||||
// an entry is free if count == 0
|
||||
struct inode inode[NINODE];
|
||||
struct spinlock inode_table_lock;
|
||||
struct spinlock inode_table_lock = { "inode_table" };
|
||||
|
||||
uint rootdev = 1;
|
||||
|
||||
|
@ -111,11 +111,14 @@ iput(struct inode *ip)
|
|||
}
|
||||
|
||||
void
|
||||
iincref(struct inode *ip)
|
||||
idecref(struct inode *ip)
|
||||
{
|
||||
acquire(&inode_table_lock);
|
||||
|
||||
ip->count += 1;
|
||||
if(ip->count < 1)
|
||||
panic("idecref");
|
||||
|
||||
ip->count -= 1;
|
||||
|
||||
release(&inode_table_lock);
|
||||
}
|
||||
|
|
2
ide.c
2
ide.c
|
@ -25,7 +25,7 @@ struct ide_request {
|
|||
};
|
||||
struct ide_request request[NREQUEST];
|
||||
int head, tail;
|
||||
struct spinlock ide_lock;
|
||||
struct spinlock ide_lock = { "ide" };
|
||||
|
||||
int disk_channel;
|
||||
|
||||
|
|
2
kalloc.c
2
kalloc.c
|
@ -15,7 +15,7 @@
|
|||
#include "proc.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
struct spinlock kalloc_lock;
|
||||
struct spinlock kalloc_lock = { "kalloc" };
|
||||
|
||||
struct run {
|
||||
struct run *next;
|
||||
|
|
2
main.c
2
main.c
|
@ -95,6 +95,8 @@ mpmain(void)
|
|||
{
|
||||
cprintf("an application processor\n");
|
||||
idtinit(); // CPU's idt
|
||||
if(cpu() == 0)
|
||||
panic("mpmain on cpu 0");
|
||||
lapic_init(cpu());
|
||||
lapic_timerinit();
|
||||
lapic_enableintr();
|
||||
|
|
6
proc.c
6
proc.c
|
@ -7,7 +7,7 @@
|
|||
#include "defs.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
struct spinlock proc_table_lock;
|
||||
struct spinlock proc_table_lock = { "proc_table" };
|
||||
|
||||
struct proc proc[NPROC];
|
||||
struct proc *curproc[NCPU];
|
||||
|
@ -137,8 +137,10 @@ scheduler(void)
|
|||
cprintf("start scheduler on cpu %d jmpbuf %p\n", cpu(), &cpus[cpu()].jmpbuf);
|
||||
cpus[cpu()].lastproc = &proc[0];
|
||||
|
||||
if(cpus[cpu()].nlock != 0)
|
||||
if(cpus[cpu()].nlock != 0){
|
||||
cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease );
|
||||
panic("holding locks at first entry to scheduler");
|
||||
}
|
||||
|
||||
for(;;){
|
||||
// Loop over process table looking for process to run.
|
||||
|
|
2
proc.h
2
proc.h
|
@ -70,6 +70,8 @@ struct cpu {
|
|||
char mpstack[MPSTACK]; // per-cpu start-up stack, only used to get into main()
|
||||
struct proc *lastproc; // last proc scheduled on this cpu (never NULL)
|
||||
int nlock; // # of locks currently held
|
||||
struct spinlock *lastacquire; // xxx debug
|
||||
struct spinlock *lastrelease; // xxx debug
|
||||
};
|
||||
|
||||
extern struct cpu cpus[NCPU];
|
||||
|
|
10
spinlock.c
10
spinlock.c
|
@ -8,7 +8,7 @@
|
|||
|
||||
// Can't call cprintf from inside these routines,
|
||||
// because cprintf uses them itself.
|
||||
#define cprintf dont_use_cprintf
|
||||
//#define cprintf dont_use_cprintf
|
||||
|
||||
extern int use_console_lock;
|
||||
|
||||
|
@ -21,8 +21,12 @@ getcallerpc(void *v)
|
|||
void
|
||||
acquire(struct spinlock * lock)
|
||||
{
|
||||
if(holding(lock))
|
||||
if(holding(lock)){
|
||||
extern use_console_lock;
|
||||
use_console_lock = 0;
|
||||
cprintf("lock %s pc %x\n", lock->name ? lock->name : "", lock->pc);
|
||||
panic("acquire");
|
||||
}
|
||||
|
||||
if(cpus[cpu()].nlock++ == 0)
|
||||
cli();
|
||||
|
@ -31,6 +35,7 @@ acquire(struct spinlock * lock)
|
|||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
lock->pc = getcallerpc(&lock);
|
||||
lock->cpu = cpu();
|
||||
cpus[cpu()].lastacquire = lock;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -39,6 +44,7 @@ release(struct spinlock * lock)
|
|||
if(!holding(lock))
|
||||
panic("release");
|
||||
|
||||
cpus[cpu()].lastrelease = lock;
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
lock->locked = 0;
|
||||
if(--cpus[cpu()].nlock == 0)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
struct spinlock {
|
||||
char *name;
|
||||
uint locked;
|
||||
uint pc;
|
||||
int cpu;
|
||||
|
|
39
syscall.c
39
syscall.c
|
@ -11,6 +11,7 @@
|
|||
#include "fs.h"
|
||||
#include "fsvar.h"
|
||||
#include "elf.h"
|
||||
#include "fd.h"
|
||||
|
||||
/*
|
||||
* User code makes a system call with INT T_SYSCALL.
|
||||
|
@ -243,6 +244,41 @@ sys_cons_puts(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sys_open(void)
|
||||
{
|
||||
struct proc *cp = curproc[cpu()];
|
||||
struct inode *ip;
|
||||
uint arg0, arg1;
|
||||
int ufd;
|
||||
struct fd *fd;
|
||||
|
||||
if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0)
|
||||
return -1;
|
||||
if(checkstring(arg0) < 0)
|
||||
return -1;
|
||||
if((ip = namei(cp->mem + arg0)) == 0)
|
||||
return -1;
|
||||
if((fd = fd_alloc()) == 0){
|
||||
iput(ip);
|
||||
return -1;
|
||||
}
|
||||
if((ufd = fd_ualloc()) < 0){
|
||||
iput(ip);
|
||||
fd_close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
iunlock(ip);
|
||||
fd->type = FD_FILE;
|
||||
fd->readable = 1;
|
||||
fd->writeable = 0;
|
||||
fd->ip = ip;
|
||||
cp->fds[ufd] = fd;
|
||||
|
||||
return ufd;
|
||||
}
|
||||
|
||||
int
|
||||
sys_exec(void)
|
||||
{
|
||||
|
@ -467,6 +503,9 @@ syscall(void)
|
|||
case SYS_exec:
|
||||
ret = sys_exec();
|
||||
break;
|
||||
case SYS_open:
|
||||
ret = sys_open();
|
||||
break;
|
||||
default:
|
||||
cprintf("unknown sys call %d\n", num);
|
||||
// XXX fault
|
||||
|
|
|
@ -11,3 +11,4 @@
|
|||
#define SYS_panic 11
|
||||
#define SYS_cons_puts 12
|
||||
#define SYS_exec 13
|
||||
#define SYS_open 14
|
||||
|
|
16
userfs.c
16
userfs.c
|
@ -8,8 +8,24 @@ char *args[] = { "echo", "hello", "goodbye", 0 };
|
|||
int
|
||||
main(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
puts("userfs running\n");
|
||||
block();
|
||||
fd = open("echo", 0);
|
||||
if(fd >= 0){
|
||||
puts("open echo ok\n");
|
||||
close(fd);
|
||||
} else {
|
||||
puts("open echo failed!\n");
|
||||
}
|
||||
fd = open("doesnotexist", 0);
|
||||
if(fd >= 0){
|
||||
puts("open doesnotexist succeeded!\n");
|
||||
close(fd);
|
||||
} else {
|
||||
puts("open doesnotexist failed\n");
|
||||
}
|
||||
exec("echo", args);
|
||||
return 0;
|
||||
}
|
||||
|
|
1
usys.S
1
usys.S
|
@ -21,3 +21,4 @@ STUB(kill)
|
|||
STUB(panic)
|
||||
STUB(cons_puts)
|
||||
STUB(exec)
|
||||
STUB(open)
|
||||
|
|
Loading…
Reference in a new issue