diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | kernel/exec.c | 1 | ||||
| -rw-r--r-- | kernel/fs.c | 38 | ||||
| -rw-r--r-- | user/ulib.c | 11 | ||||
| -rw-r--r-- | user/usertests.c | 46 | 
5 files changed, 87 insertions, 11 deletions
| @@ -90,7 +90,7 @@ tags: $(OBJS) _init  ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/umalloc.o  _%: %.o $(ULIB) -	$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^ +	$(LD) $(LDFLAGS) -N -e _main -Ttext 0 -o $@ $^  	$(OBJDUMP) -S $@ > $*.asm  	$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym diff --git a/kernel/exec.c b/kernel/exec.c index d62d29d..09b4bdc 100644 --- a/kernel/exec.c +++ b/kernel/exec.c @@ -65,6 +65,7 @@ exec(char *path, char **argv)    uint64 oldsz = p->sz;    // Allocate two pages at the next page boundary. +  // Make the first inaccessible as a stack guard.    // Use the second as the user stack.    sz = PGROUNDUP(sz);    uint64 sz1; diff --git a/kernel/fs.c b/kernel/fs.c index 53a3a0f..247a86f 100644 --- a/kernel/fs.c +++ b/kernel/fs.c @@ -61,6 +61,7 @@ bzero(int dev, int bno)  // Blocks.  // Allocate a zeroed disk block. +// returns 0 if out of disk space.  static uint  balloc(uint dev)  { @@ -82,7 +83,8 @@ balloc(uint dev)      }      brelse(bp);    } -  panic("balloc: out of blocks"); +  printf("balloc: out of blocks\n"); +  return 0;  }  // Free a disk block. @@ -374,6 +376,7 @@ iunlockput(struct inode *ip)  // Return the disk block address of the nth block in inode ip.  // If there is no such block, bmap allocates one. +// returns 0 if out of disk space.  static uint  bmap(struct inode *ip, uint bn)  { @@ -381,21 +384,32 @@ bmap(struct inode *ip, uint bn)    struct buf *bp;    if(bn < NDIRECT){ -    if((addr = ip->addrs[bn]) == 0) -      ip->addrs[bn] = addr = balloc(ip->dev); +    if((addr = ip->addrs[bn]) == 0){ +      addr = balloc(ip->dev); +      if(addr == 0) +        return 0; +      ip->addrs[bn] = addr; +    }      return addr;    }    bn -= NDIRECT;    if(bn < NINDIRECT){      // Load indirect block, allocating if necessary. -    if((addr = ip->addrs[NDIRECT]) == 0) -      ip->addrs[NDIRECT] = addr = balloc(ip->dev); +    if((addr = ip->addrs[NDIRECT]) == 0){ +      addr = balloc(ip->dev); +      if(addr == 0) +        return 0; +      ip->addrs[NDIRECT] = addr; +    }      bp = bread(ip->dev, addr);      a = (uint*)bp->data;      if((addr = a[bn]) == 0){ -      a[bn] = addr = balloc(ip->dev); -      log_write(bp); +      addr = balloc(ip->dev); +      if(addr){ +        a[bn] = addr; +        log_write(bp); +      }      }      brelse(bp);      return addr; @@ -464,7 +478,10 @@ readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)      n = ip->size - off;    for(tot=0; tot<n; tot+=m, off+=m, dst+=m){ -    bp = bread(ip->dev, bmap(ip, off/BSIZE)); +    uint addr = bmap(ip, off/BSIZE); +    if(addr == 0) +      break; +    bp = bread(ip->dev, addr);      m = min(n - tot, BSIZE - off%BSIZE);      if(either_copyout(user_dst, dst, bp->data + (off % BSIZE), m) == -1) {        brelse(bp); @@ -495,7 +512,10 @@ writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)      return -1;    for(tot=0; tot<n; tot+=m, off+=m, src+=m){ -    bp = bread(ip->dev, bmap(ip, off/BSIZE)); +    uint addr = bmap(ip, off/BSIZE); +    if(addr == 0) +      break; +    bp = bread(ip->dev, addr);      m = min(n - tot, BSIZE - off%BSIZE);      if(either_copyin(bp->data + (off % BSIZE), user_src, src, m) == -1) {        brelse(bp); diff --git a/user/ulib.c b/user/ulib.c index 4775939..c7b66c4 100644 --- a/user/ulib.c +++ b/user/ulib.c @@ -3,6 +3,17 @@  #include "kernel/fcntl.h"  #include "user/user.h" +// +// wrapper so that it's OK if main() does not call exit(). +// +void +_main() +{ +  extern int main(); +  main(); +  exit(0); +} +  char*  strcpy(char *s, const char *t)  { diff --git a/user/usertests.c b/user/usertests.c index 0fe7371..4ab34da 100644 --- a/user/usertests.c +++ b/user/usertests.c @@ -2706,6 +2706,49 @@ execout(char *s)    exit(0);  } +// can the kernel tolerate running out of disk space? +void +diskfull(char *s) +{ +  int fi; +  int done = 0; +   +  for(fi = 0; done == 0; fi++){ +    char name[32]; +    name[0] = 'b'; +    name[1] = 'i'; +    name[2] = 'g'; +    name[3] = '0' + fi; +    name[4] = '\0'; +    unlink(name); +    int fd = open(name, O_CREATE|O_RDWR|O_TRUNC); +    if(fd < 0){ +      printf("%s: could not create file %s\n", s, name); +      done = 1; +      break; +    } +    for(int i = 0; i < MAXFILE; i++){ +      char buf[BSIZE]; +      if(write(fd, buf, BSIZE) != BSIZE){ +        done = 1; +        close(fd); +        break; +      } +    } +    close(fd); +  } + +  for(int i = 0; i < fi; i++){ +    char name[32]; +    name[0] = 'b'; +    name[1] = 'i'; +    name[2] = 'g'; +    name[3] = '0' + i; +    name[4] = '\0'; +    unlink(name); +  } +} +  //  // use sbrk() to count how many free physical memory pages there are.  // touches the pages to force allocation. @@ -2818,7 +2861,7 @@ main(int argc, char *argv[])      void (*f)(char *);      char *s;    } tests[] = { -    {MAXVAplus, "MAXVAplus"}, +    {diskfull, "diskfull"},      {manywrites, "manywrites"},      {execout, "execout"},      {copyin, "copyin"}, @@ -2880,6 +2923,7 @@ main(int argc, char *argv[])      {dirfile, "dirfile"},      {iref, "iref"},      {forktest, "forktest"}, +    {MAXVAplus, "MAXVAplus"},      {bigdir, "bigdir"}, // slow      { 0, 0},    }; | 
