xv6, line by line
user/dorphan.c

user/dorphan.c

C · 35 lines · annotated 100% · user program / library · upstream

About this file

dorphan is the directory version of user/forphan.c. It creates a directory, makes it its current directory, deletes the directory’s name, and then sleeps forever. A process’s current directory holds a reference to the directory’s inode, just as an open file does, so the directory now exists with link count (nlink) 0 and no name: an orphaned inode.

test-xv6.py (test-xv6.py:156) waits for the line wait for kill and reclaim, kills QEMU, boots again and waits for ireclaim: orphaned inode N, printed by ireclaim when it frees the directory’s inode and its one data block. Run by hand at this commit, the next boot printed ireclaim: orphaned inode 24.

A directory is a harder case than a file because the kernel must also refuse to put anything into a directory that has been unlinked: create and sys_link both check dp->nlink == 0 (kernel/sysfile.c:269, kernel/sysfile.c:161), and any path lookup through an unlinked directory already fails in namex (kernel/fs.c:707). Otherwise a new file could be linked into the orphan and leak with it. user/grind.c exercises that case at random (its operation 20).

Added with user/forphan.c in commit 52efd73. Read before: user/forphan.c. Read next: sys_unlink and ireclaim.

6// Create an orphaned directory and check if test-xv6.py recovers it.
8#define BUFSZ 500
10char buf[BUFSZ];
12int
13main(int argc, char **argv)
15 char *s = argv[0];
17 if (mkdir("dd") != 0) {
18 printf("%s: mkdir dd failed\n", s);
19 exit(1);
20 }
22 if (chdir("dd") != 0) {
23 printf("%s: chdir dd failed\n", s);
24 exit(1);
25 }
27 if (unlink("../dd") < 0) {
28 printf("%s: unlink failed\n", s);
29 exit(1);
30 }
31 printf("wait for kill and reclaim\n");
32 // sit around until killed
33 for (;;)
34 pause(1000);