]> Devi Nivas Git - cs3210-lab0.git/commitdiff
printf
authorkaashoek <kaashoek>
Thu, 10 Aug 2006 01:28:57 +0000 (01:28 +0000)
committerkaashoek <kaashoek>
Thu, 10 Aug 2006 01:28:57 +0000 (01:28 +0000)
convert userfs to use printf
bfree
ifree
writei
start on unlink

Makefile
console.c
defs.h
fd.c
fs.c
printf.c [new file with mode: 0644]
syscall.c
syscall.h
user.h
userfs.c
usys.S

index cc83f3e23ecb152cc919f247d8fdd57130e848e5..3f5a3ce7c8b21845925e1c2b7e7981f064ca1d64 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,7 @@ kernel : $(OBJS) bootother.S user1 usertests userfs
 vectors.S : vectors.pl
        perl vectors.pl > vectors.S
 
-ULIB = ulib.o usys.o
+ULIB = ulib.o usys.o printf.o
 
 user1 : user1.o $(ULIB)
        $(LD) -N -e main -Ttext 0 -o user1 user1.o $(ULIB)
index 206a3800a467427bac350358f45195c32c5600d8..eca022573c5ccd288abfa96d736baab767de13bb 100644 (file)
--- a/console.c
+++ b/console.c
@@ -163,10 +163,14 @@ console_write (int minor, void *buf, int n)
   int i;
   uchar *b = buf;
 
+  acquire(&console_lock);
+
   for (i = 0; i < n; i++) {
     cons_putc((int) b[i]);
   }
 
+  release(&console_lock);
+
   return n;
 }
 
diff --git a/defs.h b/defs.h
index 728b2a47259851497787c9d615c815760216b75d..99a31196c5461505c69919f608befcb94fb7595a 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -109,5 +109,5 @@ 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);
-int writei(struct inode *ip, void *addr, uint n);
+int writei(struct inode *ip, void *addr, uint off, uint n);
 struct inode *mknod(struct inode *, char *, short, short, short);
diff --git a/fd.c b/fd.c
index 47b0f204e58397fcc56f15e571a3931030a6e79d..983497fb7d34e8f0470143439edf50d9b0220b5d 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -59,7 +59,13 @@ fd_write(struct fd *fd, char *addr, int n)
   if(fd->type == FD_PIPE){
     return pipe_write(fd->pipe, addr, n);
   } else if (fd->type == FD_FILE) {
-    return writei (fd->ip, addr, n);
+    ilock(fd->ip);
+    int r = writei (fd->ip, addr, fd->off, n);
+    if (r > 0) {
+      fd->off += r;
+    }
+    iunlock(fd->ip);
+    return r;
   } else {
     panic("fd_write");
     return -1;
diff --git a/fs.c b/fs.c
index 63b480c4d88fd04aa33659b049a8096fbeb4c54c..7e5487673dc34d9bfc677aa588dc7fc3ab2239d1 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -23,7 +23,7 @@ balloc(uint dev)
   int b;
   struct buf *bp;
   struct superblock *sb;
-  int bi;
+  int bi = 0;
   int size;
   int ninodes;
   uchar m;
@@ -50,9 +50,32 @@ balloc(uint dev)
   cprintf ("balloc: allocate block %d\n", b);
   bp->data[bi/8] |= 0x1 << (bi % 8);
   bwrite (dev, bp, BBLOCK(b, ninodes));  // mark it allocated on disk
+  brelse(bp);
   return b;
 }
 
+static void 
+bfree(int dev, uint b)
+{
+  struct buf *bp;
+  struct superblock *sb;
+  int bi;
+  int ninodes;
+  uchar m;
+
+  cprintf ("bfree: free block %d\n", b);
+  bp = bread(dev, 1);
+  sb = (struct superblock *) bp->data;
+  ninodes = sb->ninodes;
+  brelse(bp);
+
+  bp = bread(dev, BBLOCK(b, ninodes));
+  bi = b % BPB;
+  m = ~(0x1 << (bi %8));
+  bp->data[bi/8] &= m;
+  bwrite (dev, bp, BBLOCK(b, ninodes));  // mark it free on disk
+  brelse(bp);
+}
 
 // returns an inode with busy set and incremented reference count.
 struct inode *
@@ -102,7 +125,24 @@ iget(uint dev, uint inum)
   return nip;
 }
 
-// allocate an inode on disk
+void 
+iupdate (struct inode *ip)
+{
+  struct buf *bp;
+  struct dinode *dip;
+
+  bp = bread(ip->dev, IBLOCK(ip->inum));
+  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;
+  memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
+  bwrite (ip->dev, bp, IBLOCK(ip->inum));   // mark it allocated on the disk
+  brelse(bp); 
+}
+
 struct inode *
 ialloc(uint dev, short type)
 {
@@ -139,21 +179,11 @@ ialloc(uint dev, short type)
   return ip;
 }
 
