1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
3 *
4 * An implementation of a loadable kernel mode driver providing
5 * multiple kernel/user space bidirectional communications links.
6 *
7 * Author: Alan Cox <alan@cymru.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * Adapted to become the Linux 2.0 Coda pseudo device
14 * Peter Braam <braam@maths.ox.ac.uk>
15 * Michael Callahan <mjc@emmy.smith.edu>
16 *
17 * Changes for Linux 2.1
18 * Copyright (c) 1997 Carnegie-Mellon University
19 *
20 * Redone again for InterMezzo
21 * Copyright (c) 1998 Peter J. Braam
22 * Copyright (c) 2000 Mountain View Data, Inc.
23 * Copyright (c) 2000 Tacitus Systems, Inc.
24 * Copyright (c) 2001 Cluster File Systems, Inc.
25 *
26 */
27
28 #include <linux/module.h>
29 #include <linux/errno.h>
30 #include <linux/kernel.h>
31 #include <linux/major.h>
32 #include <linux/sched.h>
33 #include <linux/lp.h>
34 #include <linux/slab.h>
35 #include <linux/ioport.h>
36 #include <linux/fcntl.h>
37 #include <linux/delay.h>
38 #include <linux/skbuff.h>
39 #include <linux/proc_fs.h>
40 #include <linux/vmalloc.h>
41 #include <linux/fs.h>
42 #include <linux/file.h>
43 #include <linux/poll.h>
44 #include <linux/init.h>
45 #include <linux/list.h>
46 #include <linux/devfs_fs_kernel.h>
47 #include <asm/io.h>
48 #include <asm/segment.h>
49 #include <asm/system.h>
50 #include <asm/poll.h>
51 #include <asm/uaccess.h>
52 #include <linux/miscdevice.h>
53
54 #include <linux/intermezzo_fs.h>
55 #include <linux/intermezzo_psdev.h>
56
57
58 #ifdef PRESTO_DEVEL
59 int presto_print_entry = 1;
60 int presto_debug = 4095;
61 #else
62 int presto_print_entry = 0;
63 int presto_debug = 0;
64 #endif
65
66 /* Like inode.c (presto_sym_iops), the initializer is just to prevent
67 izo_channels from appearing as a COMMON symbol (and therefore
68 interfering with other modules that use the same variable name). */
69 struct upc_channel izo_channels[MAX_CHANNEL] = {{0}};
70
izo_psdev_get_free_channel(void)71 int izo_psdev_get_free_channel(void)
72 {
73 int i, result = -1;
74
75 for (i = 0 ; i < MAX_CHANNEL ; i++ ) {
76 if (list_empty(&(izo_channels[i].uc_cache_list))) {
77 result = i;
78 break;
79 }
80 }
81 return result;
82 }
83
84
izo_psdev_setpid(int minor)85 int izo_psdev_setpid(int minor)
86 {
87 struct upc_channel *channel;
88 if (minor < 0 || minor >= MAX_CHANNEL) {
89 return -EINVAL;
90 }
91
92 channel = &(izo_channels[minor]);
93 /*
94 * This ioctl is performed by each Lento that starts up
95 * and wants to do further communication with presto.
96 */
97 CDEBUG(D_PSDEV, "Setting current pid to %d channel %d\n",
98 current->pid, minor);
99 channel->uc_pid = current->pid;
100 spin_lock(&channel->uc_lock);
101 if ( !list_empty(&channel->uc_processing) ) {
102 struct list_head *lh;
103 struct upc_req *req;
104 CERROR("WARNING: setpid & processing not empty!\n");
105 list_for_each(lh, &channel->uc_processing) {
106 req = list_entry(lh, struct upc_req, rq_chain);
107 /* freeing of req and data is done by the sleeper */
108 wake_up(&req->rq_sleep);
109 }
110 }
111 if ( !list_empty(&channel->uc_processing) ) {
112 CERROR("BAD: FAILDED TO CLEAN PROCESSING LIST!\n");
113 }
114 spin_unlock(&channel->uc_lock);
115 EXIT;
116 return 0;
117 }
118
izo_psdev_setchannel(struct file * file,int fd)119 int izo_psdev_setchannel(struct file *file, int fd)
120 {
121
122 struct file *psdev_file = fget(fd);
123 struct presto_cache *cache = presto_get_cache(file->f_dentry->d_inode);
124
125 if (!psdev_file) {
126 CERROR("%s: no psdev_file!\n", __FUNCTION__);
127 return -EINVAL;
128 }
129
130 if (!cache) {
131 CERROR("%s: no cache!\n", __FUNCTION__);
132 fput(psdev_file);
133 return -EINVAL;
134 }
135
136 if (psdev_file->private_data) {
137 CERROR("%s: channel already set!\n", __FUNCTION__);
138 fput(psdev_file);
139 return -EINVAL;
140 }
141
142 psdev_file->private_data = cache->cache_psdev;
143 fput(psdev_file);
144 EXIT;
145 return 0;
146 }
147
presto_lento_up(int minor)148 inline int presto_lento_up(int minor)
149 {
150 return izo_channels[minor].uc_pid;
151 }
152
presto_psdev_poll(struct file * file,poll_table * wait)153 static unsigned int presto_psdev_poll(struct file *file, poll_table * wait)
154 {
155 struct upc_channel *channel = (struct upc_channel *)file->private_data;
156 unsigned int mask = POLLOUT | POLLWRNORM;
157
158 /* ENTRY; this will flood you */
159 if ( ! channel ) {
160 CERROR("%s: bad psdev file\n", __FUNCTION__);
161 return -EBADF;
162 }
163
164 poll_wait(file, &(channel->uc_waitq), wait);
165
166 spin_lock(&channel->uc_lock);
167 if (!list_empty(&channel->uc_pending)) {
168 CDEBUG(D_PSDEV, "Non-empty pending list.\n");
169 mask |= POLLIN | POLLRDNORM;
170 }
171 spin_unlock(&channel->uc_lock);
172
173 /* EXIT; will flood you */
174 return mask;
175 }
176
177 /*
178 * Receive a message written by Lento to the psdev
179 */
presto_psdev_write(struct file * file,const char * buf,size_t count,loff_t * off)180 static ssize_t presto_psdev_write(struct file *file, const char *buf,
181 size_t count, loff_t *off)
182 {
183 struct upc_channel *channel = (struct upc_channel *)file->private_data;
184 struct upc_req *req = NULL;
185 struct upc_req *tmp;
186 struct list_head *lh;
187 struct izo_upcall_resp hdr;
188 int error;
189
190 if ( ! channel ) {
191 CERROR("%s: bad psdev file\n", __FUNCTION__);
192 return -EBADF;
193 }
194
195 /* Peek at the opcode, uniquefier */
196 if ( count < sizeof(hdr) ) {
197 CERROR("presto_psdev_write: Lento didn't write full hdr.\n");
198 return -EINVAL;
199 }
200
201 error = copy_from_user(&hdr, buf, sizeof(hdr));
202 if ( error )
203 return -EFAULT;
204
205 CDEBUG(D_PSDEV, "(process,opc,uniq)=(%d,%d,%d)\n",
206 current->pid, hdr.opcode, hdr.unique);
207
208 spin_lock(&channel->uc_lock);
209 /* Look for the message on the processing queue. */
210 list_for_each(lh, &channel->uc_processing) {
211 tmp = list_entry(lh, struct upc_req , rq_chain);
212 if (tmp->rq_unique == hdr.unique) {
213 req = tmp;
214 /* unlink here: keeps search length minimal */
215 list_del_init(&req->rq_chain);
216 CDEBUG(D_PSDEV,"Eureka opc %d uniq %d!\n",
217 hdr.opcode, hdr.unique);
218 break;
219 }
220 }
221 spin_unlock(&channel->uc_lock);
222 if (!req) {
223 CERROR("psdev_write: msg (%d, %d) not found\n",
224 hdr.opcode, hdr.unique);
225 return(-ESRCH);
226 }
227
228 /* move data into response buffer. */
229 if (req->rq_bufsize < count) {
230 CERROR("psdev_write: too much cnt: %d, cnt: %d, "
231 "opc: %d, uniq: %d.\n",
232 req->rq_bufsize, count, hdr.opcode, hdr.unique);
233 count = req->rq_bufsize; /* don't have more space! */
234 }
235 error = copy_from_user(req->rq_data, buf, count);
236 if ( error )
237 return -EFAULT;
238
239 /* adjust outsize: good upcalls can be aware of this */
240 req->rq_rep_size = count;
241 req->rq_flags |= REQ_WRITE;
242
243 wake_up(&req->rq_sleep);
244 return(count);
245 }
246
247 /*
248 * Read a message from the kernel to Lento
249 */
presto_psdev_read(struct file * file,char * buf,size_t count,loff_t * off)250 static ssize_t presto_psdev_read(struct file * file, char * buf,
251 size_t count, loff_t *off)
252 {
253 struct upc_channel *channel = (struct upc_channel *)file->private_data;
254 struct upc_req *req;
255 int result = count;
256
257 if ( ! channel ) {
258 CERROR("%s: bad psdev file\n", __FUNCTION__);
259 return -EBADF;
260 }
261
262 spin_lock(&channel->uc_lock);
263 if (list_empty(&(channel->uc_pending))) {
264 CDEBUG(D_UPCALL, "Empty pending list in read, not good\n");
265 spin_unlock(&channel->uc_lock);
266 return -EINVAL;
267 }
268 req = list_entry((channel->uc_pending.next), struct upc_req, rq_chain);
269 list_del(&(req->rq_chain));
270 if (! (req->rq_flags & REQ_ASYNC) ) {
271 list_add(&(req->rq_chain), channel->uc_processing.prev);
272 }
273 spin_unlock(&channel->uc_lock);
274
275 req->rq_flags |= REQ_READ;
276
277 /* Move the input args into userspace */
278 CDEBUG(D_PSDEV, "\n");
279 if (req->rq_bufsize <= count) {
280 result = req->rq_bufsize;
281 }
282
283 if (count < req->rq_bufsize) {
284 CERROR ("psdev_read: buffer too small, read %d of %d bytes\n",
285 count, req->rq_bufsize);
286 }
287
288 if ( copy_to_user(buf, req->rq_data, result) ) {
289 BUG();
290 return -EFAULT;
291 }
292
293 /* If request was asynchronous don't enqueue, but free */
294 if (req->rq_flags & REQ_ASYNC) {
295 CDEBUG(D_PSDEV, "psdev_read: async msg (%d, %d), result %d\n",
296 req->rq_opcode, req->rq_unique, result);
297 PRESTO_FREE(req->rq_data, req->rq_bufsize);
298 PRESTO_FREE(req, sizeof(*req));
299 return result;
300 }
301
302 return result;
303 }
304
305
presto_psdev_open(struct inode * inode,struct file * file)306 static int presto_psdev_open(struct inode * inode, struct file * file)
307 {
308 ENTRY;
309
310 file->private_data = NULL;
311
312 MOD_INC_USE_COUNT;
313
314 CDEBUG(D_PSDEV, "Psdev_open: caller: %d, flags: %d\n", current->pid, file->f_flags);
315
316 EXIT;
317 return 0;
318 }
319
320
321
presto_psdev_release(struct inode * inode,struct file * file)322 static int presto_psdev_release(struct inode * inode, struct file * file)
323 {
324 struct upc_channel *channel = (struct upc_channel *)file->private_data;
325 struct upc_req *req;
326 struct list_head *lh;
327 ENTRY;
328
329 if ( ! channel ) {
330 CERROR("%s: bad psdev file\n", __FUNCTION__);
331 return -EBADF;
332 }
333
334 MOD_DEC_USE_COUNT;
335 CDEBUG(D_PSDEV, "Lento: pid %d\n", current->pid);
336 channel->uc_pid = 0;
337
338 /* Wake up clients so they can return. */
339 CDEBUG(D_PSDEV, "Wake up clients sleeping for pending.\n");
340 spin_lock(&channel->uc_lock);
341 list_for_each(lh, &channel->uc_pending) {
342 req = list_entry(lh, struct upc_req, rq_chain);
343
344 /* Async requests stay around for a new lento */
345 if (req->rq_flags & REQ_ASYNC) {
346 continue;
347 }
348 /* the sleeper will free the req and data */
349 req->rq_flags |= REQ_DEAD;
350 wake_up(&req->rq_sleep);
351 }
352
353 CDEBUG(D_PSDEV, "Wake up clients sleeping for processing\n");
354 list_for_each(lh, &channel->uc_processing) {
355 req = list_entry(lh, struct upc_req, rq_chain);
356 /* freeing of req and data is done by the sleeper */
357 req->rq_flags |= REQ_DEAD;
358 wake_up(&req->rq_sleep);
359 }
360 spin_unlock(&channel->uc_lock);
361 CDEBUG(D_PSDEV, "Done.\n");
362
363 EXIT;
364 return 0;
365 }
366
367 static struct file_operations presto_psdev_fops = {
368 .read = presto_psdev_read,
369 .write = presto_psdev_write,
370 .poll = presto_psdev_poll,
371 .open = presto_psdev_open,
372 .release = presto_psdev_release
373 };
374
375 /* modules setup */
376 static struct miscdevice intermezzo_psdev = {
377 INTERMEZZO_MINOR,
378 "intermezzo",
379 &presto_psdev_fops
380 };
381
presto_psdev_init(void)382 int presto_psdev_init(void)
383 {
384 int i;
385 int err;
386
387 if ( (err = misc_register(&intermezzo_psdev)) ) {
388 CERROR("%s: cannot register %d err %d\n",
389 __FUNCTION__, INTERMEZZO_MINOR, err);
390 return -EIO;
391 }
392
393 memset(&izo_channels, 0, sizeof(izo_channels));
394 for ( i = 0 ; i < MAX_CHANNEL ; i++ ) {
395 struct upc_channel *channel = &(izo_channels[i]);
396 INIT_LIST_HEAD(&channel->uc_pending);
397 INIT_LIST_HEAD(&channel->uc_processing);
398 INIT_LIST_HEAD(&channel->uc_cache_list);
399 init_waitqueue_head(&channel->uc_waitq);
400 channel->uc_lock = SPIN_LOCK_UNLOCKED;
401 channel->uc_hard = 0;
402 channel->uc_no_filter = 0;
403 channel->uc_no_journal = 0;
404 channel->uc_no_upcall = 0;
405 channel->uc_timeout = 30;
406 channel->uc_errorval = 0;
407 channel->uc_minor = i;
408 }
409 return 0;
410 }
411
presto_psdev_cleanup(void)412 void presto_psdev_cleanup(void)
413 {
414 int i;
415
416 misc_deregister(&intermezzo_psdev);
417
418 for ( i = 0 ; i < MAX_CHANNEL ; i++ ) {
419 struct upc_channel *channel = &(izo_channels[i]);
420 struct list_head *lh, *next;
421
422 spin_lock(&channel->uc_lock);
423 if ( ! list_empty(&channel->uc_pending)) {
424 CERROR("Weird, tell Peter: module cleanup and pending list not empty dev %d\n", i);
425 }
426 if ( ! list_empty(&channel->uc_processing)) {
427 CERROR("Weird, tell Peter: module cleanup and processing list not empty dev %d\n", i);
428 }
429 if ( ! list_empty(&channel->uc_cache_list)) {
430 CERROR("Weird, tell Peter: module cleanup and cache listnot empty dev %d\n", i);
431 }
432 list_for_each_safe(lh, next, &channel->uc_pending) {
433 struct upc_req *req;
434
435 req = list_entry(lh, struct upc_req, rq_chain);
436 if ( req->rq_flags & REQ_ASYNC ) {
437 list_del(&(req->rq_chain));
438 CDEBUG(D_UPCALL, "free pending upcall type %d\n",
439 req->rq_opcode);
440 PRESTO_FREE(req->rq_data, req->rq_bufsize);
441 PRESTO_FREE(req, sizeof(struct upc_req));
442 } else {
443 req->rq_flags |= REQ_DEAD;
444 wake_up(&req->rq_sleep);
445 }
446 }
447 list_for_each(lh, &channel->uc_processing) {
448 struct upc_req *req;
449 req = list_entry(lh, struct upc_req, rq_chain);
450 list_del(&(req->rq_chain));
451 req->rq_flags |= REQ_DEAD;
452 wake_up(&req->rq_sleep);
453 }
454 spin_unlock(&channel->uc_lock);
455 }
456 }
457
458 /*
459 * lento_upcall and lento_downcall routines
460 */
lento_waitfor_upcall(struct upc_channel * channel,struct upc_req * req,int minor)461 static inline unsigned long lento_waitfor_upcall
462 (struct upc_channel *channel, struct upc_req *req, int minor)
463 {
464 DECLARE_WAITQUEUE(wait, current);
465 unsigned long posttime;
466
467 req->rq_posttime = posttime = jiffies;
468
469 add_wait_queue(&req->rq_sleep, &wait);
470 for (;;) {
471 if ( izo_channels[minor].uc_hard == 0 )
472 set_current_state(TASK_INTERRUPTIBLE);
473 else
474 set_current_state(TASK_UNINTERRUPTIBLE);
475
476 /* got a reply */
477 if ( req->rq_flags & (REQ_WRITE | REQ_DEAD) )
478 break;
479
480 /* these cases only apply when TASK_INTERRUPTIBLE */
481 if ( !izo_channels[minor].uc_hard && signal_pending(current) ) {
482 /* if this process really wants to die, let it go */
483 if (sigismember(&(current->pending.signal), SIGKILL)||
484 sigismember(&(current->pending.signal), SIGINT) )
485 break;
486 /* signal is present: after timeout always return
487 really smart idea, probably useless ... */
488 if ( time_after(jiffies, req->rq_posttime +
489 izo_channels[minor].uc_timeout * HZ) )
490 break;
491 }
492 schedule();
493 }
494
495 spin_lock(&channel->uc_lock);
496 list_del_init(&req->rq_chain);
497 spin_unlock(&channel->uc_lock);
498 remove_wait_queue(&req->rq_sleep, &wait);
499 set_current_state(TASK_RUNNING);
500
501 CDEBUG(D_SPECIAL, "posttime: %ld, returned: %ld\n",
502 posttime, jiffies-posttime);
503 return (jiffies - posttime);
504 }
505
506 /*
507 * lento_upcall will return an error in the case of
508 * failed communication with Lento _or_ will peek at Lento
509 * reply and return Lento's error.
510 *
511 * As lento has 2 types of errors, normal errors (positive) and internal
512 * errors (negative), normal errors are negated, while internal errors
513 * are all mapped to -EINTR, while showing a nice warning message. (jh)
514 *
515 * lento_upcall will always free buffer, either directly, when an upcall
516 * is read (in presto_psdev_read), when the filesystem is unmounted, or
517 * when the module is unloaded.
518 */
izo_upc_upcall(int minor,int * size,struct izo_upcall_hdr * buffer,int async)519 int izo_upc_upcall(int minor, int *size, struct izo_upcall_hdr *buffer,
520 int async)
521 {
522 unsigned long runtime;
523 struct upc_channel *channel;
524 struct izo_upcall_resp *out;
525 struct upc_req *req;
526 int error = 0;
527
528 ENTRY;
529 channel = &(izo_channels[minor]);
530
531 if (channel->uc_no_upcall) {
532 EXIT;
533 goto exit_buf;
534 }
535 if (!channel->uc_pid && !async) {
536 EXIT;
537 error = -ENXIO;
538 goto exit_buf;
539 }
540
541 /* Format the request message. */
542 PRESTO_ALLOC(req, sizeof(struct upc_req));
543 if ( !req ) {
544 EXIT;
545 error = -ENOMEM;
546 goto exit_buf;
547 }
548 req->rq_data = (void *)buffer;
549 req->rq_flags = 0;
550 req->rq_bufsize = *size;
551 req->rq_rep_size = 0;
552 req->rq_opcode = buffer->u_opc;
553 req->rq_unique = ++channel->uc_seq;
554 init_waitqueue_head(&req->rq_sleep);
555
556 /* Fill in the common input args. */
557 buffer->u_uniq = req->rq_unique;
558 buffer->u_async = async;
559
560 /* Remove potential datarace possibility*/
561 if ( async )
562 req->rq_flags = REQ_ASYNC;
563
564 spin_lock(&channel->uc_lock);
565 /* Append msg to pending queue and poke Lento. */
566 list_add(&req->rq_chain, channel->uc_pending.prev);
567 spin_unlock(&channel->uc_lock);
568 CDEBUG(D_UPCALL,
569 "Proc %d waking Lento %d for(opc,uniq) =(%d,%d) msg at %p.\n",
570 current->pid, channel->uc_pid, req->rq_opcode,
571 req->rq_unique, req);
572 wake_up_interruptible(&channel->uc_waitq);
573
574 if ( async ) {
575 /* req, rq_data are freed in presto_psdev_read for async */
576 /* req->rq_flags = REQ_ASYNC;*/
577 EXIT;
578 return 0;
579 }
580
581 /* We can be interrupted while we wait for Lento to process
582 * our request. If the interrupt occurs before Lento has read
583 * the request, we dequeue and return. If it occurs after the
584 * read but before the reply, we dequeue, send a signal
585 * message, and return. If it occurs after the reply we ignore
586 * it. In no case do we want to restart the syscall. If it
587 * was interrupted by a lento shutdown (psdev_close), return
588 * ENODEV. */
589
590 /* Go to sleep. Wake up on signals only after the timeout. */
591 runtime = lento_waitfor_upcall(channel, req, minor);
592
593 CDEBUG(D_TIMING, "opc: %d time: %ld uniq: %d size: %d\n",
594 req->rq_opcode, jiffies - req->rq_posttime,
595 req->rq_unique, req->rq_rep_size);
596 CDEBUG(D_UPCALL,
597 "..process %d woken up by Lento for req at 0x%x, data at %x\n",
598 current->pid, (int)req, (int)req->rq_data);
599
600 if (channel->uc_pid) { /* i.e. Lento is still alive */
601 /* Op went through, interrupt or not we go on */
602 if (req->rq_flags & REQ_WRITE) {
603 out = (struct izo_upcall_resp *)req->rq_data;
604 /* here we map positive Lento errors to kernel errors */
605 if ( out->result < 0 ) {
606 CERROR("Tell Peter: Lento returns negative error %d, for oc %d!\n",
607 out->result, out->opcode);
608 out->result = EINVAL;
609 }
610 error = -out->result;
611 CDEBUG(D_UPCALL, "upcall: (u,o,r) (%d, %d, %d) out at %p\n",
612 out->unique, out->opcode, out->result, out);
613 *size = req->rq_rep_size;
614 EXIT;
615 goto exit_req;
616 }
617 /* Interrupted before lento read it. */
618 if ( !(req->rq_flags & REQ_READ) && signal_pending(current)) {
619 CDEBUG(D_UPCALL,
620 "Interrupt before read: (op,un)=(%d,%d), flags %x\n",
621 req->rq_opcode, req->rq_unique, req->rq_flags);
622 /* perhaps the best way to convince the app to give up? */
623 error = -EINTR;
624 EXIT;
625 goto exit_req;
626 }
627
628 /* interrupted after Lento did its read, send signal */
629 if ( (req->rq_flags & REQ_READ) && signal_pending(current) ) {
630 CDEBUG(D_UPCALL,"Interrupt after read: op = %d.%d, flags = %x\n",
631 req->rq_opcode, req->rq_unique, req->rq_flags);
632
633 error = -EINTR;
634 } else {
635 CERROR("Lento: Strange interruption - tell Peter.\n");
636 error = -EINTR;
637 }
638 } else { /* If lento died i.e. !UC_OPEN(channel) */
639 CERROR("lento_upcall: Lento dead on (op,un) (%d.%d) flags %d\n",
640 req->rq_opcode, req->rq_unique, req->rq_flags);
641 error = -ENODEV;
642 }
643
644 exit_req:
645 PRESTO_FREE(req, sizeof(struct upc_req));
646 exit_buf:
647 PRESTO_FREE(buffer,*size);
648 return error;
649 }
650