summaryrefslogtreecommitdiff
path: root/lib/libc/db/mpool/mpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/db/mpool/mpool.c')
-rw-r--r--lib/libc/db/mpool/mpool.c82
1 files changed, 65 insertions, 17 deletions
diff --git a/lib/libc/db/mpool/mpool.c b/lib/libc/db/mpool/mpool.c
index ab98c8e5c59..008132644f1 100644
--- a/lib/libc/db/mpool/mpool.c
+++ b/lib/libc/db/mpool/mpool.c
@@ -1,3 +1,5 @@
+/* $OpenBSD: mpool.c,v 1.6 1999/02/15 05:11:25 millert Exp $ */
+
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -32,7 +34,11 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: mpool.c,v 1.5 1998/08/28 20:49:11 deraadt Exp $";
+#if 0
+static char sccsid[] = "@(#)mpool.c 8.7 (Berkeley) 11/2/95";
+#else
+static char rcsid[] = "$OpenBSD: mpool.c,v 1.6 1999/02/15 05:11:25 millert Exp $";
+#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -116,9 +122,10 @@ mpool_filter(mp, pgin, pgout, pgcookie)
* Get a new page of memory.
*/
void *
-mpool_new(mp, pgnoaddr)
+mpool_new(mp, pgnoaddr, flags)
MPOOL *mp;
pgno_t *pgnoaddr;
+ u_int flags;
{
struct _hqh *head;
BKT *bp;
@@ -137,8 +144,13 @@ mpool_new(mp, pgnoaddr)
*/
if ((bp = mpool_bkt(mp)) == NULL)
return (NULL);
- *pgnoaddr = bp->pgno = mp->npages++;
- bp->flags = MPOOL_PINNED;
+ if (flags == MPOOL_PAGE_REQUEST) {
+ mp->npages++;
+ bp->pgno = *pgnoaddr;
+ } else
+ bp->pgno = *pgnoaddr = mp->npages++;
+
+ bp->flags = MPOOL_PINNED | MPOOL_INUSE;
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_INSERT_HEAD(head, bp, hq);
@@ -146,6 +158,33 @@ mpool_new(mp, pgnoaddr)
return (bp->page);
}
+int
+mpool_delete(mp, page)
+ MPOOL *mp;
+ void *page;
+{
+ struct _hqh *head;
+ BKT *bp;
+
+ bp = (BKT *)((char *)page - sizeof(BKT));
+
+#ifdef DEBUG
+ if (!(bp->flags & MPOOL_PINNED)) {
+ (void)fprintf(stderr,
+ "mpool_delete: page %d not pinned\n", bp->pgno);
+ abort();
+ }
+#endif
+
+ /* Remove from the hash and lru queues. */
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ CIRCLEQ_REMOVE(head, bp, hq);
+ CIRCLEQ_REMOVE(&mp->lqh, bp, q);
+
+ free(bp);
+ return (RET_SUCCESS);
+}
+
/*
* mpool_get
* Get a page.
@@ -162,12 +201,6 @@ mpool_get(mp, pgno, flags)
off_t off;
int nr;
- /* Check for attempt to retrieve a non-existent page. */
- if (pgno >= mp->npages) {
- errno = EINVAL;
- return (NULL);
- }
-
#ifdef STATISTICS
++mp->pageget;
#endif
@@ -175,7 +208,7 @@ mpool_get(mp, pgno, flags)
/* Check for a page that is cached. */
if ((bp = mpool_look(mp, pgno)) != NULL) {
#ifdef DEBUG
- if (bp->flags & MPOOL_PINNED) {
+ if (!(flags & MPOOL_IGNOREPIN) && bp->flags & MPOOL_PINNED) {
(void)fprintf(stderr,
"mpool_get: page %d already pinned\n", bp->pgno);
abort();
@@ -207,15 +240,26 @@ mpool_get(mp, pgno, flags)
off = mp->pagesize * pgno;
if (lseek(mp->fd, off, SEEK_SET) != off)
return (NULL);
+
if ((nr = read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) {
- if (nr >= 0)
- errno = EFTYPE;
- return (NULL);
+ if (nr > 0) {
+ /* A partial read is definitely bad. */
+ errno = EINVAL;
+ return (NULL);
+ } else {
+ /*
+ * A zero-length reads, means you need to create a
+ * new page.
+ */
+ memset(bp->page, 0, mp->pagesize);
+ }
}
/* Set the page number, pin the page. */
bp->pgno = pgno;
- bp->flags = MPOOL_PINNED;
+ if (!(flags & MPOOL_IGNOREPIN))
+ bp->flags = MPOOL_PINNED;
+ bp->flags |= MPOOL_INUSE;
/*
* Add the page to the head of the hash chain and the tail
@@ -257,7 +301,8 @@ mpool_put(mp, page, flags)
}
#endif
bp->flags &= ~MPOOL_PINNED;
- bp->flags |= flags & MPOOL_DIRTY;
+ if (flags & MPOOL_DIRTY)
+ bp->flags |= flags & MPOOL_DIRTY;
return (RET_SUCCESS);
}
@@ -345,6 +390,7 @@ mpool_bkt(mp)
bp->page = spage;
}
#endif
+ bp->flags = 0;
return (bp);
}
@@ -355,6 +401,7 @@ new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
#endif
memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
bp->page = (char *)bp + sizeof(BKT);
+ bp->flags = 0;
++mp->curcache;
return (bp);
}
@@ -402,7 +449,8 @@ mpool_look(mp, pgno)
head = &mp->hqh[HASHKEY(pgno)];
for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
- if (bp->pgno == pgno) {
+ if ((bp->pgno == pgno) &&
+ (bp->flags & MPOOL_INUSE == MPOOL_INUSE)) {
#ifdef STATISTICS
++mp->cachehit;
#endif