Example #1
0
/*
 * Send a message to user space.
 */
int
xfs_message_send(int fd, struct xfs_message_header * message, u_int size)
{
    struct xfs_channel *chan = &xfs_channel[fd];
    struct {
	struct xfs_link this_message;
	struct xfs_message_header msg;
    } *t;

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

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

    /* Prepare message and copy it later */
    message->size = size;
    message->sequence_num = chan->nsequence++;

    t = xfs_alloc(sizeof(t->this_message) + size);
    t->this_message.error_or_size = sizeof(t->this_message) + size;
    bcopy(message, &t->msg, size);

    t->this_message.message = &t->msg;
    xfs_appendq(&chan->messageq, &t->this_message);
    if (chan->status & CHANNEL_WAITING) {
	chan->status &= ~CHANNEL_WAITING;
	wakeup((caddr_t) chan);
    }
    xfs_select_wakeup(chan);

    return 0;
}
int
xfs_getnewvnode(struct xfs *xfsp, struct vnode **vpp, 
		struct xfs_handle *handle)
{
    struct xfs_node *result, *check;
    int error;

    error = getnewvnode(VT_XFS, NNPFS_TO_VFS(xfsp), xfs_vnodeop_p, vpp);
    if (error)
	return error;
    
    result = xfs_alloc(sizeof(*result), M_NNPFS_NODE);
    bzero(result, sizeof(*result));
    
    (*vpp)->v_data = result;
    result->vn = *vpp;
    
    result->handle = *handle;
    result->flags = 0;
    result->tokens = 0;
    result->offset = 0;
#if defined(HAVE_KERNEL_LOCKMGR) || defined(HAVE_KERNEL_DEBUGLOCKMGR)
    lockinit (&result->lock, PVFS, "xfs_lock", 0, LK_NOPAUSE);
#else
    result->vnlocks = 0;
#endif
    result->anonrights = 0;
    result->rd_cred = NULL;
    result->wr_cred = NULL;

#if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105280000
    genfs_node_init(*vpp, &xfs_genfsops);
#endif

    check = xfs_node_find(&xfsp->nodehead, handle);
    if (check) {
	vput(*vpp);
	*vpp = result->vn;
	return 0;
    }

    xfs_insert(&xfs->nodehead, result);

    return 0;
}
Example #3
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;
}