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 <mckusick@McKusick.COM>
Submitted by:	Don Lewis <Don.Lewis@tsc.tdk.com>
This commit is contained in:
Nate Williams 1998-10-03 19:17:11 +00:00
parent 94d09127cb
commit ed8d80c2de
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39933
3 changed files with 30 additions and 3 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);