diff --git a/fs.c b/fs.c
index 7f0d2eae1370d9c88f55df4fd549ab157e410181..dbecb410c4a010b507f0c131d73834d24571a977 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);
diff --git a/userfs.c b/userfs.c
index 90aa1fa5330590cef84ce8c4a079dc2303c1b7c9..2726de75d33e63cd4b6bafe83e2df3d13442e594 100644
--- a/userfs.c
+++ b/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);