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.
|
* Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
|
||||||
|
@ -1620,7 +1620,7 @@ softdep_setup_freeblocks(ip, length)
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
struct bufq_head fbqh;
|
struct bufq_head fbqh;
|
||||||
struct fs *fs = ip->i_fs;
|
struct fs *fs = ip->i_fs;
|
||||||
int i, error;
|
int i, error, delay;
|
||||||
#ifdef FFS_EI
|
#ifdef FFS_EI
|
||||||
const int needswap = UFS_FSNEEDSWAP(fs);
|
const int needswap = UFS_FSNEEDSWAP(fs);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1672,6 +1672,16 @@ softdep_setup_freeblocks(ip, length)
|
||||||
(void) inodedep_lookup(fs, ip->i_number, DEPALLOC, &inodedep);
|
(void) inodedep_lookup(fs, ip->i_number, DEPALLOC, &inodedep);
|
||||||
if ((inodedep->id_state & IOSTARTED) != 0)
|
if ((inodedep->id_state & IOSTARTED) != 0)
|
||||||
panic("softdep_setup_freeblocks: inode busy");
|
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
|
* Because the file length has been truncated to zero, any
|
||||||
* pending block allocation dependency structures associated
|
* pending block allocation dependency structures associated
|
||||||
|
@ -1708,23 +1718,16 @@ softdep_setup_freeblocks(ip, length)
|
||||||
ACQUIRE_LOCK(&lk);
|
ACQUIRE_LOCK(&lk);
|
||||||
}
|
}
|
||||||
softdep_free_pagecache(&fbqh);
|
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
|
* If the inode has never been written to disk (delay == 0),
|
||||||
* must await the zero'ed inode being written to disk. If we
|
* then we can process the freeblks now that we have deleted
|
||||||
* still have a bitmap dependency, then the inode has never been
|
* the dependencies.
|
||||||
* 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 (inodedep_lookup(fs, ip->i_number, 0, &inodedep) == 0 ||
|
if (!delay)
|
||||||
free_inodedep(inodedep) ||
|
|
||||||
(inodedep->id_state & DEPCOMPLETE) == 0) {
|
|
||||||
FREE_LOCK(&lk);
|
|
||||||
handle_workitem_freeblocks(freeblks);
|
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
|
#ifdef DIAGNOSTIC
|
||||||
if (freeblks->fb_chkcnt != blocksreleased)
|
if (freeblks->fb_chkcnt != blocksreleased)
|
||||||
panic("handle_workitem_freeblocks: block count");
|
printf("handle_workitem_freeblocks: block count");
|
||||||
if (allerror)
|
if (allerror)
|
||||||
softdep_error("handle_workitem_freeblks", allerror);
|
softdep_error("handle_workitem_freeblks", allerror);
|
||||||
#endif /* DIAGNOSTIC */
|
#endif /* DIAGNOSTIC */
|
||||||
|
|
Loading…
Reference in New Issue