This commit is contained in:
rtm 2006-08-13 02:12:44 +00:00
parent 05e975511b
commit 9e5970d596
11 changed files with 149 additions and 39 deletions

4
Notes
View file

@ -355,8 +355,6 @@ HMM maybe the variables at the end of struct cpu are being overwritten
OH! recursive interrupts will use up any amount of cpu[].stack! OH! recursive interrupts will use up any amount of cpu[].stack!
underflow and wrecks *previous* cpu's struct underflow and wrecks *previous* cpu's struct
better buffer cache replacement
read/write of open file that's been unlinked
disk scheduling disk scheduling
mkdir mkdir
more than one directory content block more than one directory content block
@ -365,3 +363,5 @@ sh redirection
indirect blocks indirect blocks
two bugs in unlink: don't just return if nlink > 0, two bugs in unlink: don't just return if nlink > 0,
and search for name, not inum and search for name, not inum
is there a create/create race for same file name?
resulting in two entries w/ same name in directory?

1
defs.h
View file

@ -123,3 +123,4 @@ int writei(struct inode *ip, char *addr, uint off, uint n);
struct inode *mknod(char *, short, short, short); struct inode *mknod(char *, short, short, short);
int unlink(char *cp); int unlink(char *cp);
void iupdate (struct inode *ip); void iupdate (struct inode *ip);
int link(char *file1, char *file2);

89
fs.c
View file

@ -439,14 +439,41 @@ namei(char *path, uint *ret_pinum)
} }
} }
void
wdir(struct inode *dp, char *name, uint ino)
{
uint off;
struct buf *bp = 0;
struct dirent *ep = 0;
int i;
for(off = 0; off < dp->size; off += BSIZE) {
bp = bread(dp->dev, bmap(dp, off / BSIZE));
for(ep = (struct dirent *) bp->data;
ep < (struct dirent *) (bp->data + BSIZE);
ep++){
if(ep->inum == 0)
goto found;
}
brelse(bp);
}
panic("mknod: XXXX no dir entry free\n");
found:
ep->inum = ino;
for(i = 0; i < DIRSIZ && name[i]; i++)
ep->name[i] = name[i];
for( ; i < DIRSIZ; i++)
ep->name[i] = '\0';
bwrite (bp, bmap(dp, off/BSIZE)); // write directory block
brelse(bp);
}
struct inode * struct inode *
mknod(char *cp, short type, short major, short minor) mknod(char *cp, short type, short major, short minor)
{ {
struct inode *ip, *dp; struct inode *ip, *dp;
struct dirent *ep = 0;
int off;
int i;
struct buf *bp = 0;
uint pinum = 0; uint pinum = 0;
cprintf("mknod: %s %d %d %d\n", cp, type, major, minor); cprintf("mknod: %s %d %d %d\n", cp, type, major, minor);
@ -469,27 +496,7 @@ mknod(char *cp, short type, short major, short minor)
iupdate (ip); // write new inode to disk iupdate (ip); // write new inode to disk
for(off = 0; off < dp->size; off += BSIZE) { wdir(dp, cp, ip->inum);
bp = bread(dp->dev, bmap(dp, off / BSIZE));
for(ep = (struct dirent *) bp->data;
ep < (struct dirent *) (bp->data + BSIZE);
ep++){
if(ep->inum == 0) {
goto found;
}
}
brelse(bp);
}
panic("mknod: XXXX no dir entry free\n");
found:
ep->inum = ip->inum;
for(i = 0; i < DIRSIZ && cp[i]; i++)
ep->name[i] = cp[i];
for( ; i < DIRSIZ; i++)
ep->name[i] = '\0';
bwrite (bp, bmap(dp, off/BSIZE)); // write directory block
brelse(bp);
iput(dp); iput(dp);
@ -541,3 +548,35 @@ unlink(char *cp)
iput(ip); iput(ip);
return 0; return 0;
} }
int
link(char *name1, char *name2)
{
struct inode *ip, *dp, *xip;
uint pinum = 0;
cprintf("link(%s, %s)\n", name1, name2);
if ((xip = namei(name2, &pinum)) != 0) {
cprintf(" failed %s exists\n", name2);
iput(xip);
return -1;
}
if ((ip = namei(name1, &pinum)) == 0){
cprintf(" failed %s does not exist\n", name1);
return -1;
}
ip->nlink += 1;
iupdate (ip);
dp = iget(rootdev, pinum);
wdir(dp, name2, ip->inum);
iput(dp);
iput(ip);
cprintf(" succeeded\n");
return 0;
}

2
ide.c
View file

@ -52,14 +52,12 @@ ide_init(void)
} }
ioapic_enable (IRQ_IDE, 1); ioapic_enable (IRQ_IDE, 1);
ide_wait_ready(0); ide_wait_ready(0);
cprintf ("cpu%d: ide_init:done\n", cpu());
} }
void void
ide_intr(void) ide_intr(void)
{ {
acquire(&ide_lock); acquire(&ide_lock);
// cprintf("cpu%d: ide_intr\n", cpu());
wakeup(&request[tail]); wakeup(&request[tail]);
release(&ide_lock); release(&ide_lock);
} }

6
main.c
View file

