Exemple #1
0
/*
 * Wakeup all sleepers and cleanup.
 */
int
xfs_devclose_common(dev_t dev, struct proc *proc)
{
    struct xfs_channel *chan = &xfs_channel[minor(dev)];
    struct xfs_link *first;
    
    /* Sanity check, paranoia? */
    if (!(chan->status & CHANNEL_OPENED))
	panic("xfs_devclose never opened?");

    chan->status &= ~CHANNEL_OPENED;

    /* No one is going to read those messages so empty queue! */
    while (!xfs_emptyq(&chan->messageq)) {
	XFSDEB(XDEBDEV, ("before outq(messageq)\n"));

	first = chan->messageq.next;
	xfs_outq(first);
	if (first->error_or_size != 0)
	    xfs_free(first, first->error_or_size);

	XFSDEB(XDEBDEV, ("after outq(messageq)\n"));
    }

    /* Wakeup those waiting for replies that will never arrive. */
    while (!xfs_emptyq(&chan->sleepq)) {
	XFSDEB(XDEBDEV, ("before outq(sleepq)\n"));
	first = chan->sleepq.next;
	xfs_outq(first);
	first->error_or_size = ENODEV;
	wakeup((caddr_t) first);
	XFSDEB(XDEBDEV, ("after outq(sleepq)\n"));
    }

    if (chan->status & CHANNEL_WAITING)
	wakeup((caddr_t) chan);

    if (chan->message_buffer) {
	xfs_free(chan->message_buffer, MAX_XMSG_SIZE);
	chan->message_buffer = NULL;
    }

    /*
     * Free all xfs nodes.
     */

    if (xfs[minor(dev)].mp != NULL) {
	if (xfs_vfs_busy(xfs[minor(dev)].mp, 0, NULL, proc)) {
	    XFSDEB(XDEBNODE, ("xfs_dev_close: vfs_busy() --> BUSY\n"));
	    return EBUSY;
	}
	free_all_xfs_nodes(&xfs[minor(dev)], FORCECLOSE, 0);

	xfs_vfs_unbusy(xfs[minor(dev)].mp, proc);
    }
    
    return 0;
}
Exemple #2
0
/*
 * Move messages from kernel to user space.
 */
int
xfs_devread(dev_t dev, struct uio * uiop, int ioflag)
{
    struct xfs_channel *chan = &xfs_channel[minor(dev)];
    struct xfs_link *first;
    int error = 0;

    XFSDEB(XDEBDEV, ("xfs_devread dev = %d\n", dev));

    XFSDEB(XDEBDEV, ("xfs_devread: m = %p, m->prev = %p, m->next = %p\n",
		&chan->messageq, chan->messageq.prev, chan->messageq.next));

 again:

    if (!xfs_emptyq (&chan->messageq)) {
	while (!xfs_emptyq (&chan->messageq)) {
	    /* Remove message */
	    first = chan->messageq.next;
	    XFSDEB(XDEBDEV, ("xfs_devread: first = %p, "
			     "first->prev = %p, first->next = %p\n",
			     first, first->prev, first->next));
	    
	    XFSDEB(XDEBDEV, ("xfs_devread: message->size = %u\n",
			     first->message->size));
	    
	    error = uiomove((caddr_t) first->message, first->message->size, 
			    uiop);
	    if (error)
		break;
	    
	    xfs_outq(first);
	    
	    if (first->error_or_size != 0)
		xfs_free(first, first->error_or_size);
	}
    } else {
	chan->status |= CHANNEL_WAITING;
	if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsr", 0)) {
	    XFSDEB(XDEBMSG, ("caught signal xfs_devread\n"));
	    error = EINTR;
	} else if ((chan->status & CHANNEL_WAITING) == 0) {
	    goto again;
	} else
	    error = EIO;
    }
    
    
    XFSDEB(XDEBDEV, ("xfs_devread done error = %d\n", error));

    return error;
}
Exemple #3
0
static int
xfs_realselect(dev_t dev, struct proc *p)
{
    struct xfs_channel *chan = &xfs_channel[minor(dev)];

    if (!xfs_emptyq(&chan->messageq))
	return 1;		       /* Something to read */

    selrecord (p, &chan->selinfo);
    return 0;
}
int
xfs_devpoll(dev_t dev, int events, d_thread_t * p)
{
	struct xfs_channel *chan = &xfs_channel[minor(dev)];
	
	NNPFSDEB(XDEBDEV, ("xfs_devpoll dev = %d(%d), events = 0x%x\n",
	    major(dev), minor(dev), events));

	if ((events & (POLLIN | POLLRDNORM)) == 0)
		return 0;			/* only supports read */
	
	if (!xfs_emptyq(&chan->messageq))
		return (events & (POLLIN | POLLRDNORM));
	
	selrecord (p, &chan->selinfo);

	return 0;
}