From 0633b9715e106ac97fafcf3a68c06da1f0cf873a Mon Sep 17 00:00:00 2001
From: kaashoek <kaashoek>
Date: Sat, 12 Aug 2006 01:25:45 +0000
Subject: [PATCH] unlink,mknod,create with multi-component pathnames should
 work now remove console init code from userfs

---
 defs.h    |  4 ++--
 fs.c      | 42 +++++++++++++++++++++++++++++++-----------
 syscall.c | 18 ++++++------------
 userfs.c  | 10 ++--------
 4 files changed, 41 insertions(+), 33 deletions(-)

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();
-- 
GitLab