From ed8d80c2dedc7503ca1e019d81c8df3dfd28aac7 Mon Sep 17 00:00:00 2001 From: Nate Williams Date: Sat, 3 Oct 1998 19:17:11 +0000 Subject: [PATCH] Fix 'noatime' bug that was unrelated to use of noatime. The problem is caused when a directory block is compacted. When this occurs, softdep_change_directoryentry_offset() is called to relocate each directory entry and adjust its matching diradd structure, if any, to match the new location of the entry. The bug is that while softdep_change_directoryentry_offset() correctly adjusts the offsets of the diradd structures on the pd_diraddhd[] lists (which are not yet ready to be committed to disk), it fails to adjust the offsets of the diradd structures on the pd_pendinghd list (which are ready to be committed to disk). This causes the dependency structures to be inconsistent with the buf contents. Now, if the compaction has moved a directory entry to the same offset as one of the diradd structures on the pd_pendinghd list *and* a syscall is done that tries to remove this directory entry before this directory block has been written to disk (which would empty pd_pendinghd), a sanity check in newdirrem() will call panic() when it notices that the inode number in the entry that it is to be removed doesn't match the inode number in the diradd structure with that offset of that entry. Reviewed by: Kirk McKusick Submitted by: Don Lewis --- contrib/sys/softupdates/ffs_softdep.c | 11 ++++++++++- sys/contrib/softupdates/ffs_softdep.c | 11 ++++++++++- sys/ufs/ffs/ffs_softdep.c | 11 ++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/contrib/sys/softupdates/ffs_softdep.c b/contrib/sys/softupdates/ffs_softdep.c index 83a4fa8fe85..c4a2cd80702 100644 --- a/contrib/sys/softupdates/ffs_softdep.c +++ b/contrib/sys/softupdates/ffs_softdep.c @@ -54,7 +54,7 @@ * SUCH DAMAGE. * * from: @(#)ffs_softdep.c 9.28 (McKusick) 8/8/98 - * $Id: ffs_softdep.c,v 1.13 1998/08/12 20:46:47 julian Exp $ + * $Id: ffs_softdep.c,v 1.14 1998/09/24 15:02:46 luoqi Exp $ */ /* @@ -2230,6 +2230,15 @@ softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize) dap, da_pdlist); break; } + if (dap == NULL) { + for (dap = LIST_FIRST(&pagedep->pd_pendinghd); + dap; dap = LIST_NEXT(dap, da_pdlist)) { + if (dap->da_offset == oldoffset) { + dap->da_offset = newoffset; + break; + } + } + } done: bcopy(oldloc, newloc, entrysize); FREE_LOCK(&lk); diff --git a/sys/contrib/softupdates/ffs_softdep.c b/sys/contrib/softupdates/ffs_softdep.c index 83a4fa8fe85..c4a2cd80702 100644 --- a/sys/contrib/softupdates/ffs_softdep.c +++ b/sys/contrib/softupdates/ffs_softdep.c @@ -54,7 +54,7 @@ * SUCH DAMAGE. * * from: @(#)ffs_softdep.c 9.28 (McKusick) 8/8/98 - * $Id: ffs_softdep.c,v 1.13 1998/08/12 20:46:47 julian Exp $ + * $Id: ffs_softdep.c,v 1.14 1998/09/24 15:02:46 luoqi Exp $ */ /* @@ -2230,6 +2230,15 @@ softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize) dap, da_pdlist); break; } + if (dap == NULL) { + for (dap = LIST_FIRST(&pagedep->pd_pendinghd); + dap; dap = LIST_NEXT(dap, da_pdlist)) { + if (dap->da_offset == oldoffset) { + dap->da_offset = newoffset; + break; + } + } + } done: bcopy(oldloc, newloc, entrysize); FREE_LOCK(&lk); diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 83a4fa8fe85..c4a2cd80702 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -54,7 +54,7 @@ * SUCH DAMAGE. * * from: @(#)ffs_softdep.c 9.28 (McKusick) 8/8/98 - * $Id: ffs_softdep.c,v 1.13 1998/08/12 20:46:47 julian Exp $ + * $Id: ffs_softdep.c,v 1.14 1998/09/24 15:02:46 luoqi Exp $ */ /* @@ -2230,6 +2230,15 @@ softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize) dap, da_pdlist); break; } + if (dap == NULL) { + for (dap = LIST_FIRST(&pagedep->pd_pendinghd); + dap; dap = LIST_NEXT(dap, da_pdlist)) { + if (dap->da_offset == oldoffset) { + dap->da_offset = newoffset; + break; + } + } + } done: bcopy(oldloc, newloc, entrysize); FREE_LOCK(&lk);