From 91ea161570a408dc49c28f08773518457839af0a Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Mon, 24 Jul 2000 19:50:20 +0000 Subject: [PATCH] If the lost+found directory is created by fsck, it will do a cacheino() which sets the inoinfo's i_parent and i_dotdot to 0, but they never get set to ROOTINO. This means that propagate will never find lost+found and its descendents, subdirectories will remain DSTATE (instead of DFOUND) even though they *are* correctly linked in, and pass4.c will try to clear them unsuccessfully, thinking that there is no link count from the DSTATE directory's parent. The result is that you need to run fsck twice and get link count increasing errors (which are unexpected and fatal when running in preen mode). The fix is to set i_parent and i_dotdot to "parent" after the second cacheino() call in dir.c:allocdir(). Obtained from: "Ethan Solomita" (of the NetBSD Project) --- sbin/fsck/dir.c | 6 +++++- sbin/fsck_ffs/dir.c | 6 +++++- sbin/fsck_ifs/dir.c | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sbin/fsck/dir.c b/sbin/fsck/dir.c index 5ce99f6b7b5..5def8b22ea3 100644 --- a/sbin/fsck/dir.c +++ b/sbin/fsck/dir.c @@ -669,7 +669,8 @@ allocdir(parent, request, mode) ino_t ino; char *cp; struct dinode *dp; - register struct bufarea *bp; + struct bufarea *bp; + struct inoinfo *inp; struct dirtemplate *dirp; ino = allocino(request, IFDIR|mode); @@ -704,6 +705,9 @@ allocdir(parent, request, mode) return (0); } cacheino(dp, ino); + inp = getinoinfo(ino); + inp->i_parent = parent; + inp->i_dotdot = parent; inoinfo(ino)->ino_state = inoinfo(parent)->ino_state; if (inoinfo(ino)->ino_state == DSTATE) { inoinfo(ino)->ino_linkcnt = dp->di_nlink; diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c index 5ce99f6b7b5..5def8b22ea3 100644 --- a/sbin/fsck_ffs/dir.c +++ b/sbin/fsck_ffs/dir.c @@ -669,7 +669,8 @@ allocdir(parent, request, mode) ino_t ino; char *cp; struct dinode *dp; - register struct bufarea *bp; + struct bufarea *bp; + struct inoinfo *inp; struct dirtemplate *dirp; ino = allocino(request, IFDIR|mode); @@ -704,6 +705,9 @@ allocdir(parent, request, mode) return (0); } cacheino(dp, ino); + inp = getinoinfo(ino); + inp->i_parent = parent; + inp->i_dotdot = parent; inoinfo(ino)->ino_state = inoinfo(parent)->ino_state; if (inoinfo(ino)->ino_state == DSTATE) { inoinfo(ino)->ino_linkcnt = dp->di_nlink; diff --git a/sbin/fsck_ifs/dir.c b/sbin/fsck_ifs/dir.c index 5ce99f6b7b5..5def8b22ea3 100644 --- a/sbin/fsck_ifs/dir.c +++ b/sbin/fsck_ifs/dir.c @@ -669,7 +669,8 @@ allocdir(parent, request, mode) ino_t ino; char *cp; struct dinode *dp; - register struct bufarea *bp; + struct bufarea *bp; + struct inoinfo *inp; struct dirtemplate *dirp; ino = allocino(request, IFDIR|mode); @@ -704,6 +705,9 @@ allocdir(parent, request, mode) return (0); } cacheino(dp, ino); + inp = getinoinfo(ino); + inp->i_parent = parent; + inp->i_dotdot = parent; inoinfo(ino)->ino_state = inoinfo(parent)->ino_state; if (inoinfo(ino)->ino_state == DSTATE) { inoinfo(ino)->ino_linkcnt = dp->di_nlink; -- 2.45.2