diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | console.c | 4 | ||||
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | fd.c | 8 | ||||
| -rw-r--r-- | fs.c | 97 | ||||
| -rw-r--r-- | printf.c | 76 | ||||
| -rw-r--r-- | syscall.c | 27 | ||||
| -rw-r--r-- | syscall.h | 2 | ||||
| -rw-r--r-- | user.h | 3 | ||||
| -rw-r--r-- | userfs.c | 58 | ||||
| -rw-r--r-- | usys.S | 1 | 
11 files changed, 238 insertions, 42 deletions
| @@ -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) @@ -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;  } @@ -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); @@ -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; @@ -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 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; +    } +  } +} @@ -331,6 +331,30 @@ sys_mknod(void)  }  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)  {    struct proc *cp = curproc[cpu()]; @@ -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 @@ -13,3 +13,5 @@  #define SYS_exec 13  #define SYS_open 14  #define SYS_mknod 15 +#define SYS_unlink 16 + @@ -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, ...); + @@ -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;  } @@ -23,3 +23,4 @@ STUB(cons_puts)  STUB(exec)  STUB(open)  STUB(mknod) +STUB(unlink)	 | 
