9ns: Fix issues with can_have_children
[akaros.git] / kern / src / ns / sysfile.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 #include <rcu.h>
41
42 /* TODO: these sizes are hokey.  DIRSIZE is used in chandirstat, and it looks
43  * like it's the size of a common-case stat. */
44 enum {
45         DIRSIZE = STAT_FIX_LEN_AK + 32 * STAT_NR_STRINGS_AK,
46         DIRREADLIM = 2048,      /* should handle the largest reasonable directory entry */
47         DIRREADSIZE=8192,       /* Just read a lot. Memory is cheap, lots of bandwidth,
48                                  * and RPCs are very expensive. At the same time,
49                                  * let's not yet exceed a common MSIZE. */
50 };
51
52 int newfd(struct chan *c, int low_fd, int oflags, bool must_use_low)
53 {
54         int ret = insert_obj_fdt(&current->open_files, c, low_fd,
55                                  oflags & O_CLOEXEC ? FD_CLOEXEC : 0,
56                                  must_use_low);
57         if (ret >= 0)
58                 cclose(c);
59         return ret;
60 }
61
62 struct chan *fdtochan(struct fd_table *fdt, int fd, int mode, int chkmnt,
63                       int iref)
64 {
65         struct chan *c;
66
67         c = lookup_fd(fdt, fd, iref);
68         if (!c) {
69                 /* We lost the info about why there was a problem (we used to track file
70                  * group closed too, can add that in later). */
71                 error(EBADF, ERROR_FIXME);
72         }
73         if (chkmnt && (c->flag & CMSG)) {
74                 if (iref)
75                         cclose(c);
76                 error(EBADF, ERROR_FIXME);
77         }
78         if (mode < 0)
79                 return c;
80         if ((mode & c->mode) != mode) {
81                 if (iref)
82                         cclose(c);
83                 error(EBADF,
84                       "FD access mode failure: chan mode 0x%x, wanted 0x%x (opened with 0 instead of O_READ?)",
85                       c->mode, mode);
86         }
87         return c;
88 }
89
90 long kchanio(void *vc, void *buf, int n, int mode)
91 {
92         ERRSTACK(1);
93         int r;
94         struct chan *c;
95
96         c = vc;
97         if (waserror()) {
98                 poperror();
99                 return -1;
100         }
101
102         if (mode == O_READ)
103                 r = devtab[c->type].read(c, buf, n, c->offset);
104         else if (mode == O_WRITE)
105                 r = devtab[c->type].write(c, buf, n, c->offset);
106         else
107                 error(ENOSYS, "kchanio: use only O_READ xor O_WRITE");
108
109         spin_lock(&c->lock);
110         c->offset += r;
111         spin_unlock(&c->lock);
112         poperror();
113         return r;
114 }
115
116 int openmode(uint32_t omode)
117 {
118 /* GIANT WARNING: if this ever throws, ipopen (and probably many others) will
119  * screw up refcnts of Qctl, err, data, etc */
120 #if 0
121         /* this is the old plan9 style.  i think they want to turn exec into read,
122          * and strip off anything higher, and just return the RD/WR style bits.  not
123          * stuff like ORCLOSE.  the lack of OEXCL might be a bug on their part (it's
124          * the only one of their non-RW-related flags that isn't masked out).
125          *
126          * Note that we no longer convert OEXEC/O_EXEC to O_READ, and instead return
127          * just the O_ACCMODE bits. */
128         if (o >= (OTRUNC | OCEXEC | ORCLOSE | OEXEC))
129                 error(EINVAL, ERROR_FIXME);
130         o &= ~(OTRUNC | OCEXEC | ORCLOSE);
131         if (o > OEXEC)
132                 error(EINVAL, ERROR_FIXME);
133         if (o == OEXEC)
134                 return OREAD;
135         return o;
136 #endif
137         /* no error checking (we have a shitload of flags anyway), and we return the
138          * basic access modes (RD/WR/ETC) */
139         return omode & O_ACCMODE;
140 }
141
142 void fdclose(struct fd_table *fdt, int fd)
143 {
144         close_fd(fdt, fd);
145 }
146
147 static void set_dot(struct chan *c)
148 {
149         c = atomic_swap_ptr((void**)&current->dot, c);
150         synchronize_rcu();
151         cclose(c);
152 }
153
154 int syschdir(char *path)
155 {
156         ERRSTACK(1);
157         struct chan *c;
158
159         if (waserror()) {
160                 poperror();
161                 return -1;
162         }
163         c = namec(path, Atodir, 0, 0, NULL);
164         poperror();
165         set_dot(c);
166         return 0;
167 }
168
169 int sysfchdir(int fd)
170 {
171         ERRSTACK(1);
172         struct chan *c;
173
174         if (waserror()) {
175                 poperror();
176                 return -1;
177         }
178         c = fdtochan(&current->open_files, fd, -1, 0, 1);
179         poperror();
180
181         /* This is a little hokey.  Ideally, we'd only allow O_PATH fds to be
182          * fchdir'd.  Linux/POSIX lets you do arbitrary FDs.  Luckily, we stored the
183          * name when we walked (__namec_from), so we should be able to recreate the
184          * chan.  Using namec() with channame() is a more heavy-weight cclone(), but
185          * also might have issues if the chan has since been removed or the
186          * namespace is otherwise different from when the original fd/chan was first
187          * created. */
188         if (c->flag & O_PATH) {
189                 set_dot(c);
190                 return 0;
191         }
192         if (waserror()) {
193                 cclose(c);
194                 poperror();
195                 return -1;
196         }
197         syschdir(channame(c));
198         cclose(c);
199         poperror();
200
201         return 0;
202 }
203
204 int sysclose(int fd)
205 {
206         ERRSTACK(1);
207         struct fd_table *fdt = &current->open_files;
208
209         if (waserror()) {
210                 poperror();
211                 return -1;
212         }
213         /*
214          * Take no reference on the chan because we don't really need the
215          * data structure, and are calling fdtochan only for error checks.
216          * fdclose takes care of processes racing through here.
217          */
218         fdtochan(fdt, fd, -1, 0, 0);
219         fdclose(fdt, fd);
220         poperror();
221         return 0;
222 }
223
224 int syscreate(char *path, int mode, uint32_t perm)
225 {
226         ERRSTACK(2);
227         int fd;
228         struct chan *c;
229
230         if (waserror()) {
231                 poperror();
232                 return -1;
233         }
234
235         openmode(mode & ~O_EXCL);       /* error check only; OEXCL okay here */
236         c = namec(path, Acreate, mode, perm, NULL);
237         if (waserror()) {
238                 cclose(c);
239                 nexterror();
240         }
241         /* 9ns mode is the O_FLAGS and perm is glibc mode */
242         fd = newfd(c, 0, mode, FALSE);
243         if (fd < 0)
244                 error(-fd, ERROR_FIXME);
245         poperror();
246
247         poperror();
248         return fd;
249 }
250
251 int sysdup(int old, int low_fd, bool must_use_low)
252 {
253         ERRSTACK(1);
254         int fd;
255         struct chan *c;
256
257         if (waserror()) {
258                 poperror();
259                 return -1;
260         }
261         c = fdtochan(&current->open_files, old, -1, 0, 1);
262         if (c->qid.type & QTAUTH) {
263                 cclose(c);
264                 error(EPERM, ERROR_FIXME);
265         }
266         fd = newfd(c, low_fd, 0, must_use_low);
267         if (fd < 0) {
268                 cclose(c);
269                 error(-fd, ERROR_FIXME);
270         }
271         poperror();
272         return fd;
273 }
274
275 /* Could pass in the fdt instead of the proc, but we used to need the to_proc
276  * for now so we can claim a VFS FD.  Careful, we don't close the old chan. */
277 int sys_dup_to(struct proc *from_proc, unsigned int from_fd,
278                struct proc *to_proc, unsigned int to_fd)
279 {
280         ERRSTACK(1);
281         int ret;
282         struct chan *c;
283
284         if (waserror()) {
285                 poperror();
286                 return -1;
287         }
288         c = fdtochan(&from_proc->open_files, from_fd, -1, 0, 1);
289         if (c->qid.type & QTAUTH) {
290                 cclose(c);
291                 error(EPERM, ERROR_FIXME);
292         }
293         ret = insert_obj_fdt(&to_proc->open_files, c, to_fd, 0, TRUE);
294         /* drop the ref from fdtochan.  if insert succeeded, there is one other ref
295          * stored in the FDT */
296         cclose(c);
297         if (ret < 0)
298                 error(EFAIL, "Can't insert FD %d into FDG", to_fd);
299         poperror();
300         return 0;
301 }
302
303 char *sysfd2path(int fd)
304 {
305         ERRSTACK(1);
306         struct chan *c;
307         char *s;
308
309         if (waserror()) {
310                 poperror();
311                 return NULL;
312         }
313         c = fdtochan(&current->open_files, fd, -1, 0, 1);
314         s = NULL;
315         if (c->name != NULL) {
316                 s = kzmalloc(c->name->len + 1, 0);
317                 if (s == NULL) {
318                         cclose(c);
319                         error(ENOMEM, ERROR_FIXME);
320                 }
321                 memmove(s, c->name->s, c->name->len + 1);
322         }
323         cclose(c);
324         poperror();
325         return s;
326 }
327
328 char *sysgetcwd(void)
329 {
330         char *s = NULL;
331         struct chan *dot;
332
333         rcu_read_lock();
334         dot = rcu_dereference(current->dot);
335         kref_get(&dot->ref, 1);
336         rcu_read_unlock();
337         if (dot->name)
338                 kstrdup(&s, dot->name->s);
339         cclose(dot);
340         return s;
341 }
342
343 int sysfauth(int fd, char *aname)
344 {
345         ERRSTACK(2);
346         struct chan *c, *ac;
347
348         if (waserror()) {
349                 poperror();
350                 return -1;
351         }
352
353         validname(aname, 0);
354         c = fdtochan(&current->open_files, fd, O_RDWR, 0, 1);
355         if (waserror()) {
356                 cclose(c);
357                 nexterror();
358         }
359
360         ac = mntauth(c, aname);
361
362         /* at this point ac is responsible for keeping c alive */
363         poperror();     /* c */
364         cclose(c);
365
366         if (waserror()) {
367                 cclose(ac);
368                 nexterror();
369         }
370
371         fd = newfd(ac, 0, 0, FALSE);
372         if (fd < 0)
373                 error(-fd, ERROR_FIXME);
374         poperror();     /* ac */
375
376         poperror();
377
378         return fd;
379 }
380
381 int sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen)
382 {
383         ERRSTACK(2);
384         int m;
385         struct chan *c;
386
387         if (waserror()) {
388                 poperror();
389                 return -1;
390         }
391
392         /* check there's a NUL in the version string */
393         if (arglen == 0 || memchr(vers, 0, arglen) == 0)
394                 error(EINVAL, ERROR_FIXME);
395
396         c = fdtochan(&current->open_files, fd, O_RDWR, 0, 1);
397         if (waserror()) {
398                 cclose(c);
399                 nexterror();
400         }
401
402         m = mntversion(c, vers, msize, arglen);
403
404         poperror();
405         cclose(c);
406
407         poperror();
408         return m;
409 }
410
411 int sysfwstat(int fd, uint8_t * buf, int n)
412 {
413         ERRSTACK(2);
414         struct chan *c;
415
416         if (waserror()) {
417                 poperror();
418                 return -1;
419         }
420
421         validstat(buf, n, 0);
422         c = fdtochan(&current->open_files, fd, -1, 1, 1);
423         if (waserror()) {
424                 cclose(c);
425                 nexterror();
426         }
427         n = devtab[c->type].wstat(c, buf, n);
428         poperror();
429         cclose(c);
430
431         poperror();
432         return n;
433 }
434
435 long bindmount(struct chan *c, char *old, int flag, char *spec)
436 {
437         ERRSTACK(1);
438         int ret;
439         struct chan *c1;
440
441         if (flag > MMASK || (flag & MORDER) == (MBEFORE | MAFTER))
442                 error(EINVAL, ERROR_FIXME);
443
444         c1 = namec(old, Amount, 0, 0, NULL);
445         if (waserror()) {
446                 cclose(c1);
447                 nexterror();
448         }
449         ret = cmount(c, c1, flag, spec);
450
451         poperror();
452         cclose(c1);
453         return ret;
454 }
455
456 int sysbind(char *new, char *old, int flags)
457 {
458         ERRSTACK(2);
459         long r;
460         struct chan *c0;
461
462         if (waserror()) {
463                 poperror();
464                 return -1;
465         }
466
467         c0 = namec(new, Abind, 0, 0, NULL);
468         if (waserror()) {
469                 cclose(c0);
470                 nexterror();
471         }
472         r = bindmount(c0, old, flags, "");
473         poperror();
474         cclose(c0);
475
476         poperror();
477         return r;
478 }
479
480 int syssymlink(char *new_path, char *old_path)
481 {
482         ERRSTACK(1);
483         struct chan *c;
484
485         if (waserror()) {
486                 poperror();
487                 return -1;
488         }
489         validname(old_path, true);
490         c = namec(new_path, Acreate, O_EXCL,
491                   DMSYMLINK | S_IRWXU | S_IRWXG | S_IRWXO, old_path);
492         cclose(c);
493         poperror();
494         return 0;
495 }
496
497 int sysmount(int fd, int afd, char *old, int flags, char *spec)
498 {
499         ERRSTACK(1);
500         long r;
501         volatile struct {
502                 struct chan *c;
503         } c0;
504         volatile struct {
505                 struct chan *c;
506         } bc;
507         volatile struct {
508                 struct chan *c;
509         } ac;
510         struct mntparam mntparam;
511
512         ac.c = NULL;
513         bc.c = NULL;
514         c0.c = NULL;
515         if (waserror()) {
516                 cclose(ac.c);
517                 cclose(bc.c);
518                 cclose(c0.c);
519                 poperror();
520                 return -1;
521         }
522         bc.c = fdtochan(&current->open_files, fd, O_RDWR, 0, 1);
523         if (afd >= 0)
524                 ac.c = fdtochan(&current->open_files, afd, O_RDWR, 0, 1);
525         mntparam.chan = bc.c;
526         mntparam.authchan = ac.c;
527         mntparam.spec = spec;
528         c0.c = devtab[devno("mnt", 0)].attach((char *)&mntparam);
529         if (flags & MCACHE)
530                 c0.c = devtab[devno("gtfs", 0)].attach((char*)c0.c);
531         r = bindmount(c0.c, old, flags, spec);
532         poperror();
533         cclose(ac.c);
534         cclose(bc.c);
535         cclose(c0.c);
536
537         return r;
538 }
539
540 int sysunmount(char *src_path, char *onto_path)
541 {
542         ERRSTACK(1);
543         volatile struct {
544                 struct chan *c;
545         } cmount;
546         volatile struct {
547                 struct chan *c;
548         } cmounted;
549
550         cmount.c = NULL;
551         cmounted.c = NULL;
552         if (waserror()) {
553                 cclose(cmount.c);
554                 cclose(cmounted.c);
555                 poperror();
556                 return -1;
557         }
558
559         cmount.c = namec(onto_path, Amount, 0, 0, NULL);
560         if (src_path != NULL && src_path[0] != '\0') {
561                 /*
562                  * This has to be namec(..., Aopen, ...) because
563                  * if arg[0] is something like /srv/cs or /fd/0,
564                  * opening it is the only way to get at the real
565                  * Chan underneath.
566                  */
567                 cmounted.c = namec(src_path, Aopen, O_READ, 0, NULL);
568         }
569
570         cunmount(cmount.c, cmounted.c);
571         poperror();
572         cclose(cmount.c);
573         cclose(cmounted.c);
574         return 0;
575 }
576
577 int sysopenat(int fromfd, char *path, int vfs_flags)
578 {
579         ERRSTACK(1);
580         int fd;
581         struct chan *c = 0, *from = 0;
582
583         if (waserror()) {
584                 cclose(c);
585                 poperror();
586                 return -1;
587         }
588         openmode(vfs_flags);    /* error check only */
589         if ((path[0] == '/') || (fromfd == AT_FDCWD)) {
590                 c = namec(path, Aopen, vfs_flags, 0, NULL);
591         } else {
592                 /* We don't cclose from.  namec_from will convert it to the new chan
593                  * during the walk process (c).  It'll probably close from internally,
594                  * and give us something new for c.  On error, namec_from will cclose
595                  * from. */
596                 from = fdtochan(&current->open_files, fromfd, -1, FALSE, TRUE);
597                 if (!(from->flag & O_PATH))
598                         error(EINVAL, "Cannot openat from a non-O_PATH FD");
599                 c = namec_from(from, path, Aopen, vfs_flags, 0, NULL);
600         }
601         /* Devices should catch this, but just in case, we'll catch it. */
602         if ((c->qid.type & QTSYMLINK) && (vfs_flags & O_NOFOLLOW))
603                 error(ELOOP, "no-follow open of a symlink");
604         fd = newfd(c, 0, vfs_flags, FALSE);
605         if (fd < 0)
606                 error(-fd, ERROR_FIXME);
607         poperror();
608         return fd;
609 }
610
611 int sysopen(char *path, int vfs_flags)
612 {
613         return sysopenat(AT_FDCWD, path, vfs_flags);
614 }
615
616 long unionread(struct chan *c, void *va, long n)
617 {
618         ERRSTACK(1);
619         int i;
620         long nr;
621         struct mhead *m;
622         struct mount *mount;
623
624         qlock(&c->umqlock);
625         m = c->umh;
626         rlock(&m->lock);
627         mount = m->mount;
628         /* bring mount in sync with c->uri and c->umc */
629         for (i = 0; mount != NULL && i < c->uri; i++)
630                 mount = mount->next;
631
632         nr = 0;
633         while (mount != NULL) {
634                 /* Error causes component of union to be skipped */
635                 if (mount->to) {
636                         /* normally we want to discard the error, but for our ghetto kdirent
637                          * hack, we need to repeat unionread if we saw a ENODATA */
638                         if (waserror()) {
639                                 if (get_errno() == ENODATA) {
640                                         runlock(&m->lock);
641                                         qunlock(&c->umqlock);
642                                         nexterror();
643                                 }
644                                 /* poperror done below for either branch */
645                         } else {
646                                 if (c->umc == NULL) {
647                                         c->umc = cclone(mount->to);
648                                         c->umc = devtab[c->umc->type].open(c->umc,
649                                                                            O_READ);
650                                 }
651
652                                 nr = devtab[c->umc->type].read(c->umc, va, n, c->umc->offset);
653                                 if (nr < 0)
654                                         nr = 0; /* dev.c can return -1 */
655                                 c->umc->offset += nr;
656                         }
657                         poperror();     /* pop regardless */
658                 }
659                 if (nr > 0)
660                         break;
661
662                 /* Advance to next element */
663                 c->uri++;
664                 if (c->umc) {
665                         cclose(c->umc);
666                         c->umc = NULL;
667                 }
668                 mount = mount->next;
669         }
670         runlock(&m->lock);
671         qunlock(&c->umqlock);
672         return nr;
673 }
674
675 static void unionrewind(struct chan *c)
676 {
677         qlock(&c->umqlock);
678         c->uri = 0;
679         if (c->umc) {
680                 cclose(c->umc);
681                 c->umc = NULL;
682         }
683         qunlock(&c->umqlock);
684 }
685
686 static long rread(int fd, void *va, long n, int64_t * offp)
687 {
688         ERRSTACK(3);
689         int dir;
690         struct chan *c;
691         int64_t off;
692
693         /* dirty dirent hack */
694         void *real_va = va;
695
696         if (waserror()) {
697                 poperror();
698                 return -1;
699         }
700
701         c = fdtochan(&current->open_files, fd, O_READ, 1, 1);
702         if (waserror()) {
703                 cclose(c);
704                 nexterror();
705         }
706
707         if (n < 0)
708                 error(EINVAL, ERROR_FIXME);
709
710         dir = c->qid.type & QTDIR;
711
712         /* kdirent hack: userspace is expecting kdirents, but all of 9ns
713          * produces Ms.  Just save up what we don't use and append the
714          * new stuff later. Allocate DIRREADSIZE bytes for that purpose.
715          */
716         if (dir) {
717                 int amt;
718                 /* expecting only one dirent at a time, o/w we're busted */
719                 assert(n >= sizeof(struct kdirent));
720                 if (!c->buf) {
721                         c->buf = kmalloc(DIRREADSIZE, MEM_WAIT);
722                         c->bufused = 0;
723                 }
724                 /* Attempt to extract an M, in case there was some already */
725                 amt = convM2kdirent(c->buf, c->bufused, real_va, 0);
726                 if (amt) {
727                         c->bufused -= amt;
728                         memmove(c->buf, c->buf + amt, c->bufused);
729                         n = sizeof(struct kdirent);
730                         goto out;
731                 }
732                 /* debugging */
733                 if (waserror()) {
734                         printk("Well, sysread of a dir sucks.%s \n", current_errstr());
735                         nexterror();
736                 }
737                 va = c->buf + c->bufused;
738                 n = DIRREADSIZE - c->bufused;
739         }
740
741         /* this is the normal plan9 read */
742         if (dir && c->umh)
743                 n = unionread(c, va, n);
744         else {
745                 if (offp == NULL) {
746                         spin_lock(&c->lock);    /* lock for int64_t assignment */
747                         off = c->offset;
748                         spin_unlock(&c->lock);
749                 } else
750                         off = *offp;
751                 if (off < 0)
752                         error(EINVAL, ERROR_FIXME);
753                 if (off == 0) {
754                         if (offp == NULL) {
755                                 spin_lock(&c->lock);
756                                 c->offset = 0;
757                                 c->dri = 0;
758                                 spin_unlock(&c->lock);
759                         }
760                         unionrewind(c);
761                 }
762                 if (! c->ateof) {
763                         n = devtab[c->type].read(c, va, n, off);
764                         if (n == 0 && dir)
765                                 c->ateof = 1;
766                 } else {
767                         n = 0;
768                 }
769                 spin_lock(&c->lock);
770                 c->offset += n;
771                 spin_unlock(&c->lock);
772         }
773
774         /* dirty kdirent hack */
775         if (dir) {
776                 int amt;
777                 c->bufused = c->bufused + n;
778                 /* extract an M from the front, then shift the remainder back */
779                 amt = convM2kdirent(c->buf, c->bufused, real_va, 0);
780                 c->bufused -= amt;
781                 memmove(c->buf, c->buf + amt, c->bufused);
782                 n = amt ? sizeof(struct kdirent) : 0;
783                 poperror();     /* matching our debugging waserror */
784         }
785
786 out:
787         poperror();
788         cclose(c);
789
790         poperror();
791         return n;
792 }
793
794 /* Reads exactly n bytes from chan c, starting at its offset.  Can block, but if
795  * we get 0 back too soon (EOF or error), then we'll error out with ENODATA.
796  * That might need a little work - if there was a previous error, then we
797  * clobbered it and only know ENODATA but not why we completed early. */
798 void read_exactly_n(struct chan *c, void *vp, long n)
799 {
800         char *p;
801         long nn;
802         int total = 0, want = n;
803
804         p = vp;
805         while (n > 0) {
806                 nn = devtab[c->type].read(c, p, n, c->offset);
807                 printd("readn: Got %d@%lld\n", nn, c->offset);
808                 if (nn == 0)
809                         error(ENODATA, "wanted %d, got %d", want, total);
810                 spin_lock(&c->lock);
811                 c->offset += nn;
812                 spin_unlock(&c->lock);
813                 p += nn;
814                 n -= nn;
815                 total += nn;
816         }
817 }
818
819 long sysread(int fd, void *va, long n)
820 {
821         return rread(fd, va, n, NULL);
822 }
823
824 long syspread(int fd, void *va, long n, int64_t off)
825 {
826         return rread(fd, va, n, &off);
827 }
828
829 int sysremove(char *path)
830 {
831         ERRSTACK(2);
832         struct chan *c;
833
834         if (waserror()) {
835                 poperror();
836                 return -1;
837         }
838
839         c = namec(path, Aremove, 0, 0, NULL);
840         if (waserror()) {
841                 c->type = -1;   /* see below */
842                 cclose(c);
843                 nexterror();
844         }
845         devtab[c->type].remove(c);
846         /*
847          * Remove clunks the fid, but we need to recover the Chan
848          * so fake it up.  -1 aborts the dev's close.
849          */
850         c->type = -1;
851         poperror();
852         cclose(c);
853
854         poperror();
855         return 0;
856 }
857
858 int sysrename(char *from_path, char *to_path)
859 {
860         ERRSTACK(1);
861         struct chan *volatile renamee = NULL;
862         struct chan *parent_chan;
863
864         if (waserror()) {
865                 cclose(renamee);
866                 poperror();
867                 return -1;
868         }
869         renamee = namec(from_path, Aremove, 0, 0, NULL);
870         /* We might need to support wstat for 'short' rename (intra-directory, with
871          * no slashes).  Til then, we can just go with EXDEV. */
872         if (!devtab[renamee->type].rename)
873                 error(EXDEV, "device does not support rename");
874         parent_chan = namec(to_path, Arename, 0, 0, (char*)renamee);
875         /* When we're done, renamee still points to the file, but it's in the new
876          * location.  Its cname is still the old location, similar to remove.  If
877          * anyone cares, we can change it.  parent_chan still points to the parent -
878          * it didn't get moved like create does.  Though it does have the name of
879          * the new location.  If we want, we can hand that to renamee.  It's a moot
880          * point, since they are both getting closed. */
881         cclose(renamee);
882         cclose(parent_chan);
883         poperror();
884         return 0;
885 }
886
887 int64_t sysseek(int fd, int64_t off, int whence)
888 {
889         ERRSTACK(2);
890         struct dir *dir;
891         struct chan *c;
892
893         if (waserror()) {
894                 poperror();
895                 return -1;
896         }
897
898         c = fdtochan(&current->open_files, fd, -1, 1, 1);
899         if (waserror()) {
900                 cclose(c);
901                 nexterror();
902         }
903         switch (whence) {
904                 case 0:
905                         if (c->qid.type & QTDIR) {
906                                 if (off != 0)
907                                         error(EISDIR, ERROR_FIXME);
908                                 unionrewind(c);
909                         } else if (off < 0)
910                                 error(EINVAL, ERROR_FIXME);
911                         spin_lock(&c->lock);    /* lock for int64_t assignment */
912                         c->offset = off;
913                         spin_unlock(&c->lock);
914                         break;
915
916                 case 1:
917                         if (c->qid.type & QTDIR)
918                                 error(EISDIR, ERROR_FIXME);
919                         spin_lock(&c->lock);    /* lock for read/write update */
920                         off += c->offset;
921                         if (off < 0) {
922                                 spin_unlock(&c->lock);
923                                 error(EINVAL, ERROR_FIXME);
924                         }
925                         c->offset = off;
926                         spin_unlock(&c->lock);
927                         break;
928
929                 case 2:
930                         if (c->qid.type & QTDIR)
931                                 error(EISDIR, ERROR_FIXME);
932                         dir = chandirstat(c);
933                         if (dir == NULL)
934                                 error(EFAIL, "internal error: stat error in seek");
935                         off += dir->length;
936                         kfree(dir);
937                         if (off < 0)
938                                 error(EINVAL, ERROR_FIXME);
939                         spin_lock(&c->lock);    /* lock for read/write update */
940                         c->offset = off;
941                         spin_unlock(&c->lock);
942                         break;
943
944                 default:
945                         error(EINVAL, ERROR_FIXME);
946                         break;
947         }
948         poperror();
949         c->dri = 0;
950         cclose(c);
951         poperror();
952         return off;
953 }
954
955 void validstat(uint8_t * s, int n, int slashok)
956 {
957
958         int m;
959         char buf[64];
960
961         if (statcheck(s, n) < 0)
962                 error(EINVAL, ERROR_FIXME);
963         /* verify that name entry is acceptable */
964         s += STAT_FIX_LEN_9P - STAT_NR_STRINGS_9P * BIT16SZ;
965         /*
966          * s now points at count for first string.
967          * if it's too long, let the server decide; this is
968          * only for his protection anyway. otherwise
969          * we'd have to allocate and waserror.
970          */
971         m = GBIT16(s);
972         s += BIT16SZ;
973         if (m + 1 > sizeof buf) {
974                 return;
975         }
976         memmove(buf, s, m);
977         buf[m] = '\0';
978         /* name could be '/' */
979         if (strcmp(buf, "/") != 0)
980                 validname(buf, slashok);
981 }
982
983 int sysfstat(int fd, uint8_t *buf, int n)
984 {
985         ERRSTACK(2);
986         struct chan *c;
987
988         if (waserror()) {
989                 poperror();
990                 return -1;
991         }
992
993         c = fdtochan(&current->open_files, fd, -1, 0, 1);
994         if (waserror()) {
995                 cclose(c);
996                 nexterror();
997         }
998         devtab[c->type].stat(c, buf, n);
999
1000         poperror();
1001         cclose(c);
1002
1003         poperror();
1004         return n;
1005 }
1006
1007 int sysfstatakaros(int fd, struct kstat *ks)
1008 {
1009
1010         int n = 4096;
1011         uint8_t *buf;
1012         buf = kmalloc(n, MEM_WAIT);
1013         n = sysfstat(fd, buf, n);
1014         if (n > 0) {
1015                 convM2kstat(buf, n, ks);
1016                 n = 0;
1017         }
1018         kfree(buf);
1019         return n;
1020 }
1021
1022 static int __stat(char *path, uint8_t *buf, int n, int flags)
1023 {
1024         ERRSTACK(2);
1025         struct chan *c;
1026
1027         if (waserror()) {
1028                 poperror();
1029                 return -1;
1030         }
1031
1032         c = namec(path, Aaccess, flags, 0, NULL);
1033         if (waserror()) {
1034                 cclose(c);
1035                 nexterror();
1036         }
1037         devtab[c->type].stat(c, buf, n);
1038         poperror();
1039         cclose(c);
1040
1041         poperror();
1042
1043         return n;
1044 }
1045
1046 int sysstat(char *path, uint8_t *buf, int n)
1047 {
1048         return __stat(path, buf, n, 0);
1049 }
1050
1051 int syslstat(char *path, uint8_t *buf, int n)
1052 {
1053         return __stat(path, buf, n, O_NOFOLLOW);
1054 }
1055
1056 int sysstatakaros(char *path, struct kstat *ks, int flags)
1057 {
1058
1059         int n = 4096;
1060         uint8_t *buf;
1061         buf = kmalloc(n, MEM_WAIT);
1062         n = __stat(path, buf, n, flags);
1063         if (n > 0) {
1064                 convM2kstat(buf, n, ks);
1065                 n = 0;
1066         }
1067         kfree(buf);
1068         return n;
1069 }
1070
1071 static long rwrite(int fd, void *va, long n, int64_t * offp)
1072 {
1073         ERRSTACK(3);
1074         struct chan *c;
1075         struct dir *dir;
1076         int64_t off;
1077         long m;
1078
1079         if (waserror()) {
1080                 poperror();
1081                 return -1;
1082         }
1083         c = fdtochan(&current->open_files, fd, O_WRITE, 1, 1);
1084         if (waserror()) {
1085                 cclose(c);
1086                 nexterror();
1087         }
1088         if (c->qid.type & QTDIR)
1089                 error(EISDIR, ERROR_FIXME);
1090
1091         if (n < 0)
1092                 error(EINVAL, ERROR_FIXME);
1093
1094         if (offp == NULL) {
1095                 /* append changes the offset to the end, and even if we fail later, this
1096                  * change will persist */
1097                 if (c->flag & O_APPEND) {
1098                         dir = chandirstat(c);
1099                         if (!dir)
1100                                 error(EFAIL, "internal error: stat error in append write");
1101                         spin_lock(&c->lock);    /* legacy lock for int64 assignment */
1102                         c->offset = dir->length;
1103                         spin_unlock(&c->lock);
1104                         kfree(dir);
1105                 }
1106                 spin_lock(&c->lock);
1107                 off = c->offset;
1108                 c->offset += n;
1109                 spin_unlock(&c->lock);
1110         } else
1111                 off = *offp;
1112
1113         if (waserror()) {
1114                 if (offp == NULL) {
1115                         spin_lock(&c->lock);
1116                         c->offset -= n;
1117                         spin_unlock(&c->lock);
1118                 }
1119                 nexterror();
1120         }
1121         if (off < 0)
1122                 error(EINVAL, ERROR_FIXME);
1123         m = devtab[c->type].write(c, va, n, off);
1124         poperror();
1125
1126         if (offp == NULL && m < n) {
1127                 spin_lock(&c->lock);
1128                 c->offset -= n - m;
1129                 spin_unlock(&c->lock);
1130         }
1131
1132         poperror();
1133         cclose(c);
1134
1135         poperror();
1136         return m;
1137 }
1138
1139 long syswrite(int fd, void *va, long n)
1140 {
1141         return rwrite(fd, va, n, NULL);
1142 }
1143
1144 long syspwrite(int fd, void *va, long n, int64_t off)
1145 {
1146         return rwrite(fd, va, n, &off);
1147 }
1148
1149 int syswstat(char *path, uint8_t * buf, int n)
1150 {
1151         ERRSTACK(2);
1152         struct chan *c;
1153
1154         if (waserror()) {
1155                 poperror();
1156                 return -1;
1157         }
1158
1159         validstat(buf, n, 0);
1160         c = namec(path, Aaccess, 0, 0, NULL);
1161         if (waserror()) {
1162                 cclose(c);
1163                 nexterror();
1164         }
1165         n = devtab[c->type].wstat(c, buf, n);
1166         poperror();
1167         cclose(c);
1168
1169         poperror();
1170         return n;
1171 }
1172
1173 struct dir *chandirstat(struct chan *c)
1174 {
1175         ERRSTACK(1);
1176         struct dir *d;
1177         uint8_t *buf;
1178         int n, nd, i;
1179
1180         nd = DIRSIZE;
1181         for (i = 0; i < 2; i++) {       /* should work by the second try */
1182                 d = kzmalloc(sizeof(struct dir) + nd, MEM_WAIT);
1183                 buf = (uint8_t *) & d[1];
1184                 if (waserror()) {
1185                         kfree(d);
1186                         poperror();
1187                         return NULL;
1188                 }
1189                 n = devtab[c->type].stat(c, buf, nd);
1190                 poperror();
1191                 if (n < BIT16SZ) {
1192                         kfree(d);
1193                         return NULL;
1194                 }
1195                 nd = GBIT16((uint8_t *) buf) + BIT16SZ; /* size needed to store whole stat buffer including count */
1196                 if (nd <= n) {
1197                         convM2D(buf, n, d, (char *)&d[1]);
1198                         return d;
1199                 }
1200                 /* else sizeof(Dir)+nd is plenty */
1201                 kfree(d);
1202         }
1203         return NULL;
1204
1205 }
1206
1207 static struct dir *__dir_stat(char *name, int flags)
1208 {
1209         ERRSTACK(2);
1210         struct chan *c;
1211         struct dir *d;
1212
1213         if (waserror()) {
1214                 poperror();
1215                 return NULL;
1216         }
1217
1218         c = namec(name, Aaccess, flags, 0, NULL);
1219         if (waserror()) {
1220                 cclose(c);
1221                 nexterror();
1222         }
1223         d = chandirstat(c);
1224         poperror();
1225         cclose(c);
1226
1227         poperror();
1228         return d;
1229 }
1230
1231 struct dir *sysdirstat(char *name)
1232 {
1233         return __dir_stat(name, 0);
1234 }
1235
1236 struct dir *sysdirlstat(char *name)
1237 {
1238         return __dir_stat(name, O_NOFOLLOW);
1239 }
1240
1241 struct dir *sysdirfstat(int fd)
1242 {
1243         ERRSTACK(2);
1244         struct chan *c;
1245         struct dir *d;
1246
1247         if (waserror()) {
1248                 poperror();
1249                 return NULL;
1250         }
1251
1252         c = fdtochan(&current->open_files, fd, -1, 0, 1);
1253         if (waserror()) {
1254                 cclose(c);
1255                 nexterror();
1256         }
1257         d = chandirstat(c);
1258         poperror();
1259         cclose(c);
1260
1261         poperror();
1262         return d;
1263 }
1264
1265 int sysdirwstat(char *name, struct dir *dir)
1266 {
1267
1268         uint8_t *buf;
1269         int r;
1270
1271         r = sizeD2M(dir);
1272         buf = kzmalloc(r, MEM_WAIT);
1273         convD2M(dir, buf, r);
1274         r = syswstat(name, buf, r);
1275         kfree(buf);
1276         return r < 0 ? r : 0;
1277 }
1278
1279 int sysdirfwstat(int fd, struct dir *dir)
1280 {
1281
1282         uint8_t *buf;
1283         int r;
1284
1285         r = sizeD2M(dir);
1286         buf = kzmalloc(r, MEM_WAIT);
1287         convD2M(dir, buf, r);
1288         r = sysfwstat(fd, buf, r);
1289         kfree(buf);
1290         return r < 0 ? r : 0;
1291 }
1292
1293 static long dirpackage(uint8_t * buf, long ts, struct kdirent **d)
1294 {
1295
1296         char *s;
1297         long ss, i, n, nn, m = 0;
1298
1299         *d = NULL;
1300         if (ts <= 0) {
1301                 return ts;
1302         }
1303
1304         /*
1305          * first find number of all stats, check they look like stats, & size all associated strings
1306          */
1307         ss = 0;
1308         n = 0;
1309         for (i = 0; i < ts; i += m) {
1310                 m = BIT16SZ + GBIT16(&buf[i]);
1311                 if (statcheck(&buf[i], m) < 0)
1312                         break;
1313                 ss += m;
1314                 n++;
1315         }
1316
1317         if (i != ts)
1318                 error(EFAIL, "bad directory format");
1319
1320         *d = kzmalloc(n * sizeof(**d) + ss, 0);
1321         if (*d == NULL)
1322                 error(ENOMEM, ERROR_FIXME);
1323
1324         /*
1325          * then convert all buffers
1326          */
1327         s = (char *)*d + n * sizeof(**d);
1328         nn = 0;
1329         for (i = 0; i < ts; i += m) {
1330                 m = BIT16SZ + GBIT16((uint8_t *) & buf[i]);
1331                 /* Note 's' is ignored by convM2kdirent */
1332                 if (nn >= n || /*convM2D */ convM2kdirent(&buf[i], m, *d + nn, s) != m) {
1333                         kfree(*d);
1334                         *d = NULL;
1335                         error(EFAIL, "bad directory entry");
1336                 }
1337                 nn++;
1338                 s += m;
1339         }
1340
1341         return nn;
1342 }
1343
1344 long sysdirread(int fd, struct kdirent **d)
1345 {
1346         ERRSTACK(2);
1347         uint8_t *buf;
1348         long ts;
1349
1350         *d = NULL;
1351         if (waserror()) {
1352                 poperror();
1353                 return -1;
1354         }
1355         buf = kzmalloc(DIRREADLIM, 0);
1356         if (buf == NULL)
1357                 error(ENOMEM, ERROR_FIXME);
1358         if (waserror()) {
1359                 kfree(buf);
1360                 nexterror();
1361         }
1362         ts = sysread(fd, buf, DIRREADLIM);
1363         if (ts >= 0)
1364                 ts = dirpackage(buf, ts, d);
1365         poperror();
1366         kfree(buf);
1367         poperror();
1368         return ts;
1369 }
1370
1371 int sysiounit(int fd)
1372 {
1373         ERRSTACK(1);
1374         struct chan *c;
1375         int n;
1376
1377         c = fdtochan(&current->open_files, fd, -1, 0, 1);
1378         if (waserror()) {
1379                 cclose(c);
1380                 poperror();
1381                 return 0;       /* n.b. */
1382         }
1383         n = c->iounit;
1384         poperror();
1385         cclose(c);
1386         return n;
1387 }
1388
1389 void print_chaninfo(struct chan *c)
1390 {
1391
1392         char buf[128] = { 0 };
1393         bool has_dev = c->type != -1;
1394         bool has_chaninfo = has_dev && devtab[c->type].chaninfo;
1395
1396         print_lock();
1397         printk("Chan flags: %p, pathname: %s, ref: %d, Dev: %s, Devinfo: %s",
1398                    c->flag,
1399                    c->name ? c->name->s : "no cname",
1400                    kref_refcnt(&c->ref),
1401                    has_dev ? devtab[c->type].name : "no dev",
1402                    has_chaninfo ? devtab[c->type].chaninfo(c, buf, sizeof(buf)) : "");
1403         if (!has_chaninfo)
1404                 printk("qid.path: %p\n", c->qid.path);
1405         printk("\n");
1406         print_unlock();
1407 }
1408
1409 /* TODO: 9ns ns inheritance flags: Shared, copied, or empty.  The old fgrp is
1410  * managed by the fd_table, which is handled outside this function.  We share
1411  * the pgrp. */
1412 int plan9setup(struct proc *new_proc, struct proc *parent, int flags)
1413 {
1414
1415         struct chan *new_dot;
1416
1417         ERRSTACK(1);
1418         if (waserror()) {
1419                 printk("plan9setup failed, %s\n", current_errstr());
1420                 poperror();
1421                 return -1;
1422         }
1423         if (!parent) {
1424                 /* We are probably spawned by the kernel directly, and have no parent to
1425                  * inherit from. */
1426                 new_proc->pgrp = newpgrp();
1427                 new_proc->slash = namec("#kfs", Atodir, 0, 0, NULL);
1428                 if (!new_proc->slash)
1429                         panic("no kfs device");
1430                 /* Want the name to be "/" instead of "#kfs" */
1431                 cnameclose(new_proc->slash->name);
1432                 new_proc->slash->name = newcname("/");
1433                 new_proc->dot = cclone(new_proc->slash);
1434                 poperror();
1435                 return 0;
1436         }
1437         /* Shared semantics */
1438         kref_get(&parent->pgrp->ref, 1);
1439         new_proc->pgrp = parent->pgrp;
1440         /* copy semantics on / and . (doesn't make a lot of sense in akaros o/w) */
1441         /* / should never disappear while we hold a ref to parent */
1442         chan_incref(parent->slash);
1443         new_proc->slash = parent->slash;
1444
1445         rcu_read_lock();
1446         new_dot = rcu_dereference(parent->dot);
1447         kref_get(&new_dot->ref, 1);
1448         rcu_read_unlock();
1449         new_proc->dot = new_dot;
1450
1451         poperror();
1452         return 0;
1453 }
1454
1455 /* Open flags, create modes, access types, file flags, and all that...
1456  *
1457  * there are a bunch of things here:
1458  *              1) file creation flags (e.g. O_TRUNC)
1459  *              2) file status flags (e.g. O_APPEND)
1460  *              3) file open modes (e.g. O_RDWR)
1461  *              4) file descriptor flags (e.g. CLOEXEC)
1462  *              5) file creation mode (e.g. S_IRWXU)
1463  * the 1-4 are passed in via open's vfs_flags, and the 5 via mode only when
1464  * O_CREATE is set.
1465  *
1466  * file creation flags (1) only matter when creating, but aren't permanent.
1467  * O_EXCL, O_DIRECTORY, O_TRUNC, etc.
1468  *
1469  * file status flags (2) are per struct file/chan.  stuff like O_APPEND,
1470  * O_ASYNC, etc.  we convert those to an internal flag bit and store in c->flags
1471  *
1472  * the open mode (3) matters for a given FD/chan (chan->mode), and should be
1473  * stored in the chan. (c->mode) stuff like O_RDONLY.
1474  *
1475  * the file descriptor flags (4) clearly are in the FD.  note that the same
1476  * file/chan can be opened by two different FDs, with different flags.  the only
1477  * one anyone uses is CLOEXEC.  while exec may not last long in akaros, i can
1478  * imagine similar "never pass to children" flags/meanings.
1479  *
1480  * the file creation mode (5) matters for the device's permissions; given this,
1481  * it should be stored in the device/inode.  ACLs fall under this category.
1482  *
1483  * finally, only certain categories can be edited afterwards: file status flags
1484  * (2), FD flags (4), and file permissions (5). */
1485 int fd_getfl(int fd)
1486 {
1487         ERRSTACK(1);
1488         struct chan *c;
1489         int ret;
1490
1491         if (waserror()) {
1492                 poperror();
1493                 return -1;
1494         }
1495         c = fdtochan(&current->open_files, fd, -1, 0, 1);
1496
1497         ret = c->mode;
1498         ret |= c->flag & CEXTERNAL_FLAGS;
1499
1500         cclose(c);
1501         poperror();
1502         return ret;
1503 }
1504
1505 static bool cexternal_flags_differ(int set1, int set2, int flags)
1506 {
1507         flags &= CEXTERNAL_FLAGS;
1508         return (set1 & flags) ^ (set2 & flags);
1509 }
1510
1511 int fd_setfl(int fd, int flags)
1512 {
1513         ERRSTACK(2);
1514         struct chan *c;
1515         int ret = 0;
1516
1517         if (waserror()) {
1518                 poperror();
1519                 return -1;
1520         }
1521         c = fdtochan(&current->open_files, fd, -1, 0, 1);
1522         if (waserror()) {
1523                 cclose(c);
1524                 nexterror();
1525         }
1526         if (cexternal_flags_differ(flags, c->flag, O_CLOEXEC)) {
1527                 /* TODO: The whole CCEXEC / O_CLOEXEC on 9ns needs work */
1528                 error(EINVAL, "can't toggle O_CLOEXEC with setfl");
1529         }
1530         if (cexternal_flags_differ(flags, c->flag, O_REMCLO))
1531                 error(EINVAL, "can't toggle O_REMCLO with setfl");
1532         if (cexternal_flags_differ(flags, c->flag, O_PATH))
1533                 error(EINVAL, "can't toggle O_PATH with setfl");
1534         if (!devtab[c->type].chan_ctl)
1535                 error(EINVAL, "can't setfl, %s has no chan_ctl", chan_dev_name(c));
1536         ret = devtab[c->type].chan_ctl(c, CCTL_SET_FL, flags & CEXTERNAL_FLAGS,
1537                                        0, 0, 0);
1538         c->flag = (c->flag & ~CEXTERNAL_FLAGS) | (flags & CEXTERNAL_FLAGS);
1539         poperror();
1540         cclose(c);
1541         poperror();
1542         return ret;
1543 }
1544
1545 int fd_sync(int fd)
1546 {
1547         ERRSTACK(2);
1548         struct chan *c;
1549         int ret = 0;
1550
1551         if (waserror()) {
1552                 poperror();
1553                 return -1;
1554         }
1555         c = fdtochan(&current->open_files, fd, -1, 0, 1);
1556         if (waserror()) {
1557                 cclose(c);
1558                 nexterror();
1559         }
1560         if (!devtab[c->type].chan_ctl)
1561                 error(EINVAL, "can't fsync, %s has no chan_ctl", chan_dev_name(c));
1562         ret = devtab[c->type].chan_ctl(c, CCTL_SYNC, 0, 0, 0, 0);
1563         poperror();
1564         cclose(c);
1565         poperror();
1566         return ret;
1567 }
1568
1569 ssize_t kread_file(struct file_or_chan *file, void *buf, size_t sz)
1570 {
1571         /* TODO: (KFOP) (VFS kernel read/writes need to be from a ktask) */
1572         uintptr_t old_ret = switch_to_ktask();
1573         off64_t dummy = 0;
1574         ssize_t cpy_amt = foc_read(file, buf, sz, dummy);
1575
1576         switch_back_from_ktask(old_ret);
1577         return cpy_amt;
1578 }
1579
1580 /* Reads the contents of an entire file into a buffer, returning that buffer.
1581  * On error, prints something useful and returns 0 */
1582 void *kread_whole_file(struct file_or_chan *file)
1583 {
1584         size_t size;
1585         void *contents;
1586         ssize_t cpy_amt;
1587
1588         size = foc_get_len(file);
1589         contents = kmalloc(size, MEM_WAIT);
1590         cpy_amt = kread_file(file, contents, size);
1591         if (cpy_amt < 0) {
1592                 printk("Error %d reading file %s\n", get_errno(), foc_to_name(file));
1593                 kfree(contents);
1594                 return 0;
1595         }
1596         if (cpy_amt != size) {
1597                 printk("Read %d, needed %d for file %s\n", cpy_amt, size,
1598                        foc_to_name(file));
1599                 kfree(contents);
1600                 return 0;
1601         }
1602         return contents;
1603 }
1604
1605 /* Process-related File management functions */
1606
1607 /* Given any FD, get the appropriate object, 0 o/w. Set incref if you want a
1608  * reference count (which is a 9ns thing, you can't use the pointer if you
1609  * didn't incref). */
1610 void *lookup_fd(struct fd_table *fdt, int fd, bool incref)
1611 {
1612         void *retval = 0;
1613
1614         if (fd < 0)
1615                 return 0;
1616         spin_lock(&fdt->lock);
1617         if (fdt->closed) {
1618                 spin_unlock(&fdt->lock);
1619                 return 0;
1620         }
1621         if (fd < fdt->max_fdset) {
1622                 if (GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd)) {
1623                         /* while max_files and max_fdset might not line up, we should never
1624                          * have a valid fdset higher than files */
1625                         assert(fd < fdt->max_files);
1626                         retval = fdt->fd[fd].fd_chan;
1627                         if (incref)
1628                                 chan_incref((struct chan*)retval);
1629                 }
1630         }
1631         spin_unlock(&fdt->lock);
1632         return retval;
1633 }
1634
1635 /* Grow the vfs fd set */
1636 static int grow_fd_set(struct fd_table *open_files)
1637 {
1638         int n;
1639         struct file_desc *nfd, *ofd;
1640
1641         /* Only update open_fds once. If currently pointing to open_fds_init, then
1642          * update it to point to a newly allocated fd_set with space for
1643          * NR_FILE_DESC_MAX */
1644         if (open_files->open_fds == (struct fd_set*)&open_files->open_fds_init) {
1645                 open_files->open_fds = kzmalloc(sizeof(struct fd_set), 0);
1646                 memmove(open_files->open_fds, &open_files->open_fds_init,
1647                         sizeof(struct small_fd_set));
1648         }
1649
1650         /* Grow the open_files->fd array in increments of NR_OPEN_FILES_DEFAULT */
1651         n = open_files->max_files + NR_OPEN_FILES_DEFAULT;
1652         if (n > NR_FILE_DESC_MAX)
1653                 return -EMFILE;
1654         nfd = kzmalloc(n * sizeof(struct file_desc), 0);
1655         if (nfd == NULL)
1656                 return -ENOMEM;
1657
1658         /* Move the old array on top of the new one */
1659         ofd = open_files->fd;
1660         memmove(nfd, ofd, open_files->max_files * sizeof(struct file_desc));
1661
1662         /* Update the array and the maxes for both max_files and max_fdset */
1663         open_files->fd = nfd;
1664         open_files->max_files = n;
1665         open_files->max_fdset = n;
1666
1667         /* Only free the old one if it wasn't pointing to open_files->fd_array */
1668         if (ofd != open_files->fd_array)
1669                 kfree(ofd);
1670         return 0;
1671 }
1672
1673 /* Free the vfs fd set if necessary */
1674 static void free_fd_set(struct fd_table *open_files)
1675 {
1676         void *free_me;
1677
1678         if (open_files->open_fds != (struct fd_set*)&open_files->open_fds_init) {
1679                 assert(open_files->fd != open_files->fd_array);
1680                 /* need to reset the pointers to the internal addrs, in case we take a
1681                  * look while debugging.  0 them out, since they have old data.  our
1682                  * current versions should all be closed. */
1683                 memset(&open_files->open_fds_init, 0, sizeof(struct small_fd_set));
1684                 memset(&open_files->fd_array, 0, sizeof(open_files->fd_array));
1685
1686                 free_me = open_files->open_fds;
1687                 open_files->open_fds = (struct fd_set*)&open_files->open_fds_init;
1688                 kfree(free_me);
1689
1690                 free_me = open_files->fd;
1691                 open_files->fd = open_files->fd_array;
1692                 kfree(free_me);
1693         }
1694 }
1695
1696 /* If FD is in the group, remove it, decref it, and return TRUE. */
1697 bool close_fd(struct fd_table *fdt, int fd)
1698 {
1699         struct chan *chan = 0;
1700         struct fd_tap *tap = 0;
1701         bool ret = FALSE;
1702
1703         if (fd < 0)
1704                 return FALSE;
1705         spin_lock(&fdt->lock);
1706         if (fd < fdt->max_fdset) {
1707                 if (GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd)) {
1708                         /* while max_files and max_fdset might not line up, we should never
1709                          * have a valid fdset higher than files */
1710                         assert(fd < fdt->max_files);
1711                         chan = fdt->fd[fd].fd_chan;
1712                         tap = fdt->fd[fd].fd_tap;
1713                         fdt->fd[fd].fd_chan = 0;
1714                         fdt->fd[fd].fd_tap = 0;
1715                         CLR_BITMASK_BIT(fdt->open_fds->fds_bits, fd);
1716                         if (fd < fdt->hint_min_fd)
1717                                 fdt->hint_min_fd = fd;
1718                         ret = TRUE;
1719                 }
1720         }
1721         spin_unlock(&fdt->lock);
1722         /* Need to decref/cclose outside of the lock; they could sleep */
1723         cclose(chan);
1724         if (tap)
1725                 kref_put(&tap->kref);
1726         return ret;
1727 }
1728
1729 static int __get_fd(struct fd_table *open_files, int low_fd, bool must_use_low)
1730 {
1731         int slot = -1;
1732         int error;
1733         bool update_hint = TRUE;
1734
1735         if ((low_fd < 0) || (low_fd > NR_FILE_DESC_MAX))
1736                 return -EINVAL;
1737         if (open_files->closed)
1738                 return -EINVAL; /* won't matter, they are dying */
1739         if (must_use_low && GET_BITMASK_BIT(open_files->open_fds->fds_bits, low_fd))
1740                 return -ENFILE;
1741         if (low_fd > open_files->hint_min_fd)
1742                 update_hint = FALSE;
1743         else
1744                 low_fd = open_files->hint_min_fd;
1745         /* Loop until we have a valid slot (we grow the fd_array at the bottom of
1746          * the loop if we haven't found a slot in the current array */
1747         while (slot == -1) {
1748                 for (low_fd; low_fd < open_files->max_fdset; low_fd++) {
1749                         if (GET_BITMASK_BIT(open_files->open_fds->fds_bits, low_fd))
1750                                 continue;
1751                         slot = low_fd;
1752                         SET_BITMASK_BIT(open_files->open_fds->fds_bits, slot);
1753                         assert(slot < open_files->max_files &&
1754                                open_files->fd[slot].fd_chan == 0);
1755                         /* We know slot >= hint, since we started with the hint */
1756                         if (update_hint)
1757                                 open_files->hint_min_fd = slot + 1;
1758                         break;
1759                 }
1760                 if (slot == -1) {
1761                         if ((error = grow_fd_set(open_files)))
1762                                 return error;
1763                 }
1764         }
1765         return slot;
1766 }
1767
1768 /* Insert a file or chan (obj, chosen by vfs) into the fd group with fd_flags.
1769  * If must_use_low, then we have to insert at FD = low_fd.  o/w we start looking
1770  * for empty slots at low_fd. */
1771 int insert_obj_fdt(struct fd_table *fdt, void *obj, int low_fd, int fd_flags,
1772                    bool must_use_low)
1773 {
1774         int slot;
1775
1776         spin_lock(&fdt->lock);
1777         slot = __get_fd(fdt, low_fd, must_use_low);
1778         if (slot < 0) {
1779                 spin_unlock(&fdt->lock);
1780                 return slot;
1781         }
1782         assert(slot < fdt->max_files &&
1783                fdt->fd[slot].fd_chan == 0);
1784         chan_incref((struct chan*)obj);
1785         fdt->fd[slot].fd_chan = obj;
1786         fdt->fd[slot].fd_flags = fd_flags;
1787         spin_unlock(&fdt->lock);
1788         return slot;
1789 }
1790
1791 /* Closes all open files.  Mostly just a "put" for all files.  If cloexec, it
1792  * will only close the FDs with FD_CLOEXEC (opened with O_CLOEXEC or fcntld).
1793  *
1794  * Notes on concurrency:
1795  * - Can't hold spinlocks while we call cclose, since it might sleep eventually.
1796  * - We're called from proc_destroy, so we could have concurrent openers trying
1797  *   to add to the group (other syscalls), hence the "closed" flag.
1798  * - dot and slash chans are dealt with in proc_free.  its difficult to close
1799  *   and zero those with concurrent syscalls, since those are a source of krefs.
1800  * - Once we lock and set closed, no further additions can happen.  To simplify
1801  *   our closes, we also allow multiple calls to this func (though that should
1802  *   never happen with the current code). */
1803 void close_fdt(struct fd_table *fdt, bool cloexec)
1804 {
1805         struct chan *chan;
1806         struct file_desc *to_close;
1807         int idx = 0;
1808
1809         to_close = kzmalloc(sizeof(struct file_desc) * fdt->max_files,
1810                             MEM_WAIT);
1811         spin_lock(&fdt->lock);
1812         if (fdt->closed) {
1813                 spin_unlock(&fdt->lock);
1814                 kfree(to_close);
1815                 return;
1816         }
1817         for (int i = 0; i < fdt->max_fdset; i++) {
1818                 if (GET_BITMASK_BIT(fdt->open_fds->fds_bits, i)) {
1819                         /* while max_files and max_fdset might not line up, we should never
1820                          * have a valid fdset higher than files */
1821                         assert(i < fdt->max_files);
1822                         if (cloexec && !(fdt->fd[i].fd_flags & FD_CLOEXEC))
1823                                 continue;
1824                         chan = fdt->fd[i].fd_chan;
1825                         to_close[idx].fd_tap = fdt->fd[i].fd_tap;
1826                         fdt->fd[i].fd_tap = 0;
1827                         fdt->fd[i].fd_chan = 0;
1828                         to_close[idx++].fd_chan = chan;
1829                         CLR_BITMASK_BIT(fdt->open_fds->fds_bits, i);
1830                 }
1831         }
1832         /* it's just a hint, we can build back up from being 0 */
1833         fdt->hint_min_fd = 0;
1834         if (!cloexec) {
1835                 free_fd_set(fdt);
1836                 fdt->closed = TRUE;
1837         }
1838         spin_unlock(&fdt->lock);
1839         /* We go through some hoops to close/decref outside the lock.  Nice for not
1840          * holding the lock for a while; critical in case the decref/cclose sleeps
1841          * (it can) */
1842         for (int i = 0; i < idx; i++) {
1843                 cclose(to_close[i].fd_chan);
1844                 if (to_close[i].fd_tap)
1845                         kref_put(&to_close[i].fd_tap->kref);
1846         }
1847         kfree(to_close);
1848 }
1849
1850 /* Inserts all of the files from src into dst, used by sys_fork(). */
1851 void clone_fdt(struct fd_table *src, struct fd_table *dst)
1852 {
1853         struct chan *chan;
1854         int ret;
1855
1856         spin_lock(&src->lock);
1857         if (src->closed) {
1858                 spin_unlock(&src->lock);
1859                 return;
1860         }
1861         spin_lock(&dst->lock);
1862         if (dst->closed) {
1863                 warn("Destination closed before it opened");
1864                 spin_unlock(&dst->lock);
1865                 spin_unlock(&src->lock);
1866                 return;
1867         }
1868         while (src->max_files > dst->max_files) {
1869                 ret = grow_fd_set(dst);
1870                 if (ret < 0) {
1871                         set_error(-ret, "Failed to grow for a clone_fdt");
1872                         spin_unlock(&dst->lock);
1873                         spin_unlock(&src->lock);
1874                         return;
1875                 }
1876         }
1877         for (int i = 0; i < src->max_fdset; i++) {
1878                 if (GET_BITMASK_BIT(src->open_fds->fds_bits, i)) {
1879                         /* while max_files and max_fdset might not line up, we should never
1880                          * have a valid fdset higher than files */
1881                         assert(i < src->max_files);
1882                         chan = src->fd[i].fd_chan;
1883                         assert(i < dst->max_files && dst->fd[i].fd_chan == 0);
1884                         SET_BITMASK_BIT(dst->open_fds->fds_bits, i);
1885                         dst->fd[i].fd_chan = chan;
1886                         chan_incref(chan);
1887                 }
1888         }
1889         dst->hint_min_fd = src->hint_min_fd;
1890         spin_unlock(&dst->lock);
1891         spin_unlock(&src->lock);
1892 }
1893
1894 int fd_get_fd_flags(struct fd_table *fdt, int fd)
1895 {
1896         int ret = -1;
1897
1898         if (fd < 0)
1899                 return -1;
1900         spin_lock(&fdt->lock);
1901         if (fdt->closed) {
1902                 spin_unlock(&fdt->lock);
1903                 return -1;
1904         }
1905         if ((fd < fdt->max_fdset) && GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd))
1906                 ret = fdt->fd[fd].fd_flags;
1907         spin_unlock(&fdt->lock);
1908         if (ret == -1)
1909                 set_error(EBADF, "FD was not open");
1910         return ret;
1911 }
1912
1913 int fd_set_fd_flags(struct fd_table *fdt, int fd, int new_fl)
1914 {
1915         int ret = -1;
1916
1917         if (fd < 0)
1918                 return -1;
1919         spin_lock(&fdt->lock);
1920         if (fdt->closed) {
1921                 spin_unlock(&fdt->lock);
1922                 return -1;
1923         }
1924         if ((fd < fdt->max_fdset) && GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd))
1925                 fdt->fd[fd].fd_flags = new_fl;
1926         spin_unlock(&fdt->lock);
1927         if (ret == -1)
1928                 set_error(EBADF, "FD was not open");
1929         return ret;
1930 }