diff --git a/Notes b/Notes
index 4c9855dd67904435d4dc731dd02b2ac6c9b1c88b..6273db5a02e501ba0ed0cfe9509df2027d0733c1 100644
--- a/Notes
+++ b/Notes
@@ -115,6 +115,11 @@ why does shell often ignore first line of input?
 test: one process unlinks a file while another links to it
 test: one process opens a file while another deletes it
 test: mkdir. deadlock d/.. vs ../d
+test: sub-sub directories. mkdir("d1/d2")
+test: dup() shared fd->off
+test: indirect blocks. files and directories.
+test: sbrk
+test: does echo foo > x truncate x?
 
 make proc[0] runnable
 cpu early tss and gdt
@@ -138,4 +143,8 @@ are the locks in the right place in keyboardintr?
 sh: support pipes?  leave it for the class?
 sh: dynamic memory allocation?
 sh: should sh support ; () &  --- need malloc
-sh: stop stdin on ctrl-d (for cat > y)
\ No newline at end of file
+sh: stop stdin on ctrl-d (for cat > y)
+
+really should have bdwrite() for file content
+  and make some inode updates async
+  so soft updates make sense
diff --git a/fs.c b/fs.c
index cd60da9eb0d08c89aeba2454a967e5a65cbeafc5..5280a4d18f5991ef580a742168b58217799b32d9 100644
--- a/fs.c
+++ b/fs.c
@@ -262,8 +262,8 @@ iunlink(struct inode *ip)
     if (ip->addrs[i] != 0) {
       if (i == INDIRECT) {
 	inbp = bread(ip->dev, ip->addrs[INDIRECT]);
+        uint *a = (uint *) inbp->data;
 	for (j = 0; j < NINDIRECT; j++) {
-	  uint *a = (uint *) inbp->data;
 	  if (a[j] != 0) {
 	    bfree(ip->dev, a[j]);
 	    a[j] = 0;
@@ -589,6 +589,9 @@ unlink(char *cp)
 
   ip = iget(dev, inum);
 
+  if(ip->nlink < 1)
+    panic("unlink nlink < 1");
+
   ip->nlink--;
 
   iupdate(ip);
diff --git a/fstests.c b/fstests.c
index e42851964de31441bc10c3759b1891ed192908b7..d177ce90773b240fcb0db47772c1325448bd8e34 100644
--- a/fstests.c
+++ b/fstests.c
@@ -365,11 +365,56 @@ concreate()
   puts("concreate ok\n");
 }
 
+// directory that uses indirect blocks
+void
+bigdir()
+{
+  int i, fd;
+  char name[10];
+
+  unlink("bd");
+
+  fd = open("bd", O_CREATE);
+  if(fd < 0){
+    puts("bigdir create failed\n");
+    exit();
+  }
+  close(fd);
+
+  for(i = 0; i < 500; i++){
+    name[0] = 'x';
+    name[1] = '0' + (i / 64);
+    name[2] = '0' + (i % 64);
+    name[3] = '\0';
+    if(link("bd", name) != 0){
+      puts("bigdir link failed\n");
+      exit();
+    }
+    puts("c");
+  }
+
+  unlink("bd");
+  for(i = 0; i < 500; i++){
+    name[0] = 'x';
+    name[1] = '0' + (i / 64);
+    name[2] = '0' + (i % 64);
+    name[3] = '\0';
+    if(unlink(name) != 0){
+      puts("bigdir unlink failed");
+      exit();
+    }
+    puts("d");
+  }
+
+  puts("bigdir ok\n");
+}
+
 int
 main(int argc, char *argv[])
 {
   puts("fstests starting\n");
 
+  bigdir();
   concreate();
   linktest();
   unlinkread();