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?
This commit is contained in:
kaashoek 2006-08-13 05:28:04 +00:00
parent 9e5970d596
commit c372e8dc34
2 changed files with 34 additions and 8 deletions

25
fs.c
View file

@ -76,6 +76,11 @@ bfree(int dev, uint b)
ninodes = sb->ninodes; ninodes = sb->ninodes;
brelse(bp); brelse(bp);
bp = bread(dev, b);
memset(bp->data, 0, BSIZE);
bwrite(bp, b);
brelse(bp);
bp = bread(dev, BBLOCK(b, ninodes)); bp = bread(dev, BBLOCK(b, ninodes));
bi = b % BPB; bi = b % BPB;
m = ~(0x1 << (bi %8)); m = ~(0x1 << (bi %8));
@ -446,6 +451,7 @@ wdir(struct inode *dp, char *name, uint ino)
struct buf *bp = 0; struct buf *bp = 0;
struct dirent *ep = 0; struct dirent *ep = 0;
int i; int i;
int lb;
for(off = 0; off < dp->size; off += BSIZE) { for(off = 0; off < dp->size; off += BSIZE) {
bp = bread(dp->dev, bmap(dp, off / BSIZE)); bp = bread(dp->dev, bmap(dp, off / BSIZE));
@ -457,17 +463,23 @@ wdir(struct inode *dp, char *name, uint ino)
} }
brelse(bp); brelse(bp);
} }
lb = dp->size / BSIZE;
panic("mknod: XXXX no dir entry free\n"); 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: found:
ep->inum = ino; ep->inum = ino;
for(i = 0; i < DIRSIZ && name[i]; i++) for(i = 0; i < DIRSIZ && name[i]; i++)
ep->name[i] = name[i]; ep->name[i] = name[i];
for( ; i < DIRSIZ; i++) for( ; i < DIRSIZ; i++)
ep->name[i] = '\0'; ep->name[i] = '\0';
dp->size += sizeof(struct dirent);
bwrite (bp, bmap(dp, off/BSIZE)); // write directory block bwrite (bp, bmap(dp, off/BSIZE)); // write directory block
brelse(bp); brelse(bp);
iupdate(dp);
} }
struct inode * struct inode *
@ -482,7 +494,6 @@ mknod(char *cp, short type, short major, short minor)
iput(ip); iput(ip);
return 0; return 0;
} }
cprintf("mknod: pinum = %d\n", pinum);
dp = iget(rootdev, pinum); dp = iget(rootdev, pinum);
ip = ialloc(dp->dev, type); ip = ialloc(dp->dev, type);
if (ip == 0) { if (ip == 0) {
@ -497,9 +508,7 @@ mknod(char *cp, short type, short major, short minor)
iupdate (ip); // write new inode to disk iupdate (ip); // write new inode to disk
wdir(dp, cp, ip->inum); wdir(dp, cp, ip->inum);
iput(dp); iput(dp);
return ip; return ip;
} }
@ -537,12 +546,14 @@ unlink(char *cp)
} }
brelse(bp); brelse(bp);
} }
panic("mknod: XXXX no dir entry free\n"); panic("unlink: entry doesn't exist\n");
found: found:
ep->inum = 0; ep->inum = 0;
memset(ep->name, '\0', DIRSIZ);
bwrite (bp, bmap(dp, off/BSIZE)); // write directory block bwrite (bp, bmap(dp, off/BSIZE)); // write directory block
brelse(bp); brelse(bp);
dp->size -= sizeof(struct dirent);
iupdate (dp); iupdate (dp);
iput(dp); iput(dp);
iput(ip); iput(ip);

View file

@ -7,6 +7,7 @@
// file system tests // file system tests
char buf[2000]; char buf[2000];
char name[3];
char *echo_args[] = { "echo", "hello", "goodbye", 0 }; char *echo_args[] = { "echo", "hello", "goodbye", 0 };
char *cat_args[] = { "cat", "README", 0 }; char *cat_args[] = { "cat", "README", 0 };
@ -65,6 +66,20 @@ main(void)
} }
close(fd); close(fd);
unlink("doesnotexist"); 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); //exec("echo", echo_args);
printf(stdout, "about to do exec\n"); printf(stdout, "about to do exec\n");
exec("cat", cat_args); exec("cat", cat_args);