summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2000-06-18 22:05:57 +0000
committermckusick <mckusick@FreeBSD.org>2000-06-18 22:05:57 +0000
commitcad96185660b12cbc2d07e6fdb03d14d1018aece (patch)
treefef115668c40653e641199db6c4f4870c2af4745
parent938731aa89afb6c22801a87ea5e9d7a423e16c19 (diff)
downloadFreeBSD-src-cad96185660b12cbc2d07e6fdb03d14d1018aece.zip
FreeBSD-src-cad96185660b12cbc2d07e6fdb03d14d1018aece.tar.gz
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.
-rw-r--r--sys/contrib/softupdates/ffs_softdep.c26
-rw-r--r--sys/ufs/ffs/ffs_softdep.c26
2 files changed, 36 insertions, 16 deletions
diff --git a/sys/contrib/softupdates/ffs_softdep.c b/sys/contrib/softupdates/ffs_softdep.c
index 870d6ac..6773d17 100644
--- a/sys/contrib/softupdates/ffs_softdep.c
+++ b/sys/contrib/softupdates/ffs_softdep.c
@@ -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);
}
}
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 870d6ac..6773d17 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -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);
}
}
OpenPOWER on IntegriCloud