Optimize the free list search a little more; in particular use words
instead of bytes for the index, and never search below fs->lfs_freehd. Fix a bug in the previous version of the search (an erroneous assumption that ino_t was signed). Free the bitmap when we unmount the filesystem.
This commit is contained in:
parent
017f856cba
commit
07ebfab840
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs.h,v 1.100 2006/04/08 00:26:34 perseant Exp $ */
|
||||
/* $NetBSD: lfs.h,v 1.101 2006/04/10 21:20:19 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
|
||||
@ -472,7 +472,7 @@ struct ifile_v1 {
|
||||
if ((_e = bread((F)->lfs_ivnode, \
|
||||
(IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \
|
||||
(F)->lfs_bsize, NOCRED, &(BP))) != 0) \
|
||||
panic("lfs: ifile read %d", _e); \
|
||||
panic("lfs: ifile ino %d read %d", (int)(IN), _e); \
|
||||
if ((F)->lfs_version == 1) \
|
||||
(IP) = (IFILE *)((IFILE_V1 *)(BP)->b_data + \
|
||||
(IN) % (F)->lfs_ifpb); \
|
||||
@ -697,6 +697,9 @@ struct dlfs {
|
||||
u_int32_t dlfs_cksum; /* 508: checksum for superblock checking */
|
||||
};
|
||||
|
||||
/* Type used for the inode bitmap */
|
||||
typedef u_int32_t lfs_bm_t;
|
||||
|
||||
/*
|
||||
* In-memory super block.
|
||||
*/
|
||||
@ -812,7 +815,7 @@ struct lfs {
|
||||
struct simplelock lfs_interlock; /* lock for lfs_seglock */
|
||||
int lfs_sleepers; /* # procs sleeping this fs */
|
||||
int lfs_pages; /* dirty pages blaming this fs */
|
||||
u_int8_t *lfs_ino_bitmap; /* Inuse inodes bitmap */
|
||||
lfs_bm_t *lfs_ino_bitmap; /* Inuse inodes bitmap */
|
||||
};
|
||||
|
||||
/* NINDIR is the number of indirects in a file system block. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_alloc.c,v 1.87 2006/04/08 00:16:56 perseant Exp $ */
|
||||
/* $NetBSD: lfs_alloc.c,v 1.88 2006/04/10 21:20:19 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
|
||||
@ -67,7 +67,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lfs_alloc.c,v 1.87 2006/04/08 00:16:56 perseant Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lfs_alloc.c,v 1.88 2006/04/10 21:20:19 perseant Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_quota.h"
|
||||
@ -101,14 +101,21 @@ static int lfs_ialloc(struct lfs *, struct vnode *, ino_t, int,
|
||||
struct vnode **);
|
||||
|
||||
/* Constants for inode free bitmap */
|
||||
#define BYTESHIFT 3 /* 8 = 2 ** 3 */
|
||||
#define BYTEMASK 0x7 /* 8 - 1 */
|
||||
#define SET_BITMAP_FREE(F, I) \
|
||||
(F)->lfs_ino_bitmap[(I) >> BYTESHIFT] |= (1 << ((I) & BYTEMASK))
|
||||
#define CLR_BITMAP_FREE(F, I) \
|
||||
(F)->lfs_ino_bitmap[(I) >> BYTESHIFT] &= ~(1 << ((I) & BYTEMASK))
|
||||
#define BMSHIFT 5 /* 2 ** 5 = 32 */
|
||||
#define BMMASK ((1 << BMSHIFT) - 1)
|
||||
#define SET_BITMAP_FREE(F, I) do { \
|
||||
DLOG((DLOG_ALLOC, "lfs: ino %d wrd %d bit %d set\n", (int)(I), \
|
||||
(int)((I) >> BMSHIFT), (int)((I) & BMMASK))); \
|
||||
(F)->lfs_ino_bitmap[(I) >> BMSHIFT] |= (1 << ((I) & BMMASK)); \
|
||||
} while (0)
|
||||
#define CLR_BITMAP_FREE(F, I) do { \
|
||||
DLOG((DLOG_ALLOC, "lfs: ino %d wrd %d bit %d clr\n", (int)(I), \
|
||||
(int)((I) >> BMSHIFT), (int)((I) & BMMASK))); \
|
||||
(F)->lfs_ino_bitmap[(I) >> BMSHIFT] &= ~(1 << ((I) & BMMASK)); \
|
||||
} while(0)
|
||||
|
||||
#define ISSET_BITMAP_FREE(F, I) \
|
||||
((F)->lfs_ino_bitmap[(I) >> BYTESHIFT] & (1 << ((I) & BYTEMASK)))
|
||||
((F)->lfs_ino_bitmap[(I) >> BMSHIFT] & (1 << ((I) & BMMASK)))
|
||||
|
||||
/*
|
||||
* Allocate a particular inode with a particular version number, freeing
|
||||
@ -257,11 +264,12 @@ extend_ifile(struct lfs *fs, struct ucred *cred)
|
||||
ip->i_ffs1_size = ip->i_size;
|
||||
uvm_vnp_setsize(vp, ip->i_size);
|
||||
|
||||
maxino = ((fs->lfs_ivnode->v_size >> fs->lfs_bshift) -
|
||||
fs->lfs_cleansz - fs->lfs_segtabsz) * fs->lfs_ifpb;
|
||||
fs->lfs_ino_bitmap = realloc(fs->lfs_ino_bitmap,
|
||||
(maxino + BYTEMASK) >> BYTESHIFT,
|
||||
M_SEGMENT, M_WAITOK);
|
||||
maxino = ((ip->i_size >> fs->lfs_bshift) - fs->lfs_cleansz -
|
||||
fs->lfs_segtabsz) * fs->lfs_ifpb;
|
||||
fs->lfs_ino_bitmap = (lfs_bm_t *)
|
||||
realloc(fs->lfs_ino_bitmap, ((maxino + BMMASK) >> BMSHIFT) *
|
||||
sizeof(lfs_bm_t), M_SEGMENT, M_WAITOK);
|
||||
KASSERT(fs->lfs_ino_bitmap != NULL);
|
||||
|
||||
i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
|
||||
fs->lfs_ifpb;
|
||||
@ -497,23 +505,36 @@ lfs_last_alloc_ino(struct lfs *fs)
|
||||
static inline ino_t
|
||||
lfs_freelist_prev(struct lfs *fs, ino_t ino)
|
||||
{
|
||||
ino_t tino;
|
||||
struct buf *bp;
|
||||
IFILE *ifp;
|
||||
ino_t tino, bound, bb, freehdbb;
|
||||
|
||||
if (fs->lfs_freehd == LFS_UNUSED_INUM) /* No free inodes at all */
|
||||
return LFS_UNUSED_INUM;
|
||||
|
||||
/* Search our own word first */
|
||||
bound = ino & ~BMMASK;
|
||||
for (tino = ino - 1; tino > bound && tino > LFS_UNUSED_INUM; tino--)
|
||||
if (ISSET_BITMAP_FREE(fs, tino))
|
||||
return tino;
|
||||
/* If there are no lower words to search, just return */
|
||||
if (ino >> BMSHIFT == 0)
|
||||
return LFS_UNUSED_INUM;
|
||||
|
||||
/*
|
||||
* Find a word with a free inode in it. We have to be a bit
|
||||
* careful here since ino_t is unsigned.
|
||||
*/
|
||||
freehdbb = (fs->lfs_freehd >> BMSHIFT);
|
||||
for (bb = (ino >> BMSHIFT) - 1; bb >= freehdbb && bb > 0; --bb)
|
||||
if (fs->lfs_ino_bitmap[bb])
|
||||
break;
|
||||
if (fs->lfs_ino_bitmap[bb] == 0)
|
||||
return LFS_UNUSED_INUM;
|
||||
|
||||
/* Search the word we found */
|
||||
for (tino = (bb << BMSHIFT) | BMMASK; tino > LFS_UNUSED_INUM; tino--)
|
||||
if (ISSET_BITMAP_FREE(fs, tino))
|
||||
break;
|
||||
|
||||
for (tino = ino - 1; tino > LFS_UNUSED_INUM; tino--) {
|
||||
if (fs->lfs_ino_bitmap) {
|
||||
if (ISSET_BITMAP_FREE(fs, tino))
|
||||
break;
|
||||
} else {
|
||||
LFS_IENTRY(ifp, fs, tino, bp);
|
||||
if (ifp->if_daddr == LFS_UNUSED_DADDR) {
|
||||
brelse(bp);
|
||||
break;
|
||||
}
|
||||
brelse(bp);
|
||||
}
|
||||
}
|
||||
if (tino <= LFS_IFILE_INUM)
|
||||
tino = LFS_UNUSED_INUM;
|
||||
|
||||
@ -542,6 +563,7 @@ lfs_vfree(struct vnode *vp, ino_t ino, int mode)
|
||||
ino = ip->i_number;
|
||||
|
||||
ASSERT_NO_SEGLOCK(fs);
|
||||
DLOG((DLOG_ALLOC, "lfs_vfree: free ino %lld\n", (long long)ino));
|
||||
|
||||
/* Drain of pending writes */
|
||||
simple_lock(&vp->v_interlock);
|
||||
@ -595,7 +617,7 @@ lfs_vfree(struct vnode *vp, ino_t ino, int mode)
|
||||
LFS_IENTRY(ifp, fs, ino, bp);
|
||||
LFS_GET_HEADFREE(fs, cip, cbp, &(ifp->if_nextfree));
|
||||
LFS_PUT_HEADFREE(fs, cip, cbp, ino);
|
||||
DLOG((DLOG_ALLOC, "lfs_valloc: headfree %lld -> %lld\n",
|
||||
DLOG((DLOG_ALLOC, "lfs_vfree: headfree %lld -> %lld\n",
|
||||
(long long)ifp->if_nextfree, (long long)ino));
|
||||
LFS_BWRITE_LOG(bp); /* Ifile */
|
||||
|
||||
@ -683,8 +705,10 @@ lfs_order_freelist(struct lfs *fs)
|
||||
|
||||
maxino = ((fs->lfs_ivnode->v_size >> fs->lfs_bshift) -
|
||||
fs->lfs_cleansz - fs->lfs_segtabsz) * fs->lfs_ifpb;
|
||||
fs->lfs_ino_bitmap = malloc((maxino + BYTEMASK) >> BYTESHIFT,
|
||||
M_SEGMENT, M_WAITOK | M_ZERO);
|
||||
fs->lfs_ino_bitmap = (lfs_bm_t *)
|
||||
malloc(((maxino + BMMASK) >> BMSHIFT) * sizeof(lfs_bm_t),
|
||||
M_SEGMENT, M_WAITOK | M_ZERO);
|
||||
KASSERT(fs->lfs_ino_bitmap != NULL);
|
||||
|
||||
firstino = lastino = LFS_UNUSED_INUM;
|
||||
for (ino = 0; ino < maxino; ino++) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_vfsops.c,v 1.201 2006/04/10 18:42:48 perseant Exp $ */
|
||||
/* $NetBSD: lfs_vfsops.c,v 1.202 2006/04/10 21:20:19 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
|
||||
@ -67,7 +67,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.201 2006/04/10 18:42:48 perseant Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.202 2006/04/10 21:20:19 perseant Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_quota.h"
|
||||
@ -1449,6 +1449,7 @@ lfs_unmount(struct mount *mp, int mntflags, struct lwp *l)
|
||||
fs->lfs_pages, lfs_subsys_pages);
|
||||
|
||||
/* Free per-mount data structures */
|
||||
free(fs->lfs_ino_bitmap, M_SEGMENT);
|
||||
free(fs->lfs_suflags[0], M_SEGMENT);
|
||||
free(fs->lfs_suflags[1], M_SEGMENT);
|
||||
free(fs->lfs_suflags, M_SEGMENT);
|
||||
|
Loading…
Reference in New Issue
Block a user