summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defs.h1
-rw-r--r--fs.c60
-rw-r--r--ioapic.c2
-rw-r--r--syscall.c36
-rw-r--r--userfs.c7
5 files changed, 73 insertions, 33 deletions
diff --git a/defs.h b/defs.h
index 5e3c1e4..91e0602 100644
--- a/defs.h
+++ b/defs.h
@@ -118,4 +118,5 @@ struct inode * namei(char *path);
int readi(struct inode *ip, char *xdst, uint off, uint n);
int writei(struct inode *ip, char *addr, uint off, uint n);
struct inode *mknod(struct inode *, char *, short, short, short);
+int unlink(char *cp);
void iupdate (struct inode *ip);
diff --git a/fs.c b/fs.c
index cbf417e..0f4ed79 100644
--- a/fs.c
+++ b/fs.c
@@ -187,7 +187,7 @@ ialloc(uint dev, short type)
}
static void
-ifree(uint dev, struct inode *ip)
+ifree(struct inode *ip)
{
ip->type = 0;
iupdate(ip);
@@ -440,3 +440,61 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
return ip;
}
+
+int
+unlink(char *cp)
+{
+ int i;
+ struct inode *ip, *dp;
+ struct dirent *ep = 0;
+ int off;
+ struct buf *bp = 0;
+
+ if ((ip = namei(cp)) == 0) {
+ cprintf("file to be unlinked doesn't exist\n");
+ return -1;
+ }
+
+ ip->nlink--;
+ if (ip->nlink > 0) {
+ iupdate(ip);
+ iput(ip); // is this the right order?
+ return 0;
+ }
+
+ // free inode, its blocks, and remove dir entry
+ for (i = 0; i < NDIRECT; i++) {
+ if (ip->addrs[i] != 0) {
+ bfree(ip->dev, ip->addrs[i]);
+ ip->addrs[i] = 0;
+ }
+ }
+ ip->size = 0;
+ ip->major = 0;
+ ip->minor = 0;
+ iupdate(ip);
+ ifree(ip); // is this the right order?
+
+ dp = iget(rootdev, 1); // XXX should parse name
+ 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 == ip->inum) {
+ goto found;
+ }
+ }
+ brelse(bp);
+ }
+ panic("mknod: XXXX no dir entry free\n");
+
+ found:
+ ep->inum = 0;
+ bwrite (dp->dev, bp, bmap(dp, off/BSIZE)); // write directory block
+ brelse(bp);
+ iput(ip);
+ iupdate (dp);
+ iput(dp);
+ return 0;
+}
diff --git a/ioapic.c b/ioapic.c
index b926863..0bd672a 100644
--- a/ioapic.c
+++ b/ioapic.c
@@ -76,7 +76,7 @@ ioapic_enable (int irq, int cpunum)
ioapic_write(io, IOAPIC_REDTBL_LO(irq), l);
h = ioapic_read(io, IOAPIC_REDTBL_HI(irq));
h &= ~IOART_DEST;
- h |= (cpunum << APIC_ID_SHIFT); // for fun, disk interrupts to cpu 1
+ h |= (cpunum << APIC_ID_SHIFT);
ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);
cprintf("cpu%d: intr %d: lo 0x%x hi 0x%x\n", cpu(), irq, l, h);
}
diff --git a/syscall.c b/syscall.c
index 6ba185e..324926e 100644
--- a/syscall.c
+++ b/syscall.c
@@ -265,10 +265,9 @@ sys_open(void)
if (l >= DIRSIZ)
return -1;
dp = iget(rootdev, 1); // XXX should parse name
- if (dp->type != T_DIR)
- return -1;
- if ((ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0)) == 0)
- return -1;
+ ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0);
+ iput(dp);
+ if (ip == 0) return -1;
} else return -1;
}
if((fd = fd_alloc()) == 0){
@@ -319,45 +318,26 @@ sys_mknod(void)
return -1;
dp = iget(rootdev, 1); // XXX should parse name
- if (dp->type != T_DIR) {
- iput(dp);
- return -1;
- }
-
nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2,
(short) arg3);
-
iput(dp);
-
- if (nip == 0) return -1;
-
iput(nip);
-
- return 0;
+ return (nip == 0) ? -1 : 0;
}
int
sys_unlink(void)
{
struct proc *cp = curproc[cpu()];
- struct inode *ip;
uint arg0;
-
+ int r;
+
if(fetcharg(0, &arg0) < 0)
return -1;
-
if(checkstring(arg0) < 0)
return -1;
-
- ip = namei(cp->mem + arg0);
- ip->nlink--;
- if (ip->nlink <= 0) {
- panic("sys_link: unimplemented\n");
- }
- iupdate(ip);
- iput(ip);
-
- return 0;
+ r = unlink(cp->mem + arg0);
+ return r;
}
int
diff --git a/userfs.c b/userfs.c
index af87561..8c6121b 100644
--- a/userfs.c
+++ b/userfs.c
@@ -5,7 +5,7 @@
// file system tests
-char buf[2000];
+char buf[3000];
char *echo_args[] = { "echo", "hello", "goodbye", 0 };
char *cat_args[] = { "cat", "README", 0 };
@@ -62,13 +62,14 @@ main(void)
} else {
printf(stdout, "error: open doesnotexist failed!\n");
}
- i = read(fd, buf, 10000);
+ i = read(fd, buf, 2000);
if (i == 2000) {
- printf(stdout, "read succeeded\\n");
+ printf(stdout, "read succeeded\n");
} else {
printf(stdout, "read failed\n");
}
close(fd);
+ unlink("doesnotexist");
//exec("echo", echo_args);
printf(stdout, "about to do exec\n");
exec("cat", cat_args);