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
2 changed files with 34 additions and 8 deletions
27
fs.c
27
fs.c
|
@ -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) {
|
||||||
|
@ -495,11 +506,9 @@ mknod(char *cp, short type, short major, short minor)
|
||||||
ip->nlink = 1;
|
ip->nlink = 1;
|
||||||
|
|
||||||
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);
|
||||||
|
|
15
userfs.c
15
userfs.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue