diff --git a/kernel/fs.c b/kernel/fs.c
index 247a86f..b220491 100644
--- a/kernel/fs.c
+++ b/kernel/fs.c
@@ -573,6 +573,7 @@ dirlookup(struct inode *dp, char *name, uint *poff)
 }
 
 // Write a new directory entry (name, inum) into the directory dp.
+// Returns 0 on success, -1 on failure (e.g. out of disk blocks).
 int
 dirlink(struct inode *dp, char *name, uint inum)
 {
@@ -597,7 +598,7 @@ dirlink(struct inode *dp, char *name, uint inum)
   strncpy(de.name, name, DIRSIZ);
   de.inum = inum;
   if(writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
-    panic("dirlink");
+    return -1;
 
   return 0;
 }
diff --git a/kernel/sysfile.c b/kernel/sysfile.c
index 970a72a..4c0470e 100644
--- a/kernel/sysfile.c
+++ b/kernel/sysfile.c
@@ -279,8 +279,13 @@ create(char *path, short type, short major, short minor)
       panic("create dots");
   }
 
-  if(dirlink(dp, name, ip->inum) < 0)
-    panic("create: dirlink");
+  if(dirlink(dp, name, ip->inum) < 0){
+    // oops. we don't need ip after all.
+    ip->nlink = 0;
+    iupdate(ip);
+    iunlockput(ip);
+    ip = 0;
+  }
 
   iunlockput(dp);
 
diff --git a/user/usertests.c b/user/usertests.c
index 4ab34da..968034a 100644
--- a/user/usertests.c
+++ b/user/usertests.c
@@ -2738,6 +2738,36 @@ diskfull(char *s)
     close(fd);
   }
 
+  // now that there are no free blocks, test that dirlink()
+  // merely fails (doesn't panic) if it can't extend
+  // directory content.
+  int nzz = 128;
+  for(int i = 0; i < nzz; i++){
+    char name[32];
+    name[0] = 'z';
+    name[1] = 'z';
+    name[2] = '0' + (i / 32);
+    name[3] = '0' + (i % 32);
+    name[4] = '\0';
+    unlink(name);
+    int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
+    if(fd < 0){
+      printf("%s: could not create file %s\n", s, name);
+      break;
+    }
+    close(fd);
+  }
+
+  for(int i = 0; i < nzz; i++){
+    char name[32];
+    name[0] = 'z';
+    name[1] = 'z';
+    name[2] = '0' + (i / 32);
+    name[3] = '0' + (i % 32);
+    name[4] = '\0';
+    unlink(name);
+  }
+
   for(int i = 0; i < fi; i++){
     char name[32];
     name[0] = 'b';