@ -87,8 +87,6 @@ main0(void)
lapic_enableintr(); lapic_enableintr();
// Enable interrupts on this processor. // Enable interrupts on this processor.
cprintf("cpu%d: nlock %d before -- and sti\n",
cpu(), cpus[0].nlock);
cpus[cpu()].nlock--; cpus[cpu()].nlock--;
sti(); sti();
@ -98,7 +96,6 @@ main0(void)
//load_icode(p, _binary_userfs_start, (uint) _binary_userfs_size); //load_icode(p, _binary_userfs_start, (uint) _binary_userfs_size);
load_icode(p, _binary_init_start, (uint) _binary_init_size); load_icode(p, _binary_init_start, (uint) _binary_init_size);
p->state = RUNNABLE; p->state = RUNNABLE;
cprintf("loaded init\n");
scheduler(); scheduler();
} }
@ -123,7 +120,6 @@ mpmain(void)
cpus[cpu()].booted = 1; cpus[cpu()].booted = 1;
// Enable interrupts on this processor. // Enable interrupts on this processor.
cprintf("cpu%d: initial nlock %d\n", cpu(), cpus[cpu()].nlock);
cpus[cpu()].nlock--; cpus[cpu()].nlock--;
sti(); sti();
@ -139,7 +135,6 @@ load_icode(struct proc *p, uchar *binary, uint size)
// Check magic number on binary // Check magic number on binary
elf = (struct elfhdr*) binary; elf = (struct elfhdr*) binary;
cprintf("elf %x magic %x\n", elf, elf->magic);
if (elf->magic != ELF_MAGIC) if (elf->magic != ELF_MAGIC)
panic("load_icode: not an ELF binary"); panic("load_icode: not an ELF binary");
@ -151,7 +146,6 @@ load_icode(struct proc *p, uchar *binary, uint size)
for (i = 0; i < elf->phnum; i++, ph++) { for (i = 0; i < elf->phnum; i++, ph++) {
if (ph->type != ELF_PROG_LOAD) if (ph->type != ELF_PROG_LOAD)
continue; continue;
cprintf("va %x memsz %d\n", ph->va, ph->memsz);
if (ph->va + ph->memsz < ph->va) if (ph->va + ph->memsz < ph->va)
panic("load_icode: overflow in elf header segment"); panic("load_icode: overflow in elf header segment");
if (ph->va + ph->memsz >= p->sz) if (ph->va + ph->memsz >= p->sz)

3
proc.c
View file

@ -140,9 +140,6 @@ scheduler(void)
struct proc *p; struct proc *p;
int i; int i;
cprintf("cpu%d: start scheduler jmpbuf %p\n",
cpu(), &cpus[cpu()].jmpbuf);
if(cpus[cpu()].nlock != 0){ if(cpus[cpu()].nlock != 0){
cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease ); cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease );
panic("holding locks at first entry to scheduler"); panic("holding locks at first entry to scheduler");

View file

@ -303,7 +303,6 @@ sys_unlink(void)
return r; return r;
} }
int int
sys_fstat(void) sys_fstat(void)
{ {
@ -325,6 +324,21 @@ sys_fstat(void)
return r; return r;
} }
int
sys_link(void)
{
struct proc *cp = curproc[cpu()];
uint name1, name2;
int r;
if(fetcharg(0, &name1) < 0 || checkstring(name1) < 0)
return -1;
if(fetcharg(1, &name2) < 0 || checkstring(name2) < 0)
return -1;
r = link(cp->mem + name1, cp->mem + name2);
return r;
}
int int
sys_exec(void) sys_exec(void)
{ {
@ -543,6 +557,9 @@ syscall(void)
case SYS_fstat: case SYS_fstat:
ret = sys_fstat(); ret = sys_fstat();
break; break;
case SYS_link:
ret = sys_link();
break;
default: default:
cprintf("unknown sys call %d\n", num); cprintf("unknown sys call %d\n", num);
// XXX fault // XXX fault

View file

@ -12,4 +12,5 @@
#define SYS_mknod 15 #define SYS_mknod 15
#define SYS_unlink 16 #define SYS_unlink 16
#define SYS_fstat 17 #define SYS_fstat 17
#define SYS_link 18

1
user.h
View file

@ -16,6 +16,7 @@ int mknod (char*,short,short,short);
int unlink (char*); int unlink (char*);
struct stat; struct stat;
int fstat (int fd, struct stat *stat); int fstat (int fd, struct stat *stat);
int link(char *, char *);
int puts(char*); int puts(char*);
char* strcpy(char*, char*); char* strcpy(char*, char*);

View file

@ -344,11 +344,72 @@ unlinkread()
puts("unlinkread ok\n"); puts("unlinkread ok\n");
} }
void
linktest()
{
int fd;
unlink("lf1");
unlink("lf2");
fd = open("lf1", O_CREATE|O_RDWR);
if(fd < 0){
puts("create lf1 failed\n");
exit();
}
if(write(fd, "hello", 5) != 5){
puts("write lf1 failed\n");
exit();
}
close(fd);
if(link("lf1", "lf2") < 0){
puts("link lf1 lf2 failed\n");
exit();
}
unlink("lf1");
if(open("lf1", 0) >= 0){
puts("unlinked lf1 but it is still there!\n");
exit();
}
fd = open("lf2", 0);
if(fd < 0){
puts("open lf2 failed\n");
exit();
}
if(read(fd, buf, sizeof(buf)) != 5){
puts("read lf2 failed\n");
exit();
}
close(fd);
if(link("lf2", "lf2") >= 0){
puts("link lf2 lf2 succeeded! oops\n");
exit();
}
unlink("lf2");
if(link("lf2", "lf1") >= 0){
puts("link non-existant succeeded! oops\n");
exit();
}
if(link(".", "lf1") >= 0){
puts("link . lf1 succeeded! oops\n");
exit();
}
puts("linktest ok\n");
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
puts("usertests starting\n"); puts("usertests starting\n");
linktest();
unlinkread(); unlinkread();
createdelete(); createdelete();
twofiles(); twofiles();

1
usys.S
View file

@ -22,3 +22,4 @@ STUB(open)
STUB(mknod) STUB(mknod)
STUB(unlink) STUB(unlink)
STUB(fstat) STUB(fstat)
STUB(link)