Unmap pages mapped during a failed fill_vmr()
[akaros.git] / kern / drivers / dev / pipe.c
1 /* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
2  * Portions Copyright © 1997-1999 Vita Nuova Limited
3  * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
4  *                                (www.vitanuova.com)
5  * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
6  *
7  * Modified for the Akaros operating system:
8  * Copyright (c) 2013-2014 The Regents of the University of California
9  * Copyright (c) 2013-2015 Google Inc.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE. */
28
29 #include <slab.h>
30 #include <kmalloc.h>
31 #include <kref.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <assert.h>
35 #include <error.h>
36 #include <cpio.h>
37 #include <pmap.h>
38 #include <smp.h>
39 #include <net/ip.h>
40
41 struct dev pipedevtab;
42
43 static char *devname(void)
44 {
45         return pipedevtab.name;
46 }
47
48 typedef struct Pipe Pipe;
49 struct Pipe {
50         qlock_t qlock;
51         Pipe *next;
52         struct kref ref;
53         uint32_t path;
54         struct queue *q[2];
55         int qref[2];
56         struct dirtab *pipedir;
57         char *user;
58         struct fdtap_slist data_taps;
59         spinlock_t tap_lock;
60 };
61
62 static struct {
63         spinlock_t lock;
64         uint32_t path;
65         int pipeqsize;
66 } pipealloc;
67
68 enum {
69         Qdir,
70         Qctl,
71         Qdata0,
72         Qdata1,
73 };
74
75 static
76 struct dirtab pipedir[] = {
77         {".", {Qdir, 0, QTDIR}, 0, DMDIR | 0500},
78         {"ctl", {Qctl}, 0, 0660},
79         {"data", {Qdata0}, 0, 0660},
80         {"data1", {Qdata1}, 0, 0660},
81 };
82
83 static void freepipe(Pipe * p)
84 {
85         if (p != NULL) {
86                 kfree(p->user);
87                 kfree(p->q[0]);
88                 kfree(p->q[1]);
89                 kfree(p->pipedir);
90                 kfree(p);
91         }
92 }
93
94 static void pipe_release(struct kref *kref)
95 {
96         Pipe *pipe = container_of(kref, Pipe, ref);
97         freepipe(pipe);
98 }
99
100 static void pipeinit(void)
101 {
102         pipealloc.pipeqsize = 32 * 1024;
103 }
104
105 /*
106  *  create a pipe, no streams are created until an open
107  */
108 static struct chan *pipeattach(char *spec)
109 {
110         ERRSTACK(2);
111         Pipe *p;
112         struct chan *c;
113
114         c = devattach(devname(), spec);
115         p = kzmalloc(sizeof(Pipe), 0);
116         if (p == 0)
117                 error(ENOMEM, ERROR_FIXME);
118         if (waserror()) {
119                 freepipe(p);
120                 nexterror();
121         }
122         p->pipedir = kzmalloc(sizeof(pipedir), 0);
123         if (p->pipedir == 0)
124                 error(ENOMEM, ERROR_FIXME);
125         memmove(p->pipedir, pipedir, sizeof(pipedir));
126         kstrdup(&p->user, current->user.name);
127         kref_init(&p->ref, pipe_release, 1);
128         qlock_init(&p->qlock);
129
130         p->q[0] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
131         if (p->q[0] == 0)
132                 error(ENOMEM, ERROR_FIXME);
133         p->q[1] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
134         if (p->q[1] == 0)
135                 error(ENOMEM, ERROR_FIXME);
136         poperror();
137
138         spin_lock(&(&pipealloc)->lock);
139         p->path = ++pipealloc.path;
140         spin_unlock(&(&pipealloc)->lock);
141
142         c->qid.path = NETQID(2 * p->path, Qdir);
143         c->qid.vers = 0;
144         c->qid.type = QTDIR;
145         c->aux = p;
146         c->dev = 0;
147
148         /* taps. */
149         SLIST_INIT(&p->data_taps);      /* already = 0; set to be futureproof */
150         spinlock_init(&p->tap_lock);
151         return c;
152 }
153
154 static int
155 pipegen(struct chan *c, char *unused,
156                 struct dirtab *tab, int ntab, int i, struct dir *dp)
157 {
158         int id, len;
159         struct qid qid;
160         Pipe *p;
161
162         if (i == DEVDOTDOT) {
163                 devdir(c, c->qid, devname(), 0, eve.name, 0555, dp);
164                 return 1;
165         }
166         i++;    /* skip . */
167         if (tab == 0 || i >= ntab)
168                 return -1;
169         tab += i;
170         p = c->aux;
171         switch (NETTYPE(tab->qid.path)) {
172                 case Qdata0:
173                         len = qlen(p->q[0]);
174                         break;
175                 case Qdata1:
176                         len = qlen(p->q[1]);
177                         break;
178                 default:
179                         len = tab->length;
180                         break;
181         }
182         id = NETID(c->qid.path);
183         qid.path = NETQID(id, tab->qid.path);
184         qid.vers = 0;
185         qid.type = QTFILE;
186         devdir(c, qid, tab->name, len, eve.name, tab->perm, dp);
187         return 1;
188 }
189
190 static struct walkqid *pipewalk(struct chan *c, struct chan *nc, char **name,
191                                 unsigned int nname)
192 {
193         struct walkqid *wq;
194         Pipe *p;
195
196         p = c->aux;
197         wq = devwalk(c, nc, name, nname, p->pipedir, ARRAY_SIZE(pipedir),
198                      pipegen);
199         if (wq != NULL && wq->clone != NULL && wq->clone != c) {
200                 qlock(&p->qlock);
201                 kref_get(&p->ref, 1);
202                 if (c->flag & COPEN) {
203                         switch (NETTYPE(c->qid.path)) {
204                                 case Qdata0:
205                                         p->qref[0]++;
206                                         break;
207                                 case Qdata1:
208                                         p->qref[1]++;
209                                         break;
210                         }
211                 }
212                 qunlock(&p->qlock);
213         }
214         return wq;
215 }
216
217 static size_t pipestat(struct chan *c, uint8_t *db, size_t n)
218 {
219         Pipe *p;
220         struct dir dir;
221         struct dirtab *tab;
222         int perm;
223         int type = NETTYPE(c->qid.path);
224
225         p = c->aux;
226         tab = p->pipedir;
227
228         switch (type) {
229         case Qdir:
230         case Qctl:
231                 devdir(c, c->qid, tab[type].name, tab[type].length, eve.name,
232                        tab[type].perm, &dir);
233                 break;
234         case Qdata0:
235                 perm = tab[1].perm;
236                 perm |= qreadable(p->q[0]) ? DMREADABLE : 0;
237                 perm |= qwritable(p->q[1]) ? DMWRITABLE : 0;
238                 devdir(c, c->qid, tab[1].name, qlen(p->q[0]), eve.name, perm,
239                        &dir);
240                 break;
241         case Qdata1:
242                 perm = tab[2].perm;
243                 perm |= qreadable(p->q[1]) ? DMREADABLE : 0;
244                 perm |= qwritable(p->q[0]) ? DMWRITABLE : 0;
245                 devdir(c, c->qid, tab[2].name, qlen(p->q[1]), eve.name, perm,
246                        &dir);
247                 break;
248         default:
249                 panic("pipestat");
250         }
251         n = convD2M(&dir, db, n);
252         if (n < BIT16SZ)
253                 error(ENODATA, ERROR_FIXME);
254         return n;
255 }
256
257 /*
258  *  if the stream doesn't exist, create it
259  */
260 static struct chan *pipeopen(struct chan *c, int omode)
261 {
262         ERRSTACK(2);
263         Pipe *p;
264
265         if (c->qid.type & QTDIR) {
266                 if (omode & O_WRITE)
267                         error(EINVAL,
268                               "Can only open directories O_READ, mode is %o oct",
269                               omode);
270                 c->mode = openmode(omode);
271                 c->flag |= COPEN;
272                 c->offset = 0;
273                 return c;
274         }
275
276         openmode(omode);        /* check it */
277
278         p = c->aux;
279         qlock(&p->qlock);
280         if (waserror()) {
281                 qunlock(&p->qlock);
282                 nexterror();
283         }
284         switch (NETTYPE(c->qid.path)) {
285         case Qdata0:
286                 devpermcheck(p->user, p->pipedir[1].perm, omode);
287                 p->qref[0]++;
288                 break;
289         case Qdata1:
290                 devpermcheck(p->user, p->pipedir[2].perm, omode);
291                 p->qref[1]++;
292                 break;
293         }
294         poperror();
295         qunlock(&p->qlock);
296
297         c->mode = openmode(omode);
298         c->flag |= COPEN;
299         c->offset = 0;
300         c->iounit = qiomaxatomic;
301         return c;
302 }
303
304 static void pipeclose(struct chan *c)
305 {
306         Pipe *p;
307
308         p = c->aux;
309         qlock(&p->qlock);
310
311         if (c->flag & COPEN) {
312                 /*
313                  *  closing either side hangs up the stream
314                  */
315                 switch (NETTYPE(c->qid.path)) {
316                 case Qdata0:
317                         p->qref[0]--;
318                         if (p->qref[0] == 0) {
319                                 qhangup(p->q[1], 0);
320                                 qclose(p->q[0]);
321                         }
322                         break;
323                 case Qdata1:
324                         p->qref[1]--;
325                         if (p->qref[1] == 0) {
326                                 qhangup(p->q[0], 0);
327                                 qclose(p->q[1]);
328                         }
329                         break;
330                 }
331         }
332
333         /*
334          *  if both sides are closed, they are reusable
335          */
336         if (p->qref[0] == 0 && p->qref[1] == 0) {
337                 qreopen(p->q[0]);
338                 qreopen(p->q[1]);
339         }
340
341         qunlock(&p->qlock);
342         /*
343          *  free the structure on last close
344          */
345         kref_put(&p->ref);
346 }
347
348 static size_t piperead(struct chan *c, void *va, size_t n, off64_t offset)
349 {
350         Pipe *p;
351
352         p = c->aux;
353
354         switch (NETTYPE(c->qid.path)) {
355         case Qdir:
356                 return devdirread(c, va, n, p->pipedir, ARRAY_SIZE(pipedir),
357                                                   pipegen);
358         case Qctl:
359                 return readnum(offset, va, n, p->path, NUMSIZE32);
360         case Qdata0:
361                 if (c->flag & O_NONBLOCK)
362                         return qread_nonblock(p->q[0], va, n);
363                 else
364                         return qread(p->q[0], va, n);
365         case Qdata1:
366                 if (c->flag & O_NONBLOCK)
367                         return qread_nonblock(p->q[1], va, n);
368                 else
369                         return qread(p->q[1], va, n);
370         default:
371                 panic("piperead");
372         }
373         return -1;      /* not reached */
374 }
375
376 static struct block *pipebread(struct chan *c, size_t n, off64_t offset)
377 {
378         Pipe *p;
379
380         p = c->aux;
381
382         switch (NETTYPE(c->qid.path)) {
383         case Qdata0:
384                 if (c->flag & O_NONBLOCK)
385                         return qbread_nonblock(p->q[0], n);
386                 else
387                         return qbread(p->q[0], n);
388         case Qdata1:
389                 if (c->flag & O_NONBLOCK)
390                         return qbread_nonblock(p->q[1], n);
391                 else
392                         return qbread(p->q[1], n);
393         }
394
395         return devbread(c, n, offset);
396 }
397
398 /*
399  *  A write to a closed pipe causes an EPIPE error to be thrown.
400  */
401 static size_t pipewrite(struct chan *c, void *va, size_t n, off64_t ignored)
402 {
403         ERRSTACK(1);
404         Pipe *p;
405         struct cmdbuf *cb;
406
407         p = c->aux;
408
409         switch (NETTYPE(c->qid.path)) {
410         case Qctl:
411                 cb = parsecmd(va, n);
412                 if (waserror()) {
413                         kfree(cb);
414                         nexterror();
415                 }
416                 if (cb->nf < 1)
417                         error(EFAIL, "short control request");
418                 if (strcmp(cb->f[0], "oneblock") == 0) {
419                         q_toggle_qmsg(p->q[0], TRUE);
420                         q_toggle_qcoalesce(p->q[0], TRUE);
421                         q_toggle_qmsg(p->q[1], TRUE);
422                         q_toggle_qcoalesce(p->q[1], TRUE);
423                 } else {
424                         error(EFAIL, "unknown control request");
425                 }
426                 kfree(cb);
427                 poperror();
428                 break;
429
430         case Qdata0:
431                 if (c->flag & O_NONBLOCK)
432                         n = qwrite_nonblock(p->q[1], va, n);
433                 else
434                         n = qwrite(p->q[1], va, n);
435                 break;
436
437         case Qdata1:
438                 if (c->flag & O_NONBLOCK)
439                         n = qwrite_nonblock(p->q[0], va, n);
440                 else
441                         n = qwrite(p->q[0], va, n);
442                 break;
443
444         default:
445                 panic("pipewrite");
446         }
447
448         return n;
449 }
450
451 static size_t pipebwrite(struct chan *c, struct block *bp, off64_t offset)
452 {
453         long n;
454         Pipe *p;
455         //Prog *r;
456
457         p = c->aux;
458         switch (NETTYPE(c->qid.path)) {
459         case Qctl:
460                 return devbwrite(c, bp, offset);
461         case Qdata0:
462                 if (c->flag & O_NONBLOCK)
463                         n = qbwrite_nonblock(p->q[1], bp);
464                 else
465                         n = qbwrite(p->q[1], bp);
466                 break;
467
468         case Qdata1:
469                 if (c->flag & O_NONBLOCK)
470                         n = qbwrite_nonblock(p->q[0], bp);
471                 else
472                         n = qbwrite(p->q[0], bp);
473                 break;
474
475         default:
476                 n = 0;
477                 panic("pipebwrite");
478         }
479
480         return n;
481 }
482
483 static size_t pipewstat(struct chan *c, uint8_t *dp, size_t n)
484 {
485         ERRSTACK(2);
486         struct dir *d;
487         Pipe *p;
488         int d1;
489
490         if (c->qid.type & QTDIR)
491                 error(EPERM, ERROR_FIXME);
492         p = c->aux;
493         if (strcmp(current->user.name, p->user) != 0)
494                 error(EPERM, ERROR_FIXME);
495         d = kzmalloc(sizeof(*d) + n, 0);
496         if (waserror()) {
497                 kfree(d);
498                 nexterror();
499         }
500         n = convM2D(dp, n, d, (char *)&d[1]);
501         if (n == 0)
502                 error(ENODATA, ERROR_FIXME);
503         d1 = NETTYPE(c->qid.path) == Qdata1;
504         if (!emptystr(d->name)) {
505                 validwstatname(d->name);
506                 if (strlen(d->name) >= KNAMELEN)
507                         error(ENAMETOOLONG, ERROR_FIXME);
508                 if (strncmp(p->pipedir[1 + !d1].name, d->name, KNAMELEN) == 0)
509                         error(EEXIST, ERROR_FIXME);
510                 strlcpy(p->pipedir[1 + d1].name, d->name, KNAMELEN);
511         }
512         if (d->mode != -1)
513                 p->pipedir[d1 + 1].perm = d->mode & 0777;
514         poperror();
515         kfree(d);
516         return n;
517 }
518
519 static char *pipechaninfo(struct chan *chan, char *ret, size_t ret_l)
520 {
521         Pipe *p = chan->aux;
522
523         switch (NETTYPE(chan->qid.path)) {
524         case Qdir:
525                 snprintf(ret, ret_l, "Qdir, ID %d", p->path);
526                 break;
527         case Qctl:
528                 snprintf(ret, ret_l, "Qctl, ID %d", p->path);
529                 break;
530         case Qdata0:
531                 snprintf(ret, ret_l,
532                          "Qdata%d, ID %d, %s, rq len %d, wq len %d, total read %llu",
533                          0, p->path,
534                          SLIST_EMPTY(&p->data_taps) ? "untapped" : "tapped",
535                          qlen(p->q[0]),
536                          qlen(p->q[1]), q_bytes_read(p->q[0]));
537                 break;
538         case Qdata1:
539                 snprintf(ret, ret_l,
540                          "Qdata%d, ID %d, %s, rq len %d, wq len %d, total read %llu",
541                          1, p->path,
542                          SLIST_EMPTY(&p->data_taps) ? "untapped" : "tapped",
543                          qlen(p->q[1]),
544                          qlen(p->q[0]), q_bytes_read(p->q[1]));
545                 break;
546         default:
547                 ret = "Unknown type";
548                 break;
549         }
550         return ret;
551 }
552
553 /* We pass the pipe as data.  The pipe will outlive any potential qio callbacks.
554  * Meaning, we don't need to worry about the pipe disappearing if we're in here.
555  * If we're in here, then the q exists, which means the pipe exists.
556  *
557  * However, the chans do not necessarily exist.  The taps keep the chans around.
558  * So we only know which chan we're firing when we look at an individual tap. */
559 static void pipe_wake_cb(struct queue *q, void *data, int filter)
560 {
561         Pipe *p = (Pipe*)data;
562         struct fd_tap *tap_i;
563         struct chan *chan;
564
565         spin_lock(&p->tap_lock);
566         SLIST_FOREACH(tap_i, &p->data_taps, link) {
567                 chan = tap_i->chan;
568                 /* Depending which chan did the tapping, we'll care about
569                  * different filters on different qs.  For instance, if we
570                  * tapped Qdata0, then we only care about readables on q[0],
571                  * writables on q[1], and hangups on either.  More precisely, we
572                  * don't care about writables on q[0] or readables on q[1].
573                  *
574                  * Note the *tap's* filter might differ from the CB's filter.
575                  * The CB could be for read|write|hangup on q[1], with a Qdata0
576                  * tap for just read.  We don't want to just pass the CB filt
577                  * directly to fire_tap, since that would pass the CB's read on
578                  * q[1] to the tap and fire.  The user would think q[0] was
579                  * readable.  This is why I mask out the CB filter events that
580                  * we know they don't want. */
581                 switch (NETTYPE(chan->qid.path)) {
582                 case Qdata0:
583                         if (q == p->q[0])
584                                 filter &= ~FDTAP_FILT_WRITABLE;
585                         else
586                                 filter &= ~FDTAP_FILT_READABLE;
587                         break;
588                 case Qdata1:
589                         if (q == p->q[1])
590                                 filter &= ~FDTAP_FILT_WRITABLE;
591                         else
592                                 filter &= ~FDTAP_FILT_READABLE;
593                         break;
594                 default:
595                         panic("Shouldn't be able to tap pipe qid %p",
596                               chan->qid.path);
597                 }
598                 fire_tap(tap_i, filter);
599         }
600         spin_unlock(&p->tap_lock);
601 }
602
603 static int pipetapfd(struct chan *chan, struct fd_tap *tap, int cmd)
604 {
605         int ret;
606         Pipe *p;
607
608         p = chan->aux;
609 #define DEVPIPE_LEGAL_DATA_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
610                                  FDTAP_FILT_HANGUP | FDTAP_FILT_ERROR)
611
612         switch (NETTYPE(chan->qid.path)) {
613         case Qdata0:
614         case Qdata1:
615                 if (tap->filter & ~DEVPIPE_LEGAL_DATA_TAPS) {
616                         set_errno(ENOSYS);
617                         set_errstr("Unsupported #%s data tap %p, must be %p",
618                                    devname(), tap->filter,
619                                    DEVPIPE_LEGAL_DATA_TAPS);
620                         return -1;
621                 }
622                 spin_lock(&p->tap_lock);
623                 switch (cmd) {
624                 case (FDTAP_CMD_ADD):
625                         if (SLIST_EMPTY(&p->data_taps)) {
626                                 qio_set_wake_cb(p->q[0], pipe_wake_cb, p);
627                                 qio_set_wake_cb(p->q[1], pipe_wake_cb, p);
628                         }
629                         SLIST_INSERT_HEAD(&p->data_taps, tap, link);
630                         ret = 0;
631                         break;
632                 case (FDTAP_CMD_REM):
633                         SLIST_REMOVE(&p->data_taps, tap, fd_tap, link);
634                         if (SLIST_EMPTY(&p->data_taps)) {
635                                 qio_set_wake_cb(p->q[0], 0, p);
636                                 qio_set_wake_cb(p->q[1], 0, p);
637                         }
638                         ret = 0;
639                         break;
640                 default:
641                         set_errno(ENOSYS);
642                         set_errstr("Unsupported #%s data tap command %p",
643                                    devname(), cmd);
644                         ret = -1;
645                 }
646                 spin_unlock(&p->tap_lock);
647                 return ret;
648         default:
649                 set_errno(ENOSYS);
650                 set_errstr("Can't tap #%s file type %d", devname(),
651                            NETTYPE(chan->qid.path));
652                 return -1;
653         }
654 }
655
656 static unsigned long pipe_chan_ctl(struct chan *c, int op, unsigned long a1,
657                                    unsigned long a2, unsigned long a3,
658                                    unsigned long a4)
659 {
660         switch (op) {
661         case CCTL_SET_FL:
662                 return 0;
663         default:
664                 error(EINVAL, "%s does not support %d", __func__, op);
665         }
666 }
667
668 struct dev pipedevtab __devtab = {
669         .name = "pipe",
670
671         .reset = devreset,
672         .init = pipeinit,
673         .shutdown = devshutdown,
674         .attach = pipeattach,
675         .walk = pipewalk,
676         .stat = pipestat,
677         .open = pipeopen,
678         .create = devcreate,
679         .close = pipeclose,
680         .read = piperead,
681         .bread = pipebread,
682         .write = pipewrite,
683         .bwrite = pipebwrite,
684         .remove = devremove,
685         .wstat = pipewstat,
686         .power = devpower,
687         .chaninfo = pipechaninfo,
688         .tapfd = pipetapfd,
689         .chan_ctl = pipe_chan_ctl,
690 };