]> Devi Nivas Git - cs3210-lab0.git/commitdiff
mknod,ialloc,iupdate
authorkaashoek <kaashoek>
Tue, 8 Aug 2006 18:07:37 +0000 (18:07 +0000)
committerkaashoek <kaashoek>
Tue, 8 Aug 2006 18:07:37 +0000 (18:07 +0000)
defs.h
fs.c
fs.h
fsvar.h
syscall.c
syscall.h
user.h
userfs.c
usys.S

diff --git a/defs.h b/defs.h
index 51c4d34ec52f62978db4cefebdf90d6e8dcb0af1..30b803d05b5f850c9048e3ceb6ee68d7a7138f62 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -109,3 +109,4 @@ 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);
+struct inode *mknod(struct inode *, char *, short, short, short);
diff --git a/fs.c b/fs.c
index 0e987c26dd446f5b10efeb8a19a2e58e5e34ac34..67743501d9b7367ee5b1edb7571f40871f08e5e4 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -54,6 +54,8 @@ iget(uint dev, uint inum)
   bp = bread(dev, inum / IPB + 2);
   dip = &((struct dinode *)(bp->data))[inum % IPB];
   nip->type = dip->type;
+  nip->major = dip->major;
+  nip->minor = dip->minor;
   nip->nlink = dip->nlink;
   nip->size = dip->size;
   memmove(nip->addrs, dip->addrs, sizeof(nip->addrs));
@@ -62,6 +64,61 @@ iget(uint dev, uint inum)
   return nip;
 }
 
+// allocate an inode on disk
+struct inode *
+ialloc(uint dev, short type)
+{
+  struct inode *ip;
+  struct dinode *dip = 0;
+  struct superblock *sb;
+  int ninodes;
+  int inum;
+  struct buf *bp;
+
+  bp = bread(dev, 1);
+  sb = (struct superblock *) bp;
+  ninodes = sb->ninodes;
+  brelse(bp);
+  for (inum = 1; inum < ninodes; inum++) {  // loop over inode blocks
+    bp = bread(dev, inum / IPB + 2);
+    dip = &((struct dinode *)(bp->data))[inum % IPB];
+    if (dip->type == 0) {  // a free inode
+      break;
+    }
+    brelse(bp);
+  }
+  if (inum >= ninodes) {
+    cprintf ("ialloc: no inodes left\n");
+    return 0;
+  }
+
+  cprintf ("ialloc: %d\n", inum);
+  dip->type = type;
+  bwrite (dev, bp, inum / IPB + 2);   // mark it allocated on the disk
+  brelse(bp);
+  ip = iget (dev, inum);
+  return ip;
+}
+
+void 
+iupdate (struct inode *ip)
+{
+  struct buf *bp;
+  struct dinode *dip;
+
+  bp = bread(ip->dev, ip->inum / IPB + 2);
+  dip = &((struct dinode *)(bp->data))[ip->inum % IPB];
+  dip->type = ip->type;
+  dip->major = ip->major;
+  dip->minor = ip->minor;
+  dip->nlink = ip->nlink;
+  dip->size = ip->size;
+  bwrite (ip->dev, bp, ip->inum / IPB + 2);   // mark it allocated on the disk
+  brelse(bp); 
+}
+
 void
 ilock(struct inode *ip)
 {
@@ -214,3 +271,41 @@ namei(char *path)
       cp++;
   }
 }
+
+struct inode *
+mknod(struct inode *dp, char *cp, short type, short major, short minor)
+{
+  struct inode *ip;
+  struct dirent *ep = 0;
+  int off;
+  int i;
+  struct buf *bp = 0;
+
+  cprintf("mknod: %s %d %d %d\n", cp, type, major, minor);
+
+  ip = ialloc(dp->dev, type);
+  if (ip == 0) return 0;
+  ip->major = major;
+  ip->minor = minor;
+
+  for(off = 0; off < dp->size; off += 512) {
+    bp = bread(dp->dev, bmap(dp, off / 512));
+    for(ep = (struct dirent *) bp->data;
+       ep < (struct dirent *) (bp->data + 512);
+       ep++){
+      if(ep->inum == 0) {
+       goto found;
+      }
+    }
+    brelse(bp);
+  }
+  panic("mknod: no dir entry free\n");
+
+ found:
+  ep->inum = ip->inum;
+  for(i = 0; i < DIRSIZ && cp[i]; i++) ep->name[i] = cp[i];
+  bwrite (dp->dev, bp, bmap(dp, off/512));   // write directory
+  brelse(bp);
+  iupdate (ip);
+  return ip;
+}
diff --git a/fs.h b/fs.h
index a842e64294f354a73500bc5b2545dc0a5defdab4..48a1c135edcc83998c529d787c1d8b33fa8c3dde 100644 (file)
--- a/fs.h
+++ b/fs.h
@@ -6,18 +6,22 @@ struct superblock{
   int ninodes;
 };
 
