Some additional performance improvements. When freeing an inode
check to see if it has been committed to disk. If it has never been written, it can be freed immediately. For short lived files this change allows the same inode to be reused repeatedly. Similarly, when upgrading a fragment to a larger size, if it has never been claimed by an inode on disk, it too can be freed immediately making it available for reuse often in the next slowly growing block of the same file.
This commit is contained in:
parent
ce5163041d
commit
d3abb52714
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=61812
@ -52,7 +52,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ffs_softdep.c 9.56 (McKusick) 1/17/00
|
||||
* from: @(#)ffs_softdep.c 9.57 (McKusick) 3/17/00
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -1525,19 +1525,22 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
oldaip; oldaip = LIST_NEXT(oldaip, ai_next))
|
||||
if (oldaip->ai_offset == aip->ai_offset)
|
||||
break;
|
||||
freefrag = NULL;
|
||||
if (oldaip != NULL) {
|
||||
if (oldaip->ai_newblkno != aip->ai_oldblkno)
|
||||
panic("setup_allocindir_phase2: blkno");
|
||||
aip->ai_oldblkno = oldaip->ai_oldblkno;
|
||||
freefrag = oldaip->ai_freefrag;
|
||||
oldaip->ai_freefrag = aip->ai_freefrag;
|
||||
aip->ai_freefrag = freefrag;
|
||||
freefrag = aip->ai_freefrag;
|
||||
aip->ai_freefrag = oldaip->ai_freefrag;
|
||||
oldaip->ai_freefrag = NULL;
|
||||
free_allocindir(oldaip, NULL);
|
||||
}
|
||||
LIST_INSERT_HEAD(&indirdep->ir_deplisthd, aip, ai_next);
|
||||
((ufs_daddr_t *)indirdep->ir_savebp->b_data)
|
||||
[aip->ai_offset] = aip->ai_oldblkno;
|
||||
FREE_LOCK(&lk);
|
||||
if (freefrag != NULL)
|
||||
handle_workitem_freefrag(freefrag);
|
||||
}
|
||||
if (newindirdep) {
|
||||
if (indirdep->ir_savebp != NULL)
|
||||
@ -1603,7 +1606,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
struct vnode *vp;
|
||||
struct buf *bp;
|
||||
struct fs *fs;
|
||||
int i, error;
|
||||
int i, delay, error;
|
||||
|
||||
fs = ip->i_fs;
|
||||
if (length != 0)
|
||||
@ -1653,10 +1656,13 @@ softdep_setup_freeblocks(ip, length)
|
||||
* with this inode are obsolete and can simply be de-allocated.
|
||||
* We must first merge the two dependency lists to get rid of
|
||||
* any duplicate freefrag structures, then purge the merged list.
|
||||
* If we still have a bitmap dependency, then the inode has never
|
||||
* been written to disk, so we can free any fragments without delay.
|
||||
*/
|
||||
merge_inode_lists(inodedep);
|
||||
delay = (inodedep->id_state & DEPCOMPLETE);
|
||||
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, delay);
|
||||
FREE_LOCK(&lk);
|
||||
bdwrite(bp);
|
||||
/*
|
||||
@ -3157,7 +3163,7 @@ handle_allocdirect_partdone(adp)
|
||||
{
|
||||
struct allocdirect *listadp;
|
||||
struct inodedep *inodedep;
|
||||
long bsize;
|
||||
long bsize, delay;
|
||||
|
||||
if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
|
||||
return;
|
||||
@ -3207,12 +3213,16 @@ handle_allocdirect_partdone(adp)
|
||||
/*
|
||||
* If we have found the just finished dependency, then free
|
||||
* it along with anything that follows it that is complete.
|
||||
* If the inode still has a bitmap dependency, then it has
|
||||
* never been written to disk, hence the on-disk inode cannot
|
||||
* reference the old fragment so we can free it without delay.
|
||||
*/
|
||||
delay = (inodedep->id_state & DEPCOMPLETE);
|
||||
for (; adp; adp = listadp) {
|
||||
listadp = TAILQ_NEXT(adp, ad_next);
|
||||
if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
|
||||
return;
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, delay);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ffs_softdep.c 9.56 (McKusick) 1/17/00
|
||||
* from: @(#)ffs_softdep.c 9.57 (McKusick) 3/17/00
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -1525,19 +1525,22 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
oldaip; oldaip = LIST_NEXT(oldaip, ai_next))
|
||||
if (oldaip->ai_offset == aip->ai_offset)
|
||||
break;
|
||||
freefrag = NULL;
|
||||
if (oldaip != NULL) {
|
||||
if (oldaip->ai_newblkno != aip->ai_oldblkno)
|
||||
panic("setup_allocindir_phase2: blkno");
|
||||
aip->ai_oldblkno = oldaip->ai_oldblkno;
|
||||
freefrag = oldaip->ai_freefrag;
|
||||
oldaip->ai_freefrag = aip->ai_freefrag;
|
||||
aip->ai_freefrag = freefrag;
|
||||
freefrag = aip->ai_freefrag;
|
||||
aip->ai_freefrag = oldaip->ai_freefrag;
|
||||
oldaip->ai_freefrag = NULL;
|
||||
free_allocindir(oldaip, NULL);
|
||||
}
|
||||
LIST_INSERT_HEAD(&indirdep->ir_deplisthd, aip, ai_next);
|
||||
((ufs_daddr_t *)indirdep->ir_savebp->b_data)
|
||||
[aip->ai_offset] = aip->ai_oldblkno;
|
||||
FREE_LOCK(&lk);
|
||||
if (freefrag != NULL)
|
||||
handle_workitem_freefrag(freefrag);
|
||||
}
|
||||
if (newindirdep) {
|
||||
if (indirdep->ir_savebp != NULL)
|
||||
@ -1603,7 +1606,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
struct vnode *vp;
|
||||
struct buf *bp;
|
||||
struct fs *fs;
|
||||
int i, error;
|
||||
int i, delay, error;
|
||||
|
||||
fs = ip->i_fs;
|
||||
if (length != 0)
|
||||
@ -1653,10 +1656,13 @@ softdep_setup_freeblocks(ip, length)
|
||||
* with this inode are obsolete and can simply be de-allocated.
|
||||
* We must first merge the two dependency lists to get rid of
|
||||
* any duplicate freefrag structures, then purge the merged list.
|
||||
* If we still have a bitmap dependency, then the inode has never
|
||||
* been written to disk, so we can free any fragments without delay.
|
||||
*/
|
||||
merge_inode_lists(inodedep);
|
||||
delay = (inodedep->id_state & DEPCOMPLETE);
|
||||
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, delay);
|
||||
FREE_LOCK(&lk);
|
||||
bdwrite(bp);
|
||||
/*
|
||||
@ -3157,7 +3163,7 @@ handle_allocdirect_partdone(adp)
|
||||
{
|
||||
struct allocdirect *listadp;
|
||||
struct inodedep *inodedep;
|
||||
long bsize;
|
||||
long bsize, delay;
|
||||
|
||||
if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
|
||||
return;
|
||||
@ -3207,12 +3213,16 @@ handle_allocdirect_partdone(adp)
|
||||
/*
|
||||
* If we have found the just finished dependency, then free
|
||||
* it along with anything that follows it that is complete.
|
||||
* If the inode still has a bitmap dependency, then it has
|
||||
* never been written to disk, hence the on-disk inode cannot
|
||||
* reference the old fragment so we can free it without delay.
|
||||
*/
|
||||
delay = (inodedep->id_state & DEPCOMPLETE);
|
||||
for (; adp; adp = listadp) {
|
||||
listadp = TAILQ_NEXT(adp, ad_next);
|
||||
if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
|
||||
return;
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
||||
free_allocdirect(&inodedep->id_inoupdt, adp, delay);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user