summaryrefslogtreecommitdiff
path: root/fs.c
diff options
context:
space:
mode:
authorkaashoek <kaashoek>2006-08-13 05:28:04 +0000
committerkaashoek <kaashoek>2006-08-13 05:28:04 +0000
commitc372e8dc348e4bb30aae7642db92ecbeedbc83ab (patch)
tree2260179bbbacee1ab83f8a4336c325294ac2867d /fs.c
parent9e5970d596d7b1634200d50e96130886f593cede (diff)
downloadxv6-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?
Diffstat (limited to 'fs.c')
-rw-r--r--fs.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs.c b/fs.c
index 7f0d2ea..dbecb41 100644
--- a/fs.c
+++ b/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);