summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2002-02-07 00:54:32 +0000
committermckusick <mckusick@FreeBSD.org>2002-02-07 00:54:32 +0000
commit9d51e5cc24febe6aab57100f22a650c0dc2779f3 (patch)
treef394264cf175d55f573272b0334fc911c273b672 /sys
parent66ffb1f1383c2274845ae6970fe3a5694a8cdf23 (diff)
downloadFreeBSD-src-9d51e5cc24febe6aab57100f22a650c0dc2779f3.zip
FreeBSD-src-9d51e5cc24febe6aab57100f22a650c0dc2779f3.tar.gz
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 <fenner@research.att.com>
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c17
1 files changed, 10 insertions, 7 deletions
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);
}
OpenPOWER on IntegriCloud