diff options
| author | kaashoek <kaashoek> | 2006-08-11 18:18:38 +0000 | 
|---|---|---|
| committer | kaashoek <kaashoek> | 2006-08-11 18:18:38 +0000 | 
| commit | 24437cd554995f729969299e72699e2ba5d9b068 (patch) | |
| tree | e3b5aa572c9621d1f932788fc882d4e6d693473f | |
| parent | 17a856577f9db766b8ef7099d0575d378dff5dd1 (diff) | |
| download | xv6-labs-24437cd554995f729969299e72699e2ba5d9b068.tar.gz xv6-labs-24437cd554995f729969299e72699e2ba5d9b068.tar.bz2 xv6-labs-24437cd554995f729969299e72699e2ba5d9b068.zip | |
fix deadlock---iput(dp) asap
working unlink, but doesn't free dir blocks that become empty
remove out-of-date comment in ioapic
| -rw-r--r-- | defs.h | 1 | ||||
| -rw-r--r-- | fs.c | 60 | ||||
| -rw-r--r-- | ioapic.c | 2 | ||||
| -rw-r--r-- | syscall.c | 36 | ||||
| -rw-r--r-- | userfs.c | 7 | 
5 files changed, 73 insertions, 33 deletions
| @@ -118,4 +118,5 @@ struct inode * namei(char *path);  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); +int unlink(char *cp);  void iupdate (struct inode *ip); @@ -187,7 +187,7 @@ ialloc(uint dev, short type)  }  static void -ifree(uint dev, struct inode *ip) +ifree(struct inode *ip)  {    ip->type = 0;    iupdate(ip); @@ -440,3 +440,61 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)    return ip;  } + +int +unlink(char *cp) +{ +  int i; +  struct inode *ip, *dp; +  struct dirent *ep = 0; +  int off; +  struct buf *bp = 0; +   +    if ((ip = namei(cp)) == 0) { +    cprintf("file to be unlinked doesn't exist\n"); +    return -1; +  } + +  ip->nlink--; +  if (ip->nlink > 0) { +    iupdate(ip); +    iput(ip); // is this the right order? +    return 0; +  } + +  // free inode, its blocks, and remove dir entry +  for (i = 0; i < NDIRECT; i++) { +    if (ip->addrs[i] != 0) { +      bfree(ip->dev, ip->addrs[i]); +      ip->addrs[i] = 0; +    } +  } +  ip->size = 0; +  ip->major = 0; +  ip->minor = 0; +  iupdate(ip); +  ifree(ip);  // is this the right order? + +  dp = iget(rootdev, 1);    // XXX should parse name +  for(off = 0; off < dp->size; off += BSIZE) { +    bp = bread(dp->dev, bmap(dp, off / BSIZE)); +    for(ep = (struct dirent *) bp->data; +	ep < (struct dirent *) (bp->data + BSIZE); +	ep++){ +      if(ep->inum == ip->inum) { +	goto found; +      } +    } +    brelse(bp); +  } +  panic("mknod: XXXX no dir entry free\n"); + + found: +  ep->inum = 0; +  bwrite (dp->dev, bp, bmap(dp, off/BSIZE));   // write directory block +  brelse(bp); +  iput(ip); +  iupdate (dp); +  iput(dp); +  return 0; +} @@ -76,7 +76,7 @@ ioapic_enable (int irq, int cpunum)    ioapic_write(io, IOAPIC_REDTBL_LO(irq), l);    h = ioapic_read(io, IOAPIC_REDTBL_HI(irq));    h &= ~IOART_DEST; -  h |= (cpunum << APIC_ID_SHIFT);  // for fun, disk interrupts to cpu 1 +  h |= (cpunum << APIC_ID_SHIFT);     ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);    cprintf("cpu%d: intr %d: lo 0x%x hi 0x%x\n", cpu(), irq, l, h);  } @@ -265,10 +265,9 @@ sys_open(void)        if (l >= DIRSIZ)  	return -1;        dp = iget(rootdev, 1);  // XXX should parse name -      if (dp->type != T_DIR)  -	return -1; -      if ((ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0)) == 0) -	return -1; +      ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0); +      iput(dp); +      if (ip == 0) return -1;      } else return -1;    }    if((fd = fd_alloc()) == 0){ @@ -319,45 +318,26 @@ sys_mknod(void)      return -1;    dp = iget(rootdev, 1);    // XXX should parse name -  if (dp->type != T_DIR) { -    iput(dp); -    return -1; -  } -    nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2,   		   (short) arg3); -    iput(dp); - -  if (nip == 0) return -1; -    iput(nip); -   -  return 0; +  return (nip == 0) ? -1 : 0;  }  int  sys_unlink(void)  {    struct proc *cp = curproc[cpu()]; -  struct inode *ip;    uint arg0; - +  int r; +      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; +  r = unlink(cp->mem + arg0); +  return r;  }  int @@ -5,7 +5,7 @@  // file system tests -char buf[2000]; +char buf[3000];  char *echo_args[] = { "echo", "hello", "goodbye", 0 };  char *cat_args[] = { "cat", "README", 0 }; @@ -62,13 +62,14 @@ main(void)    } else {      printf(stdout, "error: open doesnotexist failed!\n");    } -  i = read(fd, buf, 10000); +  i = read(fd, buf, 2000);    if (i == 2000) { -    printf(stdout, "read succeeded\\n"); +    printf(stdout, "read succeeded\n");    } else {      printf(stdout, "read failed\n");    }    close(fd); +  unlink("doesnotexist");    //exec("echo", echo_args);    printf(stdout, "about to do exec\n");    exec("cat", cat_args); | 
