John Dyson's patches (and a few from me too) to LFS to use a different
buffering scheme and make it more in tune with FreeBSD's vfs_bio implementation. The filesystem seems fairly stable, but I wouldn't recommend it to anyone not willing to experience problems. This is very green code and has the limitation that YOU CAN ONLY HAVE ONE LFS PARTITION MOUNTED AT A TIME. What LFS is good for: Non fsynced writes FASTER THAN FFS Large deletions Increadibly fast Reads are a little bit slower than FFS right now, but that is a factor of how under optimized this code is. LFS should in theory perform at least as well as FFS under fsync (iozone) type loads, and this is what I'm currently working on. Reviewed by: Justin Gibbs Submitted by: John Dyson Obtained from:
This commit is contained in:
parent
8a0403dcb9
commit
3d7002b0a0
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)lfs.h 8.3 (Berkeley) 9/23/93
|
||||
* $Id: lfs.h,v 1.3 1994/08/21 07:16:08 paul Exp $
|
||||
* $Id: lfs.h,v 1.4 1994/10/10 01:04:47 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _UFS_LFS_LFS_H_
|
||||
@ -110,6 +110,7 @@ struct lfs {
|
||||
daddr_t lfs_offset; /* offset in curseg for next partial */
|
||||
daddr_t lfs_lastpseg; /* address of last partial written */
|
||||
u_long lfs_tstamp; /* time stamp */
|
||||
long lfs_maxsymlinklen; /* max length of an internal symlink */
|
||||
|
||||
/* These are configuration parameters. */
|
||||
u_long lfs_minfree; /* minimum percentage of free blocks */
|
||||
@ -157,6 +158,7 @@ struct lfs {
|
||||
u_char lfs_flags; /* currently unused flag */
|
||||
u_char lfs_fsmnt[MNAMELEN]; /* name mounted on */
|
||||
u_char pad[3]; /* long-align */
|
||||
u_char pad2[156]; /* Block align */
|
||||
|
||||
/* Checksum; valid on disk. */
|
||||
u_long lfs_cksum; /* checksum for superblock checking */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)lfs_segment.c 8.5 (Berkeley) 1/4/94
|
||||
* $Id: lfs_segment.c,v 1.3 1994/08/02 07:54:36 davidg Exp $
|
||||
* $Id: lfs_segment.c,v 1.4 1994/08/20 03:49:02 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -63,6 +63,76 @@
|
||||
extern int count_lock_queue __P((void));
|
||||
|
||||
#define MAX_ACTIVE 10
|
||||
#define MAX_IO_BUFS 256
|
||||
#define MAX_IO_SIZE (1024*512)
|
||||
int lfs_total_io_size;
|
||||
int lfs_total_io_count;
|
||||
volatile int lfs_total_free_count;
|
||||
int lfs_free_needed;
|
||||
int lfs_in_buffer_reclaim;
|
||||
struct lfs_freebuf {
|
||||
int size;
|
||||
caddr_t address;
|
||||
} lfs_freebufs[MAX_IO_BUFS];
|
||||
|
||||
void
|
||||
lfs_free_buffer( caddr_t address, int size) {
|
||||
lfs_freebufs[lfs_total_free_count].address = address;
|
||||
lfs_freebufs[lfs_total_free_count].size = size;
|
||||
++lfs_total_free_count;
|
||||
if( lfs_free_needed) {
|
||||
wakeup((caddr_t) &lfs_free_needed);
|
||||
lfs_free_needed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lfs_reclaim_buffers() {
|
||||
int i,s;
|
||||
int reclaimed = 0;
|
||||
if( lfs_in_buffer_reclaim)
|
||||
return;
|
||||
lfs_in_buffer_reclaim = 1;
|
||||
s = splhigh();
|
||||
for(i=0;i<lfs_total_free_count;i++) {
|
||||
reclaimed = 1;
|
||||
splx(s);
|
||||
free(lfs_freebufs[i].address, M_SEGMENT);
|
||||
s = splhigh();
|
||||
lfs_total_io_size -= lfs_freebufs[i].size;
|
||||
lfs_total_io_count -= 1;
|
||||
}
|
||||
lfs_in_buffer_reclaim = 0;
|
||||
lfs_total_free_count = 0;
|
||||
splx(s);
|
||||
if( reclaimed) {
|
||||
wakeup((caddr_t) &lfs_free_needed);
|
||||
}
|
||||
}
|
||||
|
||||
caddr_t
|
||||
lfs_alloc_buffer(int size) {
|
||||
int s;
|
||||
caddr_t rtval;
|
||||
if( lfs_total_free_count)
|
||||
lfs_reclaim_buffers();
|
||||
s = splhigh();
|
||||
while( ((lfs_total_io_count+1) >= MAX_IO_BUFS) ||
|
||||
(lfs_total_io_size >= MAX_IO_SIZE)) {
|
||||
lfs_free_needed = 1;
|
||||
tsleep(&lfs_free_needed, PRIBIO, "lfsalc", 0);
|
||||
splx(s);
|
||||
lfs_reclaim_buffers();
|
||||
s = splhigh();
|
||||
}
|
||||
splx(s);
|
||||
lfs_total_io_size += size;
|
||||
lfs_total_io_count += 1;
|
||||
rtval = malloc(size, M_SEGMENT, M_WAITOK);
|
||||
return rtval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine if it's OK to start a partial in this segment, or if we need
|
||||
* to go on to a new segment.
|
||||
@ -227,7 +297,7 @@ lfs_segwrite(mp, flags)
|
||||
clean = cip->clean;
|
||||
brelse(bp);
|
||||
if (clean <= 2) {
|
||||
printf ("segs clean: %d\n", clean);
|
||||
printf("segs clean: %d\n", clean);
|
||||
wakeup(&lfs_allclean_wakeup);
|
||||
if (error = tsleep(&fs->lfs_avail, PRIBIO + 1,
|
||||
"lfs writer", 0))
|
||||
@ -596,7 +666,7 @@ lfs_updatemeta(sp)
|
||||
* to get counted for the inode.
|
||||
*/
|
||||
if (bp->b_blkno == -1 && !(bp->b_flags & B_CACHE)) {
|
||||
printf ("Updatemeta allocating indirect block: shouldn't happen\n");
|
||||
printf ("Updatemeta allocating indirect block: shouldn't happen\n");
|
||||
ip->i_blocks += btodb(fs->lfs_bsize);
|
||||
fs->lfs_bfree -= btodb(fs->lfs_bsize);
|
||||
}
|
||||
@ -858,10 +928,13 @@ lfs_writeseg(fs, sp)
|
||||
B_LOCKED | B_GATHERED);
|
||||
if (bp->b_flags & B_CALL) {
|
||||
/* if B_CALL, it was created with newbuf */
|
||||
brelvp(bp);
|
||||
if (!(bp->b_flags & B_INVAL))
|
||||
/*
|
||||
free(bp->b_data, M_SEGMENT);
|
||||
free(bp, M_SEGMENT);
|
||||
*/
|
||||
lfs_free_buffer( bp->b_data, roundup( bp->b_bufsize, DEV_BSIZE));
|
||||
/* free(bp, M_SEGMENT); */
|
||||
relpbuf(bp);
|
||||
} else {
|
||||
bremfree(bp);
|
||||
bp->b_flags |= B_DONE;
|
||||
@ -998,10 +1071,12 @@ lfs_newbuf(vp, daddr, size)
|
||||
size_t nbytes;
|
||||
|
||||
nbytes = roundup(size, DEV_BSIZE);
|
||||
bp = malloc(sizeof(struct buf), M_SEGMENT, M_WAITOK);
|
||||
bzero(bp, sizeof(struct buf));
|
||||
/* bp = malloc(sizeof(struct buf), M_SEGMENT, M_WAITOK); */
|
||||
bp = getpbuf();
|
||||
/* bzero(bp, sizeof(struct buf)); */
|
||||
if (nbytes)
|
||||
bp->b_data = malloc(nbytes, M_SEGMENT, M_WAITOK);
|
||||
/* bp->b_data = malloc(nbytes, M_SEGMENT, M_WAITOK); */
|
||||
bp->b_data = lfs_alloc_buffer( nbytes);
|
||||
bgetvp(vp, bp);
|
||||
bp->b_bufsize = size;
|
||||
bp->b_bcount = size;
|
||||
@ -1028,18 +1103,25 @@ lfs_callback(bp)
|
||||
if (--fs->lfs_iocount == 0)
|
||||
wakeup(&fs->lfs_iocount);
|
||||
|
||||
brelvp(bp);
|
||||
/*
|
||||
free(bp->b_data, M_SEGMENT);
|
||||
free(bp, M_SEGMENT);
|
||||
*/
|
||||
lfs_free_buffer( bp->b_data, roundup( bp->b_bufsize, DEV_BSIZE));
|
||||
relpbuf(bp);
|
||||
}
|
||||
|
||||
void
|
||||
lfs_supercallback(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
brelvp(bp);
|
||||
if( bp->b_data)
|
||||
lfs_free_buffer( bp->b_data, roundup( bp->b_bufsize, DEV_BSIZE));
|
||||
relpbuf(bp);
|
||||
/*
|
||||
free(bp->b_data, M_SEGMENT);
|
||||
free(bp, M_SEGMENT);
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1109,3 +1191,5 @@ lfs_vunref(vp)
|
||||
vrele(vp);
|
||||
lfs_no_inactive = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)lfs_subr.c 8.2 (Berkeley) 9/21/93
|
||||
* $Id$
|
||||
* $Id: lfs_subr.c,v 1.3 1994/08/02 07:54:37 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -146,9 +146,11 @@ lfs_segunlock(fs)
|
||||
if (sp->bpp != sp->cbpp) {
|
||||
/* Free allocated segment summary */
|
||||
fs->lfs_offset -= LFS_SUMMARY_SIZE / DEV_BSIZE;
|
||||
brelvp(*sp->bpp);
|
||||
free((*sp->bpp)->b_data, M_SEGMENT);
|
||||
free(*sp->bpp, M_SEGMENT);
|
||||
/* free((*sp->bpp)->b_data, M_SEGMENT); */
|
||||
lfs_free_buffer((*sp->bpp)->b_data, roundup( (*sp->bpp)->b_bufsize, DEV_BSIZE));
|
||||
/* free(*sp->bpp, M_SEGMENT); */
|
||||
relpbuf(*sp->bpp);
|
||||
|
||||
} else
|
||||
printf ("unlock to 0 with no summary");
|
||||
free(sp->bpp, M_SEGMENT);
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)lfs_syscalls.c 8.5 (Berkeley) 4/20/94
|
||||
* $Id$
|
||||
* $Id: lfs_syscalls.c,v 1.3 1994/08/02 07:54:38 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -239,7 +239,10 @@ err2: lfs_vunref(vp);
|
||||
for (bpp = --sp->cbpp; bpp >= sp->bpp; --bpp)
|
||||
if ((*bpp)->b_flags & B_CALL) {
|
||||
brelvp(*bpp);
|
||||
/*
|
||||
free(*bpp, M_SEGMENT);
|
||||
*/
|
||||
relpbuf(*bpp);
|
||||
} else
|
||||
brelse(*bpp);
|
||||
lfs_segunlock(fs);
|
||||
@ -562,3 +565,5 @@ lfs_fakebuf(vp, lbn, size, uaddr)
|
||||
bp->b_flags |= B_INVAL;
|
||||
return (bp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)lfs_vfsops.c 8.7 (Berkeley) 4/16/94
|
||||
* $Id: lfs_vfsops.c,v 1.7 1994/10/28 12:42:05 jkh Exp $
|
||||
* $Id: lfs_vfsops.c,v 1.8 1994/11/14 13:21:53 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -277,6 +277,7 @@ lfs_mountfs(devvp, mp, p)
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
mp->mnt_stat.f_fsid.val[1] = MOUNT_LFS;
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
mp->mnt_maxsymlinklen = fs->lfs_maxsymlinklen;
|
||||
ump->um_mountp = mp;
|
||||
ump->um_dev = dev;
|
||||
ump->um_devvp = devvp;
|
||||
|
Loading…
Reference in New Issue
Block a user