diff --git a/defs.h b/defs.h index 91e0602..566380d 100644 --- a/defs.h +++ b/defs.h @@ -114,9 +114,9 @@ void ilock(struct inode *ip); void iunlock(struct inode *ip); void idecref(struct inode *ip); void iput(struct inode *ip); -struct inode * namei(char *path); +struct inode * namei(char *path, uint *); 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); +struct inode *mknod(char *, short, short, short); int unlink(char *cp); void iupdate (struct inode *ip); diff --git a/fs.c b/fs.c index 0f4ed79..0c00c6f 100644 --- a/fs.c +++ b/fs.c @@ -189,6 +189,7 @@ ialloc(uint dev, short type) static void ifree(struct inode *ip) { + cprintf("ifree: %d\n", ip->inum); ip->type = 0; iupdate(ip); } @@ -340,7 +341,7 @@ writei(struct inode *ip, char *addr, uint off, uint n) } struct inode * -namei(char *path) +namei(char *path, uint *ret_pinum) { struct inode *dp; char *cp = path; @@ -349,17 +350,24 @@ namei(char *path) struct dirent *ep; int i; unsigned ninum; + unsigned pinum; dp = iget(rootdev, 1); + pinum = dp->inum; while(*cp == '/') cp++; while(1){ - if(*cp == '\0') + if(*cp == '\0') { + if (ret_pinum) + *ret_pinum = pinum; return dp; + } if(dp->type != T_DIR){ + if (ret_pinum) + *ret_pinum = pinum; iput(dp); return 0; } @@ -384,10 +392,13 @@ namei(char *path) brelse(bp); } iput(dp); + if (ret_pinum) + *ret_pinum = pinum; return 0; found: dev = dp->dev; + pinum = dp->inum; iput(dp); dp = iget(dev, ninum); while(*cp == '/') @@ -396,19 +407,28 @@ namei(char *path) } struct inode * -mknod(struct inode *dp, char *cp, short type, short major, short minor) +mknod(char *cp, short type, short major, short minor) { - struct inode *ip; + struct inode *ip, *dp; struct dirent *ep = 0; int off; int i; struct buf *bp = 0; + uint pinum = 0; - cprintf("mknod: dir %d %s %d %d %d\n", - dp->inum, cp, type, major, minor); + cprintf("mknod: %s %d %d %d\n", cp, type, major, minor); + if ((ip = namei(cp, &pinum)) != 0) { + iput(ip); + return 0; + } + cprintf("mknod: pinum = %d\n", pinum); + dp = iget(rootdev, pinum); ip = ialloc(dp->dev, type); - if (ip == 0) return 0; + if (ip == 0) { + iput(dp); + return 0; + } ip->major = major; ip->minor = minor; ip->size = 0; @@ -434,10 +454,9 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor) for(i = 0; i < DIRSIZ && cp[i]; i++) ep->name[i] = cp[i]; bwrite (dp->dev, bp, bmap(dp, off/BSIZE)); // write directory block brelse(bp); - dp->size += sizeof(struct dirent); // update directory inode iupdate (dp); - + iput(dp); return ip; } @@ -449,8 +468,9 @@ unlink(char *cp) struct dirent *ep = 0; int off; struct buf *bp = 0; + uint pinum; - if ((ip = namei(cp)) == 0) { + if ((ip = namei(cp, &pinum)) == 0) { cprintf("file to be unlinked doesn't exist\n"); return -1; } @@ -475,7 +495,7 @@ unlink(char *cp) iupdate(ip); ifree(ip); // is this the right order? - dp = iget(rootdev, 1); // XXX should parse name + dp = iget(rootdev, pinum); for(off = 0; off < dp->size; off += BSIZE) { bp = bread(dp->dev, bmap(dp, off / BSIZE)); for(ep = (struct dirent *) bp->data; diff --git a/syscall.c b/syscall.c index 324926e..dfd86c4 100644 --- a/syscall.c +++ b/syscall.c @@ -253,20 +253,17 @@ sys_open(void) uint arg0, arg1; int ufd; struct fd *fd; - struct inode *dp; int l; if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0) return -1; if((l = checkstring(arg0)) < 0) return -1; - if((ip = namei(cp->mem + arg0)) == 0) { + if((ip = namei(cp->mem + arg0, 0)) == 0) { if (arg1 & O_CREATE) { if (l >= DIRSIZ) return -1; - dp = iget(rootdev, 1); // XXX should parse name - ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0); - iput(dp); + ip = mknod (cp->mem + arg0, T_FILE, 0, 0); if (ip == 0) return -1; } else return -1; } @@ -303,7 +300,7 @@ int sys_mknod(void) { struct proc *cp = curproc[cpu()]; - struct inode *dp, *nip; + struct inode *nip; uint arg0, arg1, arg2, arg3; int l; @@ -317,10 +314,7 @@ sys_mknod(void) if(l >= DIRSIZ) return -1; - dp = iget(rootdev, 1); // XXX should parse name - nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2, - (short) arg3); - iput(dp); + nip = mknod (cp->mem + arg0, (short) arg1, (short) arg2, (short) arg3); iput(nip); return (nip == 0) ? -1 : 0; } @@ -357,7 +351,7 @@ sys_exec(void) return -1; if(checkstring(arg0) < 0) return -1; - ip = namei(cp->mem + arg0); + ip = namei(cp->mem + arg0, 0); if(ip == 0) return -1; @@ -495,7 +489,7 @@ sys_block(void) ip->type, ip->nlink, ip->size, ip->addrs[0]); iput(ip); - ip = namei(".././//./../usertests"); + ip = namei(".././//./../usertests", 0); if(ip){ cprintf("namei(usertests): %d %d %d %d %d %d %d %d\n", ip->dev, ip->inum, ip->count, ip->busy, diff --git a/userfs.c b/userfs.c index 8c6121b..046768d 100644 --- a/userfs.c +++ b/userfs.c @@ -5,7 +5,7 @@ // file system tests -char buf[3000]; +char buf[2000]; char *echo_args[] = { "echo", "hello", "goodbye", 0 }; char *cat_args[] = { "cat", "README", 0 }; @@ -14,14 +14,8 @@ main(void) { int fd; int i; - int stdout; + int stdout = 1; - // printf(stdout, "userfs running\n"); - if (mknod ("console", T_DEV, 1, 1) < 0) - puts ("mknod failed\n"); - else - puts ("made a node\n"); - stdout = open("console", O_WRONLY); printf(stdout, "userfs is running\n"); block();