/* * 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; }
/* * 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; }