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 :-(.
This commit is contained in:
Doug Rabson 1998-09-20 21:42:20 +00:00
parent b554c7492a
commit 02c40feecd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39529

View File

@ -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);
}