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:
parent
9e5970d596
commit
c372e8dc34
27
fs.c
27
fs.c
|
@ -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);
|
||||
|
|
15
userfs.c
15
userfs.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue