Annotation of sys/xfs/xfs_dev-common.c, Revision 1.1.1.1
1.1 nbrk 1: /*
2: * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan
3: * (Royal Institute of Technology, Stockholm, Sweden).
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: *
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: *
17: * 3. Neither the name of the Institute nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34:
35: #include <xfs/xfs_locl.h>
36: #include <xfs/xfs_message.h>
37: #include <xfs/xfs_msg_locl.h>
38: #include <xfs/xfs_fs.h>
39: #include <xfs/xfs_dev.h>
40: #include <xfs/xfs_deb.h>
41:
42: RCSID("$arla: xfs_dev-common.c,v 1.61 2003/07/15 16:25:42 lha Exp $");
43:
44: struct xfs_channel xfs_channel[NNNPFS];
45:
46: void
47: xfs_initq(struct xfs_link *q)
48: {
49: q->next = q;
50: q->prev = q;
51: }
52:
53: /* Is this queue empty? */
54: int
55: xfs_emptyq(const struct xfs_link *q)
56: {
57: return q->next == q;
58: }
59:
60: /* Is this link on any queue? Link *must* be inited! */
61: int
62: xfs_onq(const struct xfs_link *link)
63: {
64: return link->next != NULL || link->prev != NULL;
65: }
66:
67: /* Append q with p */
68: void
69: xfs_appendq(struct xfs_link *q, struct xfs_link *p)
70: {
71: p->next = q;
72: p->prev = q->prev;
73: p->prev->next = p;
74: q->prev = p;
75: }
76:
77: /* remove `p' from its queue */
78: void
79: xfs_outq(struct xfs_link *p)
80: {
81: p->next->prev = p->prev;
82: p->prev->next = p->next;
83: p->next = p->prev = NULL;
84: }
85:
86: /*
87: * Only allow one open.
88: */
89: int
90: xfs_devopen_common(dev_t dev)
91: {
92: struct xfs_channel *chan;
93:
94: if (minor(dev) < 0 || minor(dev) >= NNNPFS)
95: return ENXIO;
96:
97: chan = &xfs_channel[minor(dev)];
98:
99: /* Only allow one reader/writer */
100: if (chan->status & CHANNEL_OPENED) {
101: NNPFSDEB(XDEBDEV, ("xfs_devopen: already open\n"));
102: return EBUSY;
103: } else {
104: chan->status |= CHANNEL_OPENED;
105: }
106:
107: chan->message_buffer = xfs_alloc(MAX_XMSG_SIZE, M_NNPFS_MSG);
108:
109: /* initialize the queues if they have not been initialized before */
110: xfs_initq(&chan->sleepq);
111: xfs_initq(&chan->messageq);
112:
113: return 0;
114: }
115:
116: #if defined(HAVE_TWO_ARGUMENT_VFS_BUSY)
117: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags))
118: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
119: #elif defined(HAVE_THREE_ARGUMENT_VFS_BUSY)
120: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock))
121: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
122: #elif defined(HAVE_FOUR_ARGUMENT_VFS_BUSY)
123: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock), (proc))
124: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp), (proc))
125: #elif defined(__osf__)
126: #define xfs_vfs_busy(mp, flags, lock, proc) (0)
127: #define xfs_vfs_unbusy(mp, proc) (0)
128: #else
129: #define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp))
130: #define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
131: #endif
132:
133: /*
134: * Wakeup all sleepers and cleanup.
135: */
136: int
137: xfs_devclose_common(dev_t dev, d_thread_t *proc)
138: {
139: struct xfs_channel *chan = &xfs_channel[minor(dev)];
140: struct xfs_link *first;
141:
142: /* Sanity check, paranoia? */
143: if (!(chan->status & CHANNEL_OPENED))
144: panic("xfs_devclose never opened?");
145:
146: chan->status &= ~CHANNEL_OPENED;
147:
148: /* No one is going to read those messages so empty queue! */
149: while (!xfs_emptyq(&chan->messageq)) {
150: NNPFSDEB(XDEBDEV, ("before outq(messageq)\n"));
151:
152: first = chan->messageq.next;
153: xfs_outq(first);
154: if (first->error_or_size != 0)
155: xfs_free(first, first->error_or_size, M_NNPFS_LINK);
156:
157: NNPFSDEB(XDEBDEV, ("after outq(messageq)\n"));
158: }
159:
160: /* Wakeup those waiting for replies that will never arrive. */
161: while (!xfs_emptyq(&chan->sleepq)) {
162: NNPFSDEB(XDEBDEV, ("before outq(sleepq)\n"));
163: first = chan->sleepq.next;
164: xfs_outq(first);
165: first->error_or_size = ENODEV;
166: wakeup((caddr_t) first);
167: NNPFSDEB(XDEBDEV, ("after outq(sleepq)\n"));
168: }
169:
170: if (chan->status & CHANNEL_WAITING)
171: wakeup((caddr_t) chan);
172:
173: if (chan->message_buffer) {
174: xfs_free(chan->message_buffer, MAX_XMSG_SIZE, M_NNPFS_MSG);
175: chan->message_buffer = NULL;
176: }
177:
178: /*
179: * Free all xfs nodes.
180: */
181:
182: if (xfs[minor(dev)].mp != NULL) {
183: if (xfs_vfs_busy(xfs[minor(dev)].mp, VB_READ|VB_WAIT, NULL, proc)) {
184: NNPFSDEB(XDEBNODE, ("xfs_dev_close: vfs_busy() --> BUSY\n"));
185: return EBUSY;
186: }
187: free_all_xfs_nodes(&xfs[minor(dev)], FORCECLOSE, 0);
188:
189: xfs_vfs_unbusy(xfs[minor(dev)].mp, proc);
190: }
191:
192: return 0;
193: }
194:
195: #ifdef NNPFS_DEBUG
196: /*
197: * debugging glue for CURSIG
198: */
199:
200: static long
201: xfs_cursig (d_thread_t *p)
202: {
203: #if defined(__osf__)
204: thread_t th = current_thread();
205: struct np_uthread *npu = thread_to_np_uthread(th);
206: return CURSIG(p,npu);
207: #elif defined(HAVE_FREEBSD_THREAD)
208: #ifndef CURSIG
209: return 0; /* XXX we would like to use sig_ffs, but that isn't
210: * exported */
211: #else
212: return CURSIG(p->td_proc);
213: #endif
214: #else
215: #if defined(__NetBSD__) && __NetBSD_Version__ >= 106130000
216: return 0; /* XXX CURSIG operates on a struct lwp */
217: #else
218: return CURSIG(p);
219: #endif
220: #endif
221: }
222: #endif
223:
224: /*
225: * Move messages from kernel to user space.
226: */
227:
228: int
229: xfs_devread(dev_t dev, struct uio * uiop, int ioflag)
230: {
231: struct xfs_channel *chan = &xfs_channel[minor(dev)];
232: struct xfs_link *first;
233: int error = 0;
234: #ifdef NNPFS_DEBUG
235: char devname[64];
236: #endif
237:
238: NNPFSDEB(XDEBDEV, ("xfs_devread dev = %s\n",
239: xfs_devtoname_r(dev, devname, sizeof(devname))));
240:
241: NNPFSDEB(XDEBDEV, ("xfs_devread: m = %lx, m->prev = %lx, m->next = %lx\n",
242: (unsigned long)&chan->messageq,
243: (unsigned long)chan->messageq.prev,
244: (unsigned long)chan->messageq.next));
245:
246: #ifdef HAVE_FREEBSD_THREAD
247: chan->proc = xfs_uio_to_thread(uiop);
248: #else
249: chan->proc = xfs_uio_to_proc(uiop);
250: #endif
251:
252: again:
253:
254: if (!xfs_emptyq (&chan->messageq)) {
255: while (!xfs_emptyq (&chan->messageq)) {
256: /* Remove message */
257: first = chan->messageq.next;
258: NNPFSDEB(XDEBDEV, ("xfs_devread: first = %lx, "
259: "first->prev = %lx, first->next = %lx\n",
260: (unsigned long)first,
261: (unsigned long)first->prev,
262: (unsigned long)first->next));
263:
264: NNPFSDEB(XDEBDEV, ("xfs_devread: message->size = %u\n",
265: first->message->size));
266:
267: if (first->message->size > uiop->uio_resid)
268: break;
269:
270: error = uiomove((caddr_t) first->message, first->message->size,
271: uiop);
272: if (error)
273: break;
274:
275: xfs_outq(first);
276:
277: if (first->error_or_size != 0)
278: xfs_free(first, first->error_or_size, M_NNPFS_LINK);
279: }
280: } else {
281: chan->status |= CHANNEL_WAITING;
282: if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsread", 0)) {
283: #ifdef HAVE_FREEBSD_THREAD
284: NNPFSDEB(XDEBMSG,
285: ("caught signal xfs_devread: %ld\n",
286: xfs_cursig(xfs_uio_to_thread(uiop))));
287: #else
288: NNPFSDEB(XDEBMSG,
289: ("caught signal xfs_devread: %ld\n",
290: xfs_cursig(xfs_uio_to_proc(uiop))));
291: #endif
292: error = EINTR;
293: } else if ((chan->status & CHANNEL_WAITING) == 0) {
294: goto again;
295: } else
296: error = EIO;
297: }
298:
299: NNPFSDEB(XDEBDEV, ("xfs_devread done error = %d\n", error));
300:
301: return error;
302: }
303:
304: /*
305: * Move messages from user space to kernel space,
306: * wakeup sleepers, insert new data in VFS.
307: */
308: int
309: xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag)
310: {
311: struct xfs_channel *chan = &xfs_channel[minor(dev)];
312: char *p;
313: int error;
314: u_int cnt;
315: struct xfs_message_header *msg_buf;
316: #ifdef NNPFS_DEBUG
317: char devname[64];
318: #endif
319:
320: NNPFSDEB(XDEBDEV, ("xfs_devwrite dev = %s\n",
321: xfs_devtoname_r (dev, devname, sizeof(devname))));
322:
323: #ifdef HAVE_FREEBSD_THREAD
324: chan->proc = xfs_uio_to_thread(uiop);
325: #else
326: chan->proc = xfs_uio_to_proc(uiop);
327: #endif
328: cnt = uiop->uio_resid;
329: error = uiomove((caddr_t) chan->message_buffer, MAX_XMSG_SIZE, uiop);
330: if (error != 0)
331: return error;
332:
333: cnt -= uiop->uio_resid;
334:
335: /*
336: * This thread handles the received message.
337: */
338: for (p = (char *)chan->message_buffer;
339: cnt > 0;
340: p += msg_buf->size, cnt -= msg_buf->size) {
341: #ifdef HAVE_FREEBSD_THREAD
342: d_thread_t *pp = xfs_uio_to_thread(uiop);
343: #else
344: d_thread_t *pp = xfs_uio_to_proc(uiop);
345: #endif
346:
347: msg_buf = (struct xfs_message_header *)p;
348: error = xfs_message_receive (minor(dev),
349: msg_buf,
350: msg_buf->size,
351: pp);
352: }
353: NNPFSDEB(XDEBDEV, ("xfs_devwrite error = %d\n", error));
354: return error;
355: }
356:
357: /*
358: * Send a message to user space.
359: */
360: int
361: xfs_message_send(int fd, struct xfs_message_header * message, u_int size)
362: {
363: struct xfs_channel *chan = &xfs_channel[fd];
364: struct {
365: struct xfs_link this_message;
366: struct xfs_message_header msg;
367: } *t;
368:
369: NNPFSDEB(XDEBMSG, ("xfs_message_send opcode = %d\n", message->opcode));
370:
371: if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */
372: return ENODEV;
373:
374: /* Prepare message and copy it later */
375: message->size = size;
376: message->sequence_num = chan->nsequence++;
377:
378: t = xfs_alloc(sizeof(t->this_message) + size, M_NNPFS);
379: t->this_message.error_or_size = sizeof(t->this_message) + size;
380: bcopy(message, &t->msg, size);
381:
382: t->this_message.message = &t->msg;
383: xfs_appendq(&chan->messageq, &t->this_message);
384: if (chan->status & CHANNEL_WAITING) {
385: chan->status &= ~CHANNEL_WAITING;
386: wakeup((caddr_t) chan);
387: }
388: xfs_select_wakeup(chan);
389:
390: return 0;
391: }
392:
393: #if defined(SWEXIT)
394: #define NNPFS_P_EXIT SWEXIT
395: #elif defined(P_WEXIT)
396: #define NNPFS_P_EXIT P_WEXIT
397: #else
398: #error what is your exit named ?
399: #endif
400:
401: #if defined(HAVE_STRUCT_PROC_P_SIGMASK) || defined(HAVE_STRUCT_PROC_P_SIGCTX) || defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) || defined(__osf__) || defined(HAVE_FREEBSD_THREAD)
402: static void
403: xfs_block_sigset (sigset_t *sigset)
404: {
405:
406: #if defined(__sigaddset)
407: #define xfs_sig_block(ss,signo) __sigaddset((ss), (signo))
408: #elif defined(SIGADDSET)
409: #define xfs_sig_block(ss,signo) SIGADDSET(*(ss), (signo))
410: #else
411: #define xfs_sig_block(ss,signo) *(ss) |= sigmask(signo)
412: #endif
413:
414: xfs_sig_block(sigset, SIGIO);
415: xfs_sig_block(sigset, SIGALRM);
416: xfs_sig_block(sigset, SIGVTALRM);
417: xfs_sig_block(sigset, SIGCHLD);
418: #ifdef SIGINFO
419: xfs_sig_block(sigset, SIGINFO);
420: #endif
421: #undef xfs_sig_block
422: }
423: #endif
424:
425: /*
426: * Send a message to user space and wait for reply.
427: */
428:
429: int
430: xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size,
431: d_thread_t *proc)
432: {
433: int ret;
434: struct xfs_channel *chan = &xfs_channel[fd];
435: struct xfs_link *this_message;
436: struct xfs_link *this_process;
437: struct xfs_message_header *msg;
438: #if defined(HAVE_STRUCT_PROC_P_SIGMASK) || defined(HAVE_STRUCT_PROC_P_SIGCTX) || defined(__osf__) || defined(HAVE_FREEBSD_THREAD)
439: sigset_t oldsigmask;
440: #endif
441: int catch;
442:
443: NNPFSDEB(XDEBMSG, ("xfs_message_rpc opcode = %d\n", message->opcode));
444:
445: if (proc == NULL) {
446: #ifdef HAVE_FREEBSD_THREAD
447: proc = xfs_curthread();
448: #else
449: proc = xfs_curproc();
450: #endif
451: }
452: if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */
453: return ENODEV;
454:
455: #ifdef HAVE_FREEBSD_THREAD
456: if (chan->proc != NULL && chan->proc->td_proc != NULL &&
457: proc->td_proc->p_pid == chan->proc->td_proc->p_pid) {
458: printf("xfs_message_rpc: deadlock avoided "
459: "pid = %u == %u\n", proc->td_proc->p_pid, chan->proc->td_proc->p_pid);
460: #else
461: if (chan->proc != NULL && proc->p_pid == chan->proc->p_pid) {
462: printf("xfs_message_rpc: deadlock avoided "
463: "pid = %u == %u\n", proc->p_pid, chan->proc->p_pid);
464: #endif
465: #if 0
466: psignal (proc, SIGABRT);
467: #endif
468: return EDEADLK;
469: }
470:
471: if (size < sizeof(struct xfs_message_wakeup)) {
472: printf("NNPFS PANIC Error: Message to small to receive wakeup, opcode = %d\n", message->opcode);
473: return ENOMEM;
474: }
475: this_message = xfs_alloc(sizeof(struct xfs_link), M_NNPFS_LINK);
476: this_process = xfs_alloc(sizeof(struct xfs_link), M_NNPFS_LINK);
477: msg = xfs_alloc(size, M_NNPFS_MSG);
478: bcopy(message, msg, size);
479:
480: msg->size = size;
481: msg->sequence_num = chan->nsequence++;
482: this_message->error_or_size = 0;
483: this_message->message = msg;
484: this_process->message = msg;
485: xfs_appendq(&chan->messageq, this_message);
486: xfs_appendq(&chan->sleepq, this_process);
487: xfs_select_wakeup(chan);
488: this_process->error_or_size = 0;
489:
490: if (chan->status & CHANNEL_WAITING) {
491: chan->status &= ~CHANNEL_WAITING;
492: wakeup((caddr_t) chan);
493: }
494:
495: /*
496: * Remove signals from the sigmask so no IO will wake us up from
497: * tsleep(). We don't want to wake up from since program (emacs,
498: * bash & co can't handle them.
499: */
500:
501: #ifdef HAVE_FREEBSD_THREAD
502: /* FreeBSD 5.1 */
503: oldsigmask = proc->td_sigmask;
504: xfs_block_sigset (&proc->td_sigmask);
505: #elif HAVE_STRUCT_PROC_P_SIGMASK
506: /* NetBSD 1.5, Darwin 1.3, FreeBSD 4.3, 5.0, OpenBSD 2.8 */
507: oldsigmask = proc->p_sigmask;
508: xfs_block_sigset (&proc->p_sigmask);
509: #elif defined(HAVE_STRUCT_PROC_P_SIGCTX)
510: /* NetBSD 1.6 */
511: oldsigmask = proc->p_sigctx.ps_sigmask;
512: xfs_block_sigset (&proc->p_sigctx.ps_sigmask);
513: #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
514: /* OSF 4.0 */
515: oldsigmask = proc->p_sigwaitmask;
516: xfs_block_sigset (&proc->p_sigwaitmask);
517: #elif defined(__osf__)
518: /* OSF 5.0 */
519: oldsigmask = u.u_sigmask;
520: xfs_block_sigset (&u.u_sigmask);
521: #endif
522:
523: /*
524: * if we are exiting we should not try to catch signals, since
525: * there might not be enough context left in the process to handle
526: * signal delivery, and besides, most BSD-variants ignore all
527: * signals while closing anyway.
528: */
529:
530: catch = 0;
531: #ifdef HAVE_FREEBSD_THREAD
532: if (!(proc->td_proc->p_flag & NNPFS_P_EXIT))
533: #else
534: if (!(proc->p_flag & NNPFS_P_EXIT))
535: #endif
536: catch |= PCATCH;
537:
538: /*
539: * We have to check if we have a receiver here too because the
540: * daemon could have terminated before we sleep. This seems to
541: * happen sometimes when rebooting. */
542:
543: if (!(chan->status & CHANNEL_OPENED)) {
544: NNPFSDEB(XDEBMSG, ("xfs_message_rpc: channel went away\n"));
545: this_process->error_or_size = EINTR;
546: } else if ((ret = tsleep((caddr_t) this_process,
547: (PZERO + 1) | catch, "xfs", 0)) != 0) {
548: NNPFSDEB(XDEBMSG, ("caught signal (%d): %ld\n",
549: ret, xfs_cursig(proc)));
550: this_process->error_or_size = EINTR;
551: }
552:
553: #ifdef HAVE_FREEBSD_THREAD
554: proc->td_sigmask = oldsigmask;
555: #elif HAVE_STRUCT_PROC_P_SIGMASK
556: proc->p_sigmask = oldsigmask;
557: #elif defined(HAVE_STRUCT_PROC_P_SIGCTX)
558: proc->p_sigctx.ps_sigmask = oldsigmask;
559: #elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
560: proc->p_sigwaitmask = oldsigmask;
561: #elif defined(__osf__)
562: u.u_sigmask = oldsigmask;
563: #endif
564:
565: /*
566: * Caught signal, got reply message or device was closed.
567: * Need to clean up both messageq and sleepq.
568: */
569: if (xfs_onq(this_message)) {
570: xfs_outq(this_message);
571: }
572: if (xfs_onq(this_process)) {
573: xfs_outq(this_process);
574: }
575: ret = this_process->error_or_size;
576:
577: NNPFSDEB(XDEBMSG, ("xfs_message_rpc this_process->error_or_size = %d\n",
578: this_process->error_or_size));
579: NNPFSDEB(XDEBMSG, ("xfs_message_rpc opcode ((xfs_message_wakeup*)(this_process->message))->error = %d\n", ((struct xfs_message_wakeup *) (this_process->message))->error));
580:
581: bcopy(msg, message, size);
582:
583: xfs_free(this_message, sizeof(*this_message), M_NNPFS_LINK);
584: xfs_free(this_process, sizeof(*this_process), M_NNPFS_LINK);
585: xfs_free(msg, size, M_NNPFS_MSG);
586:
587: return ret;
588: }
589:
590: /*
591: * For each message type there is a message handler
592: * that implements its action, xfs_message_receive
593: * invokes the correct function.
594: */
595: int
596: xfs_message_receive(int fd,
597: struct xfs_message_header *message,
598: u_int size,
599: d_thread_t *p)
600: {
601: NNPFSDEB(XDEBMSG, ("xfs_message_receive opcode = %d\n", message->opcode));
602:
603: /* Dispatch and coerce message type */
604: switch (message->opcode) {
605: case NNPFS_MSG_WAKEUP:
606: return xfs_message_wakeup(fd,
607: (struct xfs_message_wakeup *) message,
608: message->size,
609: p);
610: case NNPFS_MSG_WAKEUP_DATA:
611: return xfs_message_wakeup_data(fd,
612: (struct xfs_message_wakeup_data *) message,
613: message->size,
614: p);
615: case NNPFS_MSG_INSTALLROOT:
616: return xfs_message_installroot(fd,
617: (struct xfs_message_installroot *) message,
618: message->size,
619: p);
620: case NNPFS_MSG_INSTALLNODE:
621: return xfs_message_installnode(fd,
622: (struct xfs_message_installnode *) message,
623: message->size,
624: p);
625: case NNPFS_MSG_INSTALLATTR:
626: return xfs_message_installattr(fd,
627: (struct xfs_message_installattr *) message,
628: message->size,
629: p);
630: case NNPFS_MSG_INSTALLDATA:
631: return xfs_message_installdata(fd,
632: (struct xfs_message_installdata *) message,
633: message->size,
634: p);
635: case NNPFS_MSG_INVALIDNODE:
636: return xfs_message_invalidnode(fd,
637: (struct xfs_message_invalidnode *) message,
638: message->size,
639: p);
640: case NNPFS_MSG_UPDATEFID:
641: return xfs_message_updatefid(fd,
642: (struct xfs_message_updatefid *)message,
643: message->size,
644: p);
645: case NNPFS_MSG_GC_NODES:
646: return xfs_message_gc_nodes(fd,
647: (struct xfs_message_gc_nodes *)message,
648: message->size,
649: p);
650: case NNPFS_MSG_VERSION:
651: return xfs_message_version(fd,
652: (struct xfs_message_version *)message,
653: message->size,
654: p);
655: default:
656: printf("NNPFS PANIC Warning xfs_dev: Unknown message opcode == %d\n",
657: message->opcode);
658: return EINVAL;
659: }
660: }
661:
662: int
663: xfs_message_wakeup(int fd,
664: struct xfs_message_wakeup *message,
665: u_int size,
666: d_thread_t *p)
667: {
668: struct xfs_channel *chan = &xfs_channel[fd];
669: struct xfs_link *sleepq = &chan->sleepq;
670: struct xfs_link *t = chan->sleepq.next; /* Really first in q */
671:
672: NNPFSDEB(XDEBMSG, ("xfs_message_wakeup error: %d\n", message->error));
673:
674: for (; t != sleepq; t = t->next)
675: if (t->message->sequence_num == message->sleepers_sequence_num) {
676: if (t->message->size < size) {
677: printf("NNPFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode);
678: t->error_or_size = ENOMEM;
679: } else
680: bcopy(message, t->message, size);
681:
682: wakeup((caddr_t) t);
683: break;
684: }
685:
686: return 0;
687: }
688:
689: int
690: xfs_message_wakeup_data(int fd,
691: struct xfs_message_wakeup_data * message,
692: u_int size,
693: d_thread_t *p)
694: {
695: struct xfs_channel *chan = &xfs_channel[fd];
696: struct xfs_link *sleepq = &chan->sleepq;
697: struct xfs_link *t = chan->sleepq.next; /* Really first in q */
698:
699: NNPFSDEB(XDEBMSG, ("xfs_message_wakeup_data error: %d\n", message->error));
700:
701: for (; t != sleepq; t = t->next)
702: if (t->message->sequence_num == message->sleepers_sequence_num) {
703: if (t->message->size < size) {
704: printf("NNPFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode);
705: t->error_or_size = ENOMEM;
706: } else
707: bcopy(message, t->message, size);
708: wakeup((caddr_t) t);
709: break;
710: }
711: return 0;
712: }
713:
714: /*
715: *
716: */
717: int
718: xfs_uprintf_device(void)
719: {
720: #if 0
721: int i;
722:
723: for (i = 0; i < NNNPFS; i++) {
724: uprintf("xfs_channel[%d] = {\n", i);
725: uprintf("messageq.next = %lx ", xfs_channel[i].messageq.next);
726: uprintf("messageq.prev = %lx ", xfs_channel[i].messageq.prev);
727: uprintf("sleepq.next = %lx ", xfs_channel[i].sleepq.next);
728: uprintf("sleepq.prev = %lx ", xfs_channel[i].sleepq.prev);
729: uprintf("nsequence = %d status = %d\n",
730: xfs_channel[i].nsequence,
731: xfs_channel[i].status);
732: uprintf("}\n");
733: }
734: #endif
735: return 0;
736: }
CVSweb