int
xfs_root(struct mount *mp, struct vnode **vpp)
{
    NNPFSDEB(XDEBVFOPS, ("xfs_root mp = %lx\n", (unsigned long)mp));
#ifdef HAVE_FREEBSD_THREAD
    return xfs_root_common(mp, vpp, xfs_curthread(), xfs_curthread()->td_proc->p_ucred);
#else
    return xfs_root_common(mp, vpp, xfs_curproc(), xfs_curproc()->p_ucred);
#endif
}
Esempio n. 2
0
/*
 * Send a message to user space and wait for reply.
 */
int
xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size)
{
    int ret;
    struct xfs_channel *chan = &xfs_channel[fd];
    struct xfs_link *this_message;
    struct xfs_link *this_process;
    struct xfs_message_header *msg;
#if defined(HAVE_STRUCT_PROC_P_SIGMASK)
    sigset_t oldsigmask;
#endif /* HAVE_STRUCT_PROC_P_SIGMASK */

    XFSDEB(XDEBMSG, ("xfs_message_rpc opcode = %d\n", message->opcode));

    if (!(chan->status & CHANNEL_OPENED))	/* No receiver? */
	return ENODEV;

    if (size < sizeof(struct xfs_message_wakeup)) {
	printf("XFS PANIC Error: Message to small to receive wakeup, opcode = %d\n", message->opcode);
	return ENOMEM;
    }
    this_message = xfs_alloc(sizeof(struct xfs_link));
    this_process = xfs_alloc(sizeof(struct xfs_link));
    msg = xfs_alloc(size);
    bcopy(message, msg, size);

    msg->size = size;
    msg->sequence_num = chan->nsequence++;
    this_message->error_or_size = 0;
    this_message->message = msg;
    this_process->message = msg;
    xfs_appendq(&chan->messageq, this_message);
    xfs_appendq(&chan->sleepq, this_process);
    xfs_select_wakeup(chan);
    this_process->error_or_size = 0;

    if (chan->status & CHANNEL_WAITING) {
	chan->status &= ~CHANNEL_WAITING;
	wakeup((caddr_t) chan);
    }

    /*
     * Remove SIGIO from the sigmask so no IO will
     * wake us up from tsleep()
     */

#ifdef HAVE_STRUCT_PROC_P_SIGMASK
    oldsigmask = xfs_curproc()->p_sigmask;
#ifdef __sigaddset
    __sigaddset(&xfs_curproc()->p_sigmask, SIGIO);
#else
    xfs_curproc()->p_sigmask |= sigmask(SIGIO);
#endif /* __sigaddset */
#elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
    oldsigmask = xfs_curproc()->p_sigwaitmask;
    sigaddset(&xfs_curproc()->p_sigwaitmask, SIGIO);
#endif
    /*
     * We have to check if we have a receiver here too because the
     * daemon could have terminated before we sleep. This seems to
     * happen sometimes when rebooting.
     */
    if (!(chan->status & CHANNEL_OPENED) ||
	tsleep((caddr_t) this_process, (PZERO + 1) | PCATCH, "xfs", 0)) {
	XFSDEB(XDEBMSG, ("caught signal\n"));
	this_process->error_or_size = EINTR;
    }

#ifdef HAVE_STRUCT_PROC_P_SIGMASK
    xfs_curproc()->p_sigmask = oldsigmask;
#elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
    xfs_curproc()->p_sigwaitmask = oldsigmask;
#endif

    /*
     * Caught signal, got reply message or device was closed.
     * Need to clean up both messageq and sleepq.
     */
    if (xfs_onq(this_message)) {
	xfs_outq(this_message);
    }
    if (xfs_onq(this_process)) {
	xfs_outq(this_process);
    }
    ret = this_process->error_or_size;

    XFSDEB(XDEBMSG, ("xfs_message_rpc this_process->error_or_size = %d\n",
		     this_process->error_or_size));
    XFSDEB(XDEBMSG, ("xfs_message_rpc opcode ((xfs_message_wakeup*)(this_process->message))->error = %d\n", ((struct xfs_message_wakeup *) (this_process->message))->error));

    bcopy(msg, message, size);

    xfs_free(this_message, sizeof(*this_message));
    xfs_free(this_process, sizeof(*this_process));
    xfs_free(msg, size);

    return ret;
}