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:
parent
c2cfcae955
commit
61a6479ab1
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue