diff options
| author | kaashoek <kaashoek> | 2006-08-13 05:28:04 +0000 | 
|---|---|---|
| committer | kaashoek <kaashoek> | 2006-08-13 05:28:04 +0000 | 
| commit | c372e8dc348e4bb30aae7642db92ecbeedbc83ab (patch) | |
| tree | 2260179bbbacee1ab83f8a4336c325294ac2867d | |
| parent | 9e5970d596d7b1634200d50e96130886f593cede (diff) | |
| download | xv6-labs-c372e8dc348e4bb30aae7642db92ecbeedbc83ab.tar.gz xv6-labs-c372e8dc348e4bb30aae7642db92ecbeedbc83ab.tar.bz2 xv6-labs-c372e8dc348e4bb30aae7642db92ecbeedbc83ab.zip | |
zero freed blocks
multi-block directories
track size of directory (size = number entries in use)
should namei (and other code that scans through directories) scan through all blocks of a directory and not use size?
| -rw-r--r-- | fs.c | 27 | ||||
| -rw-r--r-- | userfs.c | 15 | 
2 files changed, 34 insertions, 8 deletions
| @@ -76,6 +76,11 @@ bfree(int dev, uint b)    ninodes = sb->ninodes;    brelse(bp); +  bp = bread(dev, b); +  memset(bp->data, 0, BSIZE); +  bwrite(bp, b); +  brelse(bp); +    bp = bread(dev, BBLOCK(b, ninodes));    bi = b % BPB;    m = ~(0x1 << (bi %8)); @@ -446,6 +451,7 @@ wdir(struct inode *dp, char *name, uint ino)    struct buf *bp = 0;    struct dirent *ep = 0;    int i; +  int lb;    for(off = 0; off < dp->size; off += BSIZE) {      bp = bread(dp->dev, bmap(dp, off / BSIZE)); @@ -457,17 +463,23 @@ wdir(struct inode *dp, char *name, uint ino)      }      brelse(bp);    } - -  panic("mknod: XXXX no dir entry free\n"); - +  lb = dp->size / BSIZE; +  if (lb >= NDIRECT) { +    panic ("wdir: too many entries"); +  } +  dp->addrs[lb] = balloc(dp->dev); +  bp = bread(dp->dev, dp->addrs[lb]); +  ep = (struct dirent *) (bp->data);   found:    ep->inum = ino;    for(i = 0; i < DIRSIZ && name[i]; i++)      ep->name[i] = name[i];    for( ; i < DIRSIZ; i++)      ep->name[i] = '\0'; +  dp->size += sizeof(struct dirent);    bwrite (bp, bmap(dp, off/BSIZE));   // write directory block    brelse(bp); +  iupdate(dp);  }  struct inode * @@ -482,7 +494,6 @@ mknod(char *cp, short type, short major, short minor)      iput(ip);      return 0;    } -  cprintf("mknod: pinum = %d\n", pinum);    dp = iget(rootdev, pinum);    ip = ialloc(dp->dev, type);    if (ip == 0) { @@ -495,11 +506,9 @@ mknod(char *cp, short type, short major, short minor)    ip->nlink = 1;    iupdate (ip);  // write new inode to disk - +      wdir(dp, cp, ip->inum); -    iput(dp); -    return ip;  } @@ -537,12 +546,14 @@ unlink(char *cp)      }      brelse(bp);    } -  panic("mknod: XXXX no dir entry free\n"); +  panic("unlink: entry doesn't exist\n");   found:    ep->inum = 0; +  memset(ep->name, '\0', DIRSIZ);    bwrite (bp, bmap(dp, off/BSIZE));   // write directory block    brelse(bp); +  dp->size -= sizeof(struct dirent);    iupdate (dp);    iput(dp);    iput(ip); @@ -7,6 +7,7 @@  // file system tests  char buf[2000]; +char name[3];  char *echo_args[] = { "echo", "hello", "goodbye", 0 };  char *cat_args[] = { "cat", "README", 0 }; @@ -65,6 +66,20 @@ main(void)    }    close(fd);    unlink("doesnotexist"); +  name[0] = 'a'; +  name[2] = '\0'; +  for (i = 0; i < 52; i++) { +    name[1] = '0' + i; +    fd = open(name, O_CREATE|O_RDWR); +    close(fd); +  } +  name[0] = 'a'; +  name[2] = '\0'; +  for (i = 0; i < 52; i++) { +    name[1] = '0' + i; +    unlink(name); +  } +    //exec("echo", echo_args);    printf(stdout, "about to do exec\n");    exec("cat", cat_args); | 