-#define NDIRECT 14
+#define NDIRECT 13
 
 // inodes start at the third sector
 // and blocks start at (ninodes * sizeof(dinode) + 511) / 512
 struct dinode {
   short type;
+  short major;
+  short minor;
   short nlink;
   uint size;
   uint addrs[NDIRECT];
 };
+
 #define T_DIR 1
 #define T_FILE 2
+#define T_DEV 3
 
 #define IPB (512 / sizeof(struct dinode))
 
diff --git a/fsvar.h b/fsvar.h
index dba45d524b5fc26f4d607d6a077187c8069bc739..ef678ddc0e09fce250dbf2fedcee94afadfce4b4 100644 (file)
--- a/fsvar.h
+++ b/fsvar.h
@@ -6,6 +6,8 @@ struct inode {
   int count;
   int busy;
   short type;
+  short major;
+  short minor;
   short nlink;
   uint size;
   uint addrs[NDIRECT];
index 29ebee8bf6dc2b9381210c991f81866c7b677390..498078e111d342d283271a5ab7a9676fb82e65fc 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -279,6 +279,41 @@ sys_open(void)
   return ufd;
 }
 
+int
+sys_mknod(void)
+{
+  struct proc *cp = curproc[cpu()];
+  struct inode *dp, *nip;
+  uint arg0, arg1, arg2, arg3;
+  int l;
+
+  if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0 || 
+     fetcharg(2, &arg2) < 0 || fetcharg(3, &arg3) < 0)
+    return -1;
+
+  if((l = checkstring(arg0)) < 0)
+    return -1;
+
+  if(l >= DIRSIZ)
+    return -1;
+
+  dp = iget(rootdev, 1);
+
+  cprintf("root inode type: %d\n", dp->type);
+
+  if (dp->type != T_DIR) 
+    return -1;
+  
+  nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2, 
+                  (short) arg3);
+
+  if (nip == 0) return -1;
+  iput(nip);
+  iput(dp);
+  
+  return 0;
+}
+
 int
 sys_exec(void)
 {
@@ -515,6 +550,9 @@ syscall(void)
   case SYS_open:
     ret = sys_open();
     break;
+  case SYS_mknod:
+    ret = sys_mknod();
+    break;
   default:
     cprintf("unknown sys call %d\n", num);
     // XXX fault
index e894200c9103781143c03a1a3264a92811dec22b..959f0151d191fb86821977e8f06fdf3390716485 100644 (file)
--- a/syscall.h
+++ b/syscall.h
@@ -12,3 +12,4 @@
 #define SYS_cons_puts 12
 #define SYS_exec 13
 #define SYS_open 14
+#define SYS_mknod 15
diff --git a/user.h b/user.h
index 16664cabf9132a6a86996795b2a8d763a7a4098a..cf9881672c64e494bd91adc86642e511352ea1b5 100644 (file)
--- a/user.h
+++ b/user.h
@@ -10,7 +10,7 @@ int block(void);
 int kill(int);
 int panic(char*);
 int cons_puts(char*);
-
+int mknod (char*,short,short,short);
 int puts(char*);
 int puts1(char*);
 char* strcpy(char*, char*);
index c263868e8c087191837988592d548c12662389c7..0b2e9c31ca3419abad3ec58c17d2ffc1ce16f2a9 100644 (file)
--- a/userfs.c
+++ b/userfs.c
@@ -1,4 +1,6 @@
 #include "user.h"
+#include "types.h"
+#include "fs.h"
 
 // file system tests
 
@@ -12,6 +14,12 @@ main(void)
 
   puts("userfs running\n");
   block();
+
+  if (mknod ("console", T_DEV, 1, 1) < 0)
+    puts ("mknod failed\n");
+  else
+    puts ("made a node\n");
+
   fd = open("echo", 0);
   if(fd >= 0){
     puts("open echo ok\n");
diff --git a/usys.S b/usys.S
index 2c3c855d954321af6832c2e5ae8b9920480dfc04..3622f82dafba3d070adffa53efdde52a5a91cd34 100644 (file)
--- a/usys.S
+++ b/usys.S
@@ -22,3 +22,4 @@ STUB(panic)
 STUB(cons_puts)
 STUB(exec)
 STUB(open)
+STUB(mknod)