From 9d51e5cc24febe6aab57100f22a650c0dc2779f3 Mon Sep 17 00:00:00 2001 From: mckusick Date: Thu, 7 Feb 2002 00:54:32 +0000 Subject: Occationally deleted files would hang around for hours or days without being reclaimed. This bug was introduced in revision 1.95 dealing with filenames placed in newly allocated directory blocks, thus is not present in 4.X systems. The bug is triggered when a new entry is made in a directory after the data block containing the original new entry has been written, but before the inode that references the data block has been written. Submitted by: Bill Fenner --- sys/ufs/ffs/ffs_softdep.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'sys') diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index a7c12d4..05da93e 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -900,7 +900,8 @@ u_long pagedep_hash; /* size of hash table - 1 */ static struct sema pagedep_in_progress; /* - * Look up a pagedep. Return 1 if found, 0 if not found. + * Look up a pagedep. Return 1 if found, 0 if not found or found + * when asked to allocate but not associated with any buffer. * If not found, allocate if DEPALLOC flag is passed. * Found or allocated entry is returned in pagedeppp. * This routine must be called with splbio interrupts blocked. @@ -931,6 +932,9 @@ top: break; if (pagedep) { *pagedeppp = pagedep; + if ((flags & DEPALLOC) != 0 && + (pagedep->pd_state & ONWORKLIST) == 0) + return (0); return (1); } if ((flags & DEPALLOC) == 0) { @@ -3973,13 +3977,12 @@ handle_written_filepage(pagedep, bp) return (1); } /* - * If no dependencies remain and we are not waiting for a - * new directory block to be claimed by its inode, then the - * pagedep will be freed. Otherwise it will remain to track - * any new entries on the page in case they are fsync'ed. + * If we are not waiting for a new directory block to be + * claimed by its inode, then the pagedep will be freed. + * Otherwise it will remain to track any new entries on + * the page in case they are fsync'ed. */ - if (LIST_FIRST(&pagedep->pd_pendinghd) == 0 && - (pagedep->pd_state & NEWBLOCK) == 0) { + if ((pagedep->pd_state & NEWBLOCK) == 0) { LIST_REMOVE(pagedep, pd_hash); WORKITEM_FREE(pagedep, D_PAGEDEP); } -- cgit v1.1