diff --git a/fs.c b/fs.c
index fe9ce487459e99f9d368f53c528733fbe9da6f19..b755c78d5292b4971518081f3a5ba259d33c2652 100644
--- a/fs.c
+++ b/fs.c
@@ -469,30 +469,25 @@ struct inode*
 dirlookup(struct inode *dp, char *name, uint *poff)
 {
   uint off, inum;
-  struct buf *bp;
-  struct dirent *de;
+  struct dirent de;
 
   if(dp->type != T_DIR)
     panic("dirlookup not DIR");
 
-  for(off = 0; off < dp->size; off += BSIZE){
-    bp = bread(dp->dev, bmap(dp, off / BSIZE));
-    for(de = (struct dirent*)bp->data;
-        de < (struct dirent*)(bp->data + BSIZE);
-        de++){
-      if(de->inum == 0)
-        continue;
-      if(namecmp(name, de->name) == 0){
-        // entry matches path element
-        if(poff)
-          *poff = off + (uchar*)de - bp->data;
-        inum = de->inum;
-        brelse(bp);
-        return iget(dp->dev, inum);
-      }
+  for(off = 0; off < dp->size; off += sizeof(de)){
+    if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
+      panic("dirlink read");
+    if(de.inum == 0)
+      continue;
+    if(namecmp(name, de.name) == 0){
+      // entry matches path element
+      if(poff)
+        *poff = off;
+      inum = de.inum;
+      return iget(dp->dev, inum);
     }
-    brelse(bp);
   }
+
   return 0;
 }
 
diff --git a/usertests.c b/usertests.c
index 8db8385cf90cb739eb38c9ba4f2d18930247d773..455e68a6fb2e5949291e8778769932bdbee6e0c1 100644
--- a/usertests.c
+++ b/usertests.c
@@ -1529,6 +1529,59 @@ bigargtest(void)
   wait();
 }
 
+// what happens when the file system runs out of blocks?
+// answer: balloc panics, so this test is not useful.
+void
+fsfull()
+{
+  int nfiles;
+  int fsblocks = 0;
+
+  printf(1, "fsfull test\n");
+
+  for(nfiles = 0; ; nfiles++){
+    char name[64];
+    name[0] = 'f';
+    name[1] = '0' + nfiles / 1000;
+    name[2] = '0' + (nfiles % 1000) / 100;
+    name[3] = '0' + (nfiles % 100) / 10;
+    name[4] = '0' + (nfiles % 10);
+    name[5] = '\0';
+    printf(1, "writing %s\n", name);
+    int fd = open(name, O_CREATE|O_RDWR);
+    if(fd < 0){
+      printf(1, "open %s failed\n", name);
+      break;
+    }
+    int total = 0;
+    while(1){
+      int cc = write(fd, buf, 512);
+      if(cc < 512)
+        break;
+      total += cc;
+      fsblocks++;
+    }
+    printf(1, "wrote %d bytes\n", total);
+    close(fd);
+    if(total == 0)
+      break;
+  }
+
+  while(nfiles >= 0){
+    char name[64];
+    name[0] = 'f';
+    name[1] = '0' + nfiles / 1000;
+    name[2] = '0' + (nfiles % 1000) / 100;
+    name[3] = '0' + (nfiles % 100) / 10;
+    name[4] = '0' + (nfiles % 10);
+    name[5] = '\0';
+    unlink(name);
+    nfiles--;
+  }
+
+  printf(1, "fsfull test finished\n");
+}
+
 int
 main(int argc, char *argv[])
 {