Add some private storage so that we can queue requests in an interrupt

environment even if malloc fails.
This commit is contained in:
Greg Lehey 1999-10-13 03:16:05 +00:00
parent 79ed692973
commit 8409d98998
2 changed files with 36 additions and 4 deletions

View File

@ -33,6 +33,7 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
* $Id: request.h,v 1.16 1999/10/12 04:33:24 grog Exp grog $
* $FreeBSD$
*/
@ -234,6 +235,7 @@ union daemoninfo { /* and the request information */
struct daemonq {
struct daemonq *next; /* pointer to next element in queue */
enum daemonrq type; /* type of request */
int privateinuse; /* private element, being used */
union daemoninfo info; /* and the request information */
};

View File

@ -34,6 +34,7 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
* $Id: vinumdaemon.c,v 1.7 1999/10/12 09:39:48 grog Exp grog $
* $FreeBSD$
*/
@ -47,16 +48,26 @@
/* declarations */
void recover_io(struct request *rq);
struct daemonq *daemonq; /* daemon's work queue */
struct daemonq *dqend; /* and the end of the queue */
int daemon_options = 0; /* options */
int daemonpid; /* PID of daemon */
struct daemonq *daemonq; /* daemon's work queue */
struct daemonq *dqend; /* and the end of the queue */
/*
* We normally call Malloc to get a queue element. In interrupt
* context, we can't guarantee that we'll get one, since we're not
* allowed to wait. If malloc fails, use one of these elements.
*/
#define INTQSIZE 4
struct daemonq intq[INTQSIZE]; /* queue elements for interrupt context */
struct daemonq *intqp; /* and pointer in it */
void
vinum_daemon(void)
{
struct daemonq *request;
int s;
struct daemonq *request;
daemon_save_config(); /* start by saving the configuration */
daemonpid = curproc->p_pid; /* mark our territory */
@ -160,7 +171,10 @@ vinum_daemon(void)
log(LOG_WARNING, "Invalid request\n");
break;
}
Free(request); /* done with the request */
if (request->privateinuse) /* one of ours, */
request->privateinuse = 0; /* no longer in use */
else
Free(request); /* return it */
}
}
}
@ -202,6 +216,22 @@ queue_daemon_request(enum daemonrq type, union daemoninfo info)
int s;
struct daemonq *qelt = (struct daemonq *) Malloc(sizeof(struct daemonq));
if (qelt == NULL) { /* malloc failed, we're prepared for that */
/*
* Take one of our spares. Give up if it's still in use; the only
* message we're likely to get here is a 'drive failed' message,
* and that'll come by again if we miss it.
*/
if (intqp->privateinuse) /* still in use? */
return; /* yes, give up */
qelt = intqp++;
if (intqp == &intq[INTQSIZE]) /* got to the end, */
intqp = intq; /* wrap around */
qelt->privateinuse = 1; /* it's ours, and it's in use */
} else
qelt->privateinuse = 0;
qelt->next = NULL; /* end of the chain */
qelt->type = type;
qelt->info = info;