-void 
-iupdate (struct inode *ip)
+static void
+ifree(uint dev, struct inode *ip)
 {
-  struct buf *bp;
-  struct dinode *dip;
-
-  bp = bread(ip->dev, IBLOCK(ip->inum));
-  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, IBLOCK(ip->inum));   // mark it allocated on the disk
-  brelse(bp); 
+  ip->type = 0;
+  iupdate(ip);
 }
 
 void
@@ -259,13 +289,44 @@ readi(struct inode *ip, void *xdst, uint off, uint n)
   return target - n;
 }
 
+#define MIN(a, b) ((a < b) ? a : b)
+
 int
-writei(struct inode *ip, void *addr, uint n)
+writei(struct inode *ip, void *addr, uint off, uint n)
 {
   if (ip->type == T_DEV) {
     if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write)
       return -1;
     return devsw[ip->major].d_write (ip->minor, addr, n);
+  } else if (ip->type == T_FILE || ip->type == T_DIR) { // XXX dir here too?
+    struct buf *bp;
+    int r = 0;
+    int m;
+    int lbn;
+    uint b;
+    while (r < n) {
+      lbn = off / BSIZE;
+      if (lbn >= NDIRECT) return r;
+      if (ip->addrs[lbn] == 0) {
+       b = balloc(ip->dev);
+       if (b <= 0) return r;
+       ip->addrs[lbn] = b;
+      }
+      m = MIN(BSIZE - off % BSIZE, n-r);
+      bp = bread(ip->dev, bmap(ip, off / BSIZE));
+      memmove (bp->data + off % BSIZE, addr, m);
+      bwrite (ip->dev, bp, bmap(ip, off/BSIZE));
+      brelse (bp);
+      r += m;
+      off += m;
+    }
+    if (r > 0) {
+      if (off > ip->size) {
+       ip->size = off;
+      }
+      iupdate(ip);
+    }
+    return r;
   } else {
     panic ("writei: unknown type\n");
   }
@@ -358,7 +419,7 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
     }
     brelse(bp);
   }
-  panic("mknod: no dir entry free\n");
+  panic("mknod: XXXX no dir entry free\n");
 
  found:
   ep->inum = ip->inum;
diff --git a/printf.c b/printf.c
new file mode 100644 (file)
index 0000000..0d42236
--- /dev/null
+++ b/printf.c
@@ -0,0 +1,76 @@
+#include "user.h"
+#include "types.h"
+
+static void
+putc(int fd, char c)
+{
+  write (fd, &c, 1);
+}
+
+static void
+printint(int fd, int xx, int base, int sgn)
+{
+  char buf[16];
+  char digits[] = "0123456789ABCDEF";
+  int i = 0, neg = 0;
+  uint x;
+  
+  if(sgn && xx < 0){
+    neg = 1;
+    x = 0 - xx;
+  } else {
+    x = xx;
+  }
+
+  do {
+    buf[i++] = digits[x % base];
+  } while((x /= base) != 0);
+  if(neg)
+    buf[i++] = '-';
+
+  while(--i >= 0)
+    putc(fd, buf[i]);
+}
+
+/*
+ * printf to the stdout. only understands %d, %x, %p, %s.
+ */
+void
+printf(int fd, char *fmt, ...)
+{
+  int i, state = 0, c;
+  uint *ap = (uint *)(void*)&fmt + 1;
+
+  for(i = 0; fmt[i]; i++){
+    c = fmt[i] & 0xff;
+    if(state == 0){
+      if(c == '%'){
+        state = '%';
+      } else {
+        putc(fd, c);
+      }
+    } else if(state == '%'){
+      if(c == 'd'){
+        printint(fd, *ap, 10, 1);
+        ap++;
+      } else if(c == 'x' || c == 'p'){
+        printint(fd, *ap, 16, 0);
+        ap++;
+      } else if(c == 's'){
+        char *s = (char*)*ap;
+        ap++;
+        while(*s != 0){
+          putc(fd, *s);
+          s++;
+        }
+      } else if(c == '%'){
+        putc(fd, c);
+      } else {
+        // Unknown % sequence.  Print it to draw attention.
+        putc(fd, '%');
+        putc(fd, c);
+      }
+      state = 0;
+    }
+  }
+}
index eb7ecf36933eb7e243203cf00df8ce8d60163c09..685fa465e0417d378f22f321df888137b01e409c 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -330,6 +330,30 @@ sys_mknod(void)
   return 0;
 }
 
