diff options
author | dfr <dfr@FreeBSD.org> | 1998-09-20 21:42:20 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 1998-09-20 21:42:20 +0000 |
commit | 48b3e5470102066f456686c366cf49009cf063b3 (patch) | |
tree | cb32b6a85aa2c8acb5f3d9ae7cbb49bdb8a9fb90 /lib/libstand/ufs.c | |
parent | 0c4d54326b22d40a5283b0904333f7f4b75e35a3 (diff) | |
download | FreeBSD-src-48b3e5470102066f456686c366cf49009cf063b3.zip FreeBSD-src-48b3e5470102066f456686c366cf49009cf063b3.tar.gz |
Allocate disk buffers using a custom allocator. The standard allocator fragments
extremely badly if disk buffers are freed back into the main heap and the alpha
bootstrap has a restricted address space which just ran out :-(.
Diffstat (limited to 'lib/libstand/ufs.c')
-rw-r--r-- | lib/libstand/ufs.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/lib/libstand/ufs.c b/lib/libstand/ufs.c index 1c7fd90..a32fe06 100644 --- a/lib/libstand/ufs.c +++ b/lib/libstand/ufs.c @@ -113,6 +113,39 @@ static int search_directory(char *, struct open_file *, ino_t *); static void ffs_oldfscompat(struct fs *); #endif +static void *buffers4 = 0; +static void *buffers8 = 0; + +static void * +getbuf(size_t size) +{ + void *p = 0; + if (size == 8192 && buffers8) { + p = buffers8; + buffers8 = *(void **) p; + } + if (size == 4096 && buffers4) { + p = buffers4; + buffers4 = *(void **) p; + } + if (!p) + p = malloc(size); + return p; +} + +static void +relbuf(void *p, size_t size) +{ + if (size == 8192) { + *(void**) p = buffers8; + buffers8 = p; + } else if (size == 4096) { + *(void**) p = buffers4; + buffers8 = p; + } else + free(p); +} + /* * Read a new inode into a file structure. */ @@ -130,7 +163,7 @@ read_inode(inumber, f) /* * Read inode and save it. */ - buf = malloc(fs->fs_bsize); + buf = getbuf(fs->fs_bsize); twiddle(); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize, @@ -160,7 +193,7 @@ read_inode(inumber, f) fp->f_buf_blkno = -1; } out: - free(buf); + relbuf(buf, fs->fs_bsize); return (rc); } @@ -240,7 +273,7 @@ block_map(f, file_block, disk_block_p) if (fp->f_blkno[level] != ind_block_num) { if (fp->f_blk[level] == (char *)0) fp->f_blk[level] = - malloc(fs->fs_bsize); + getbuf(fs->fs_bsize); twiddle(); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fp->f_fs, ind_block_num), @@ -298,7 +331,7 @@ buf_read_file(f, buf_p, size_p) return (rc); if (fp->f_buf == (char *)0) - fp->f_buf = malloc(fs->fs_bsize); + fp->f_buf = getbuf(fs->fs_bsize); if (disk_block == 0) { bzero(fp->f_buf, block_size); @@ -409,7 +442,7 @@ ufs_open(upath, f) f->f_fsdata = (void *)fp; /* allocate space and read super block */ - fs = malloc(SBSIZE); + fs = getbuf(SBSIZE); fp->f_fs = fs; twiddle(); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, @@ -530,7 +563,7 @@ ufs_open(upath, f) register struct fs *fs = fp->f_fs; if (!buf) - buf = malloc(fs->fs_bsize); + buf = getbuf(fs->fs_bsize); rc = block_map(f, (daddr_t)0, &disk_block); if (rc) goto out; @@ -566,12 +599,12 @@ ufs_open(upath, f) rc = 0; out: if (buf) - free(buf); + relbuf(buf, fs->fs_bsize); if (path) free(path); if (rc) { if (fp->f_buf) - free(fp->f_buf); + relbuf(fp->f_buf, fs->fs_bsize); free(fp->f_fs); free(fp); } @@ -583,6 +616,7 @@ ufs_close(f) struct open_file *f; { register struct file *fp = (struct file *)f->f_fsdata; + struct fs *fs = fp->f_fs; int level; f->f_fsdata = (void *)0; @@ -591,11 +625,11 @@ ufs_close(f) for (level = 0; level < NIADDR; level++) { if (fp->f_blk[level]) - free(fp->f_blk[level]); + relbuf(fp->f_blk[level], fs->fs_bsize); } if (fp->f_buf) - free(fp->f_buf); - free(fp->f_fs); + relbuf(fp->f_buf, fs->fs_bsize); + relbuf(fp->f_fs, SBSIZE); free(fp); return (0); } |