Patch from Kirk McKusick to fix an ordering problem in softdep_setup_freeblks()

that could cause an inode to be reused prematurely (possibly resulting in the
file containing garbage blocks).
This commit is contained in:
mycroft 2000-12-13 20:07:32 +00:00
parent c2cfcae955
commit 61a6479ab1
1 changed files with 20 additions and 17 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_softdep.c,v 1.11 2000/12/13 15:32:31 chs Exp $ */
/* $NetBSD: ffs_softdep.c,v 1.12 2000/12/13 20:07:32 mycroft Exp $ */
/*
* Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
@ -1620,7 +1620,7 @@ softdep_setup_freeblocks(ip, length)
struct buf *bp;
struct bufq_head fbqh;
struct fs *fs = ip->i_fs;
int i, error;
int i, error, delay;
#ifdef FFS_EI
const int needswap = UFS_FSNEEDSWAP(fs);
#endif
@ -1672,6 +1672,16 @@ softdep_setup_freeblocks(ip, length)
(void) inodedep_lookup(fs, ip->i_number, DEPALLOC, &inodedep);
if ((inodedep->id_state & IOSTARTED) != 0)
panic("softdep_setup_freeblocks: inode busy");
/*
* Add the freeblks structure to the list of operations that
* must await the zero'ed inode being written to disk. If we
* still have a bitmap dependency (delay == 0), then the inode
* has never been written to disk, so we can process the
* freeblks below once we have deleted the dependencies.
*/
delay = (inodedep->id_state & DEPCOMPLETE);
if (delay)
WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
/*
* Because the file length has been truncated to zero, any
* pending block allocation dependency structures associated
@ -1708,23 +1718,16 @@ softdep_setup_freeblocks(ip, length)
ACQUIRE_LOCK(&lk);
}
softdep_free_pagecache(&fbqh);
if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) != 0)
(void) free_inodedep(inodedep);
FREE_LOCK(&lk);
/*
* Add the freeblks structure to the list of operations that
* must await the zero'ed inode being written to disk. If we
* still have a bitmap dependency, then the inode has never been
* written to disk, so we can process the freeblks immediately.
* If the inodedep does not exist, then the zero'ed inode has
* been written and we can also proceed.
* If the inode has never been written to disk (delay == 0),
* then we can process the freeblks now that we have deleted
* the dependencies.
*/
if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) == 0 ||
free_inodedep(inodedep) ||
(inodedep->id_state & DEPCOMPLETE) == 0) {
FREE_LOCK(&lk);
if (!delay)
handle_workitem_freeblocks(freeblks);
} else {
WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
FREE_LOCK(&lk);
}
}
/*
@ -2042,7 +2045,7 @@ handle_workitem_freeblocks(freeblks)
#ifdef DIAGNOSTIC
if (freeblks->fb_chkcnt != blocksreleased)
panic("handle_workitem_freeblocks: block count");
printf("handle_workitem_freeblocks: block count");
if (allerror)
softdep_error("handle_workitem_freeblks", allerror);
#endif /* DIAGNOSTIC */