+int
+sys_unlink(void)
+{
+  struct proc *cp = curproc[cpu()];
+  struct inode *ip;
+  uint arg0;
+
+  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;
+}
+
 int
 sys_exec(void)
 {
@@ -561,6 +585,9 @@ syscall(void)
   case SYS_mknod:
     ret = sys_mknod();
     break;
+  case SYS_unlink:
+    ret = sys_unlink();
+    break;
   default:
     cprintf("unknown sys call %d\n", num);
     // XXX fault
index 959f0151d191fb86821977e8f06fdf3390716485..e6019ad05510c05fb9b3330db4871b5011228f01 100644 (file)
--- a/syscall.h
+++ b/syscall.h
@@ -13,3 +13,5 @@
 #define SYS_exec 13
 #define SYS_open 14
 #define SYS_mknod 15
+#define SYS_unlink 16
+
diff --git a/user.h b/user.h
index d86933845d83b434f14f486bb036f0f96f2b6d90..351b9706554bdff32972eb7c94e44afcc9b851bf 100644 (file)
--- a/user.h
+++ b/user.h
@@ -13,6 +13,9 @@ int cons_puts(char*);
 int exec(char *, char **);
 int open(char *, int);
 int mknod (char*,short,short,short);
+int unlink (char*);
 int puts(char*);
 int puts1(char*);
 char* strcpy(char*, char*);
+void printf(int fd, char *fmt, ...);
+
index 56be4fc5b57470c05d1fd74be3245bd032611f32..516a7c90d66241e11283c10d0d70eb492c09f14f 100644 (file)
--- a/userfs.c
+++ b/userfs.c
@@ -4,7 +4,7 @@
 
 // file system tests
 
-char buf[1024];
+char buf[2000];
 char *echo_args[] = { "echo", "hello", "goodbye", 0 };
 char *cat_args[] = { "cat", "README", 0 };
 
@@ -12,48 +12,64 @@ int
 main(void)
 {
   int fd;
+  int i;
+  int stdout;
 
-  puts("userfs running\n");
-  block();
-
+  //  printf(stdout, "userfs running\n");
   if (mknod ("console", T_DEV, 1, 1) < 0)
     puts ("mknod failed\n");
   else
     puts ("made a node\n");
-  fd = open("console", O_WRONLY);
-  if(fd >= 0){
-    puts("open console ok\n");
-  } else {
-    puts("open console failed!\n");
-  }
-  if (write (fd, "hello\n", 6) != 6) {
-    puts ("write to console failed\n");
-  }
-  close (fd);
+  stdout = open("console", O_WRONLY);
+  printf(stdout, "userfs is running\n");
+
+  block();
 
   fd = open("echo", 0);
   if(fd >= 0){
-    puts("open echo ok\n");
+    printf(stdout, "open echo ok\n");
     close(fd);
   } else {
-    puts("open echo failed!\n");
+    printf(stdout, "open echo failed!\n");
   }
   fd = open("doesnotexist", 0);
   if(fd >= 0){
-    puts("open doesnotexist succeeded!\n");
+    printf(stdout, "open doesnotexist succeeded!\n");
     close(fd);
   } else {
-    puts("open doesnotexist failed\n");
+    printf(stdout, "open doesnotexist failed\n");
   }
-
   fd = open("doesnotexist", O_CREATE|O_RDWR);
   if(fd >= 0){
-    puts("creat doesnotexist succeeded\n");
+    printf(stdout, "creat doesnotexist succeeded\n");
+  } else {
+    printf(stdout, "error: creat doesnotexist failed!\n");
+  }
+  for (i = 0; i < 100; i++) {
+    if (write (fd, "aaaaaaaaaa", 10) != 10) {
+      printf(stdout, "error: write new file failed\n");
+    }
+    if (write (fd, "bbbbbbbbbb", 10) != 10) {
+      printf(stdout, "error: write new file failed\n");
+    }
+  }
+  printf(stdout, "writes done\n");
+  close(fd);
+  fd = open("doesnotexist", O_RDONLY);
+  if(fd >= 0){
+    printf(stdout, "open doesnotexist succeeded\n");
+  } else {
+    printf(stdout, "error: open doesnotexist failed!\n");
+  }
+  i = read(fd, buf, 10000);
+  if (i == 2000) {
+    printf(stdout, "read succeeded\\n");
   } else {
-    puts("error: creat doesnotexist failed!\n");
+    printf(stdout, "read failed\n");
   }
   close(fd);
   //exec("echo", echo_args);
+  printf(stdout, "about to do exec\n");
   exec("cat", cat_args);
   return 0;
 }
diff --git a/usys.S b/usys.S
index 3622f82dafba3d070adffa53efdde52a5a91cd34..8cf7581fcd76e63bcc010148fad6195b1336fa90 100644 (file)
--- a/usys.S
+++ b/usys.S
@@ -23,3 +23,4 @@ STUB(cons_puts)
 STUB(exec)
 STUB(open)
 STUB(mknod)
+STUB(unlink)