akaros/kern/include/ns.h
<<
>>
Prefs
   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
  30#pragma once
  31
  32#include <err.h>
  33#include <rendez.h>
  34#include <rwlock.h>
  35#include <linker_func.h>
  36#include <fdtap.h>
  37#include <ros/fs.h>
  38#include <bitmask.h>
  39#include <mm.h>
  40#include <sys/uio.h>
  41#include <time.h>
  42
  43/*
  44 * functions (possibly) linked in, complete, from libc.
  45 */
  46enum {
  47        UTFmax = 4,             /* maximum bytes per rune */
  48        Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
  49        Runeself = 0x80,        /* rune and UTF sequences are the same (<) */
  50        Runeerror = 0xFFFD,     /* decoding error in UTF */
  51        Runemax = 0x10FFFF,     /* 21-bit rune */
  52        Runemask = 0x1FFFFF,    /* bits used by runes (see grep) */
  53        NUMSIZE32 = 10, /* max size of formatted 32 bit number (hex or deci) */
  54        NUMSIZE64 = 20, /* max size of formatted 64 bit number (hex or deci) */
  55};
  56
  57/*
  58 * math
  59 */
  60extern int isNaN(double);
  61extern int isInf(double, int);
  62extern double floor(double);
  63extern double frexp(double, int *);
  64extern double pow10(int);
  65
  66/*
  67 * one-of-a-kind
  68 */
  69extern char *cleanname(char *unused_char_p_t);
  70
  71extern int getfields(char *unused_char_p_t, char **unused_char_pp_t,
  72                                         int unused_int, int, char *);
  73extern int tokenize(char *unused_char_p_t, char **unused_char_pp_t, int);
  74extern int dec64(uint8_t * unused_uint8_p_t, int unused_int,
  75                                 char *unused_char_p_t, int);
  76extern void qsort(void *, long, long, int (*)(void *, void *));
  77
  78extern int toupper(int);
  79extern int myetheraddr(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
  80extern int parseether(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
  81
  82/*
  83 * network dialling
  84 */
  85#define NETPATHLEN      40
  86
  87/*
  88 * Syscall data structures
  89 */
  90#define MORDER  0x0003  /* mask for bits defining order of mounting */
  91#define MREPL   0x0000  /* mount replaces object */
  92#define MBEFORE 0x0001  /* mount goes before others in union directory */
  93#define MAFTER  0x0002  /* mount goes after others in union directory */
  94#define MCREATE 0x0004  /* permit creation in mounted directory */
  95#define MCACHE  0x0010  /* cache some data */
  96#define MMASK   0x0017  /* all bits on */
  97
  98#define NCONT   0       /* continue after note */
  99#define NDFLT   1       /* terminate after note */
 100#define NSAVE   2       /* clear note but hold state */
 101#define NRSTR   3       /* restore saved state */
 102
 103#define STATMAX 65535U  /* max length of machine-independent stat structure */
 104#define ERRMAX          128     /* max length of error string */
 105#define KNAMELEN        28      /* max length of name held in kernel */
 106
 107/* bits in Qid.type */
 108#define QTDIR           0x80    /* type bit for directories */
 109#define QTAPPEND        0x40    /* type bit for append only files */
 110#define QTEXCL          0x20    /* type bit for exclusive use files */
 111#define QTMOUNT         0x10    /* type bit for mounted channel */
 112#define QTAUTH          0x08    /* type bit for authentication file */
 113#define QTSYMLINK       0x02    /* type bit for symlinks */
 114#define QTFILE          0x00    /* plain file.  Yeah, a zero.  Fucking 9p. */
 115
 116/* bits in Dir.mode */
 117#define DMDIR           0x80000000      /* mode bit for directories */
 118#define DMAPPEND        0x40000000      /* mode bit for append only files */
 119#define DMEXCL          0x20000000      /* mode bit for exclusive use files */
 120#define DMMOUNT         0x10000000      /* mode bit for mounted channel */
 121#define DMWRITABLE      0x08000000      /* non-standard, for select() */
 122#define DMREADABLE      0x04000000      /* non-standard, for select() */
 123#define DMSYMLINK       0x02000000      /* symlink -- from 9p2000.u */
 124/* The lower parts of dir.mode are the three rwx perms (S_PMASK) */
 125#define DMMODE_BITS (DMDIR | DMAPPEND | DMEXCL | DMMOUNT | DMWRITABLE \
 126                     | DMREADABLE | DMSYMLINK)
 127
 128struct qid {
 129        uint64_t path;
 130        uint32_t vers;
 131        uint8_t type;
 132};
 133
 134static inline bool qid_is_file(struct qid q)
 135{
 136        return (q.type & (QTDIR | QTSYMLINK)) == 0;
 137}
 138
 139struct dir {
 140        /* system-modified data */
 141        uint16_t type;          /* server type */
 142        uint32_t dev;           /* server subtype */
 143        /* file data */
 144        struct qid qid;         /* unique id from server */
 145        uint32_t mode;          /* permissions */
 146        /* 9p stat has u32 atime (seconds) here */
 147        /* 9p stat has u32 mtime (seconds) here */
 148        uint64_t length;        /* file length: see <u.h> */
 149        char *name;             /* last element of path */
 150        char *uid;              /* owner name */
 151        char *gid;              /* group name */
 152        char *muid;             /* last modifier name */
 153        char *ext;              /* extensions for special files (symlinks) */
 154        uint32_t n_uid;         /* numeric owner uid */
 155        uint32_t n_gid;         /* numeric group id */
 156        uint32_t n_muid;        /* numeric last modifier id */
 157        struct timespec atime;  /* last access time */
 158        struct timespec btime;  /* file creation time */
 159        struct timespec ctime;  /* last attribute change time */
 160        struct timespec mtime;  /* last data modification time */
 161};
 162
 163struct waitmsg {
 164        int pid;                /* of loved one */
 165        uint32_t time[3];       /* of loved one and descendants */
 166        char msg[ERRMAX];       /* actually variable-size in user mode */
 167};
 168
 169#define VERSION9P       "9P2000"
 170
 171#define MAXWELEM        16
 172
 173typedef
 174        struct fcall {
 175        uint8_t type;
 176        uint32_t fid;
 177        uint16_t tag;
 178        /* union { */
 179        /* struct { */
 180        uint32_t msize;                 /* Tversion, Rversion */
 181        char *version;                  /* Tversion, Rversion */
 182        /* }; */
 183        /* struct { */
 184        uint16_t oldtag;                /* Tflush */
 185        /* }; */
 186        /* struct { */
 187        char *ename;                    /* Rerror */
 188        /* }; */
 189        /* struct { */
 190        struct qid qid;                 /* Rattach, Ropen, Rcreate */
 191        uint32_t iounit;                /* Ropen, Rcreate */
 192        /* }; */
 193        /* struct { */
 194        struct qid aqid;                /* Rauth */
 195        /* }; */
 196        /* struct { */
 197        uint32_t afid;                  /* Tauth, Tattach */
 198        char *uname;                    /* Tauth, Tattach */
 199        char *aname;                    /* Tauth, Tattach */
 200        /* }; */
 201        /* struct { */
 202        uint32_t perm;                  /* Tcreate */
 203        char *name;                     /* Tcreate */
 204        uint8_t mode;                   /* Tcreate, Topen */
 205        /* }; */
 206        /* struct { */
 207        uint32_t newfid;                /* Twalk */
 208        uint16_t nwname;                /* Twalk */
 209        char *wname[MAXWELEM];          /* Twalk */
 210        /* }; */
 211        /* struct { */
 212        uint16_t nwqid;                 /* Rwalk */
 213        struct qid wqid[MAXWELEM];      /* Rwalk */
 214        /* }; */
 215        /* struct { */
 216        int64_t offset;                 /* Tread, Twrite */
 217        uint32_t count;                 /* Tread, Twrite, Rread */
 218        char *data;                     /* Twrite, Rread */
 219        /* }; */
 220        /* struct { */
 221        uint16_t nstat;                 /* Twstat, Rstat */
 222        uint8_t *stat;                  /* Twstat, Rstat */
 223        /* }; */
 224        /* }; */
 225} fcall;
 226
 227#define GBIT8(p)  ((p)[0])
 228#define GBIT16(p) ((p)[0]|((p)[1]<<8))
 229#define GBIT32(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)))
 230#define GBIT64(p) ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
 231        ((int64_t)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
 232
 233#define PBIT8(p,v)  (p)[0]=(v)
 234#define PBIT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8
 235#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
 236#define PBIT64(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
 237                (p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
 238
 239#define BIT8SZ  1
 240#define BIT16SZ 2
 241#define BIT32SZ 4
 242#define BIT64SZ 8
 243#define QIDSZ   (BIT8SZ+BIT32SZ+BIT64SZ)
 244
 245/* The 9p STATFIXLENs include the leading 16-bit count.  The count, however,
 246 * excludes itself; total size is BIT16SZ + count.  This is the amount of fixed
 247 * length data in a stat buffer.  This does not include the strings, but it
 248 * includes the string counts (u16s)
 249 *
 250 * STAT_FIX_LEN_9P is the original 9p stat message: type to length, including
 251 * u32 atime and u32 mtime.  This is the bare minimum for a stat that we
 252 * receive.  We check in e.g. convM2D for any extra fields.
 253 *
 254 * STAT_FIX_LEN_AK is the stat message used by Akaros, which includes Eric VH's
 255 * extensions and full timespecs.  It is analogous to struct dir, including the
 256 * u32s for the legacy atime/mtime.  We always send stats of this size, e.g. in
 257 * convD2M.
 258 *
 259 * Note that the extended stat message has fixed data after the strings, but to
 260 * get to this data, you have to jump through the string and their counts
 261 * (u16s).  The counts are part of the fixed length, but not the strings.  Also
 262 * note that the _AK version has an extra string. */
 263#define STAT_NR_STRINGS_9P 4
 264#define STAT_NR_STRINGS_AK 5
 265#define STAT_FIX_LEN_9P (BIT16SZ +                      /* size */             \
 266                         BIT16SZ +                      /* type */             \
 267                         BIT32SZ +                      /* dev */              \
 268                         QIDSZ +                        /* qid */              \
 269                         BIT32SZ +                      /* mode */             \
 270                         BIT32SZ +                      /* atime u32 */        \
 271                         BIT32SZ +                      /* mtime u32 */        \
 272                         BIT64SZ +                      /* length */           \
 273                         STAT_NR_STRINGS_9P * BIT16SZ + /* string counts */    \
 274                                                 0)
 275#define __STAT_FIX_LEN_AK_NONSTRING (                                          \
 276                         BIT32SZ +                      /* n_uid */            \
 277                         BIT32SZ +                      /* n_gid */            \
 278                         BIT32SZ +                      /* n_muid */           \
 279                         2 * BIT64SZ +                  /* atime */            \
 280                         2 * BIT64SZ +                  /* btime */            \
 281                         2 * BIT64SZ +                  /* ctime */            \
 282                         2 * BIT64SZ +                  /* mtime */            \
 283                                                 0)
 284#define STAT_FIX_LEN_AK (STAT_FIX_LEN_9P +                                     \
 285                         (STAT_NR_STRINGS_AK - STAT_NR_STRINGS_9P) * BIT16SZ + \
 286                         __STAT_FIX_LEN_AK_NONSTRING +                         \
 287                                                 0)
 288
 289#define NOTAG           (uint16_t)~0U   /* Dummy tag */
 290#define NOFID           (uint32_t)~0U   /* Dummy fid */
 291#define IOHDRSZ         24 /* ample room for Twrite/Rread header (iounit) */
 292
 293enum {
 294        Tversion = 100,
 295        Rversion,
 296        Tauth = 102,
 297        Rauth,
 298        Tattach = 104,
 299        Rattach,
 300        Terror = 106,   /* illegal */
 301        Rerror,
 302        Tflush = 108,
 303        Rflush,
 304        Twalk = 110,
 305        Rwalk,
 306        Topen = 112,
 307        Ropen,
 308        Tcreate = 114,
 309        Rcreate,
 310        Tread = 116,
 311        Rread,
 312        Twrite = 118,
 313        Rwrite,
 314        Tclunk = 120,
 315        Rclunk,
 316        Tremove = 122,
 317        Rremove,
 318        Tstat = 124,
 319        Rstat,
 320        Twstat = 126,
 321        Rwstat,
 322        Tmax,
 323};
 324
 325void init_empty_dir(struct dir *d);
 326unsigned int convM2S(uint8_t * unused_uint8_p_t, unsigned int unused_int,
 327                     struct fcall *);
 328unsigned int convS2M(struct fcall *, uint8_t * unused_uint8_p_t, unsigned int);
 329unsigned int sizeS2M(struct fcall *);
 330
 331unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd,
 332                           char *strs);
 333unsigned int convM2kstat(uint8_t * buf, unsigned int nbuf, struct kstat *ks);
 334
 335void statcheck(uint8_t *buf, size_t nbuf);
 336unsigned int convM2D(uint8_t * unused_uint8_p_t, unsigned int unused_int,
 337                     struct dir *, char *unused_char_p_t);
 338unsigned int convD2M(struct dir *, uint8_t * unused_uint8_p_t, unsigned int);
 339unsigned int sizeD2M(struct dir *);
 340
 341int read9pmsg(int unused_int, void *, unsigned int);
 342
 343struct ref {
 344        spinlock_t l;
 345        long ref;
 346};
 347
 348struct rept {
 349        spinlock_t l;
 350        struct rendez r;
 351        void *o;
 352        int t;
 353        int (*active) (void *);
 354        int (*ck) (void *, int);
 355        void (*f) (void *);                     /* called with VM acquire()'d */
 356};
 357
 358enum {
 359        Nopin = -1
 360};
 361
 362struct talarm {
 363        spinlock_t lock;
 364        struct proc *list;
 365};
 366
 367struct alarms {
 368        qlock_t qlock;
 369        struct proc *head;
 370};
 371
 372/*
 373 * Access types in namec & channel flags
 374 */
 375enum {
 376        Aaccess,                        /* as in stat, wstat */
 377        Abind,                          /* for left-hand-side of bind */
 378        Atodir,                         /* as in chdir */
 379        Aopen,                          /* for i/o */
 380        Amount,                         /* to be mounted or mounted upon */
 381        Acreate,                        /* is to be created */
 382        Aremove,                        /* will be removed by caller */
 383        Arename,                        /* new_path of a rename */
 384
 385        /* internal chan flags, used by the kernel only */
 386        COPEN =                 0x0001, /* for i/o */
 387        CMSG =                  0x0002, /* the message channel for a mount */
 388        CFREE =                 0x0004, /* not in use */
 389        CINTERNAL_FLAGS = (COPEN | CMSG | CFREE),
 390
 391        /* chan/file flags, getable via fcntl/getfl and setably via open and
 392         * sometimes fcntl/setfl.  those that can't be set cause an error() in
 393         * fd_setfl. */
 394        CEXTERNAL_FLAGS = (
 395            O_CLOEXEC      | /* (prob should be on the FD, 9ns has it here) */
 396            O_REMCLO       | /* remove on close (also, maybe should be on FD) */
 397            O_APPEND       | /* append on write */
 398            O_NONBLOCK     | /* don't block, can't be set via setfl */
 399            O_PATH         | /* path open, just the name, no I/O */
 400            0),
 401};
 402
 403#define NS_IPCK_SHIFT  2
 404#define NS_UDPCK_SHIFT 3
 405#define NS_TCPCK_SHIFT 4
 406#define NS_PKTCK_SHIFT 5
 407#define NS_TSO_SHIFT 6
 408#define NS_SHIFT_MAX 6
 409
 410enum {
 411        BFREE = (1 << 1),
 412        Bipck = (1 << NS_IPCK_SHIFT),   /* ip checksum (rx) */
 413        Budpck = (1 << NS_UDPCK_SHIFT), /* udp checksum (rx), needed (tx) */
 414        Btcpck = (1 << NS_TCPCK_SHIFT), /* tcp checksum (rx), needed (tx) */
 415        Bpktck = (1 << NS_PKTCK_SHIFT), /* packet checksum (rx, maybe) */
 416        Btso = (1 << NS_TSO_SHIFT),     /* TSO desired (tx) */
 417};
 418#define BLOCK_META_FLAGS (Bipck | Budpck | Btcpck | Bpktck | Btso)
 419#define BLOCK_TRANS_TX_CSUM (Budpck | Btcpck)
 420#define BLOCK_RX_CSUM (Bipck | Budpck | Btcpck)
 421
 422struct extra_bdata {
 423        uintptr_t base;
 424        /* using u32s for packing reasons.  this means no extras > 4GB */
 425        uint32_t off;
 426        uint32_t len;
 427};
 428
 429struct block {
 430        struct block *next;
 431        struct block *list;
 432        uint8_t *rp;                    /* first unconsumed byte */
 433        uint8_t *wp;                    /* first empty byte */
 434        uint8_t *lim;                   /* 1 past the end of the buffer */
 435        uint8_t *base;                  /* start of the buffer */
 436        void (*free) (struct block *);
 437        uint16_t flag;
 438        uint16_t mss;                   /* TCP MSS for TSO */
 439        uint16_t network_offset;        /* offset from rp */
 440        uint16_t transport_offset;      /* offset from rp */
 441        uint16_t tx_csum_offset;        /* offset from tx_offset to store csum */
 442        /* might want something to track the next free extra_data slot */
 443        size_t extra_len;
 444        unsigned int nr_extra_bufs;
 445        struct extra_bdata *extra_data;
 446};
 447#define BLEN(s) ((s)->wp - (s)->rp + (s)->extra_len)
 448#define BHLEN(s) ((s)->wp - (s)->rp)
 449#define BALLOC(s) ((s)->lim - (s)->base + (s)->extra_len)
 450
 451struct chan {
 452        spinlock_t lock;
 453        struct kref ref;
 454        struct chan *next;      /* allocation */
 455        struct chan *link;
 456        int64_t offset;         /* in file */
 457        int type;               /* ID for device type, e.g. #mnt, #kfs, #ip */
 458        uint32_t dev;           /* device specific; can be an instance ID */
 459        uint16_t mode;          /* read/write */
 460        int flag;
 461        struct qid qid;
 462        int fid;                /* for devmnt */
 463        uint32_t iounit;        /* chunk size for i/o; 0==default */
 464        struct mhead *umh;      /* mount point that derived Chan */
 465        struct chan *umc;       /* channel in union; for union read */
 466        qlock_t umqlock;        /* serialize unionreads */
 467        int uri;                /* union read index */
 468        int dri;                /* devdirread index */
 469        uint32_t mountid;
 470        struct mntcache *mcp;   /* Mount cache pointer */
 471        struct mnt *mux;        /* Mnt for clients using me for messages */
 472        union {
 473                void *aux;
 474                char tag[4];    /* for iproute */
 475        };
 476        /* mountpoint, as discovered during walk.
 477         * Used for rename at present.
 478         */
 479        struct chan *mountpoint;
 480        struct chan *mchan;     /* channel to mounted server */
 481        struct qid mqid;        /* qid of root of mount point */
 482        struct cname *name;
 483        /* hack for dir reads to try to get them right. */
 484        int ateof;
 485        void *buf;
 486        int bufused;
 487        /* A lot of synthetic files need something generated at open time, which
 488         * the user can read from (including offsets) while the underlying file
 489         * changes.  Hang that buffer here. */
 490        void *synth_buf;
 491};
 492
 493extern struct chan *kern_slash;
 494
 495struct cname {
 496        struct kref ref;
 497        int alen;               /* allocated length */
 498        int len;                /* strlen(s) */
 499        char *s;
 500};
 501
 502struct fs_file;
 503
 504struct dev {
 505        char *name;
 506
 507        void (*reset)(void);
 508        void (*init)(void);
 509        void (*shutdown)(void);
 510        struct chan *(*attach)(char *muxattach);
 511        struct walkqid *(*walk)(struct chan *, struct chan *, char **name,
 512                                unsigned int);
 513        size_t (*stat)(struct chan *, uint8_t *, size_t);
 514        struct chan *(*open)(struct chan *, int);
 515        void (*create)(struct chan *, char *, int, uint32_t, char *);
 516        void (*close)(struct chan *);
 517        size_t (*read)(struct chan *, void *, size_t, off64_t);
 518        struct block *(*bread)(struct chan *, size_t, off64_t);
 519        size_t (*write)(struct chan *, void *, size_t, off64_t);
 520        size_t (*bwrite)(struct chan *, struct block *, off64_t);
 521        void (*remove)(struct chan *);
 522        void (*rename)(struct chan *, struct chan *, const char *, int);
 523        size_t (*wstat)(struct chan *, uint8_t *, size_t);
 524        void (*power)(int);     /* power mgt: power(1) → on, power (0) → off */
 525//  int (*config)( int unused_int, char *unused_char_p_t, DevConf*);
 526        char *(*chaninfo)(struct chan *, char *, size_t);
 527        int (*tapfd)(struct chan *, struct fd_tap *, int);
 528        unsigned long (*chan_ctl)(struct chan *c, int op, unsigned long a1,
 529                                  unsigned long a2, unsigned long a3,
 530                                  unsigned long a4);
 531        struct fs_file *(*mmap)(struct chan *, struct vm_region *, int, int);
 532        /* we need to be aligned to 64 bytes for the linker tables. */
 533} __attribute__ ((aligned(64)));
 534
 535struct dirtab {
 536        char name[KNAMELEN];
 537        struct qid qid;
 538        int64_t length;
 539        int perm;
 540        /* we need to be aligned to 64 bytes for the linker tables. */
 541} __attribute__ ((aligned(64)));
 542
 543struct walkqid {
 544        struct chan *clone;
 545        int nqid;
 546        struct qid qid[1];
 547};
 548
 549enum {
 550        NSMAX = 1000,
 551        NSLOG = 7,
 552        NSCACHE = (1 << NSLOG),
 553};
 554
 555struct mntwalk {                        /* state for /proc/#/ns */
 556        int cddone;
 557        uint32_t id;
 558        struct mhead *mh;
 559        struct mount *cm;
 560};
 561
 562struct mount {
 563        uint32_t mountid;
 564        struct mount *next;
 565        struct mhead *head;
 566        struct mount *copy;
 567        struct mount *order;
 568        struct chan *to;                /* channel replacing channel */
 569        int mflag;
 570        char *spec;
 571};
 572
 573struct mhead {
 574        struct kref ref;
 575        struct rwlock lock;
 576        struct chan *from;              /* channel mounted upon */
 577        struct mount *mount;            /* what's mounted upon it */
 578        struct mhead *hash;             /* Hash chain */
 579};
 580
 581struct mnt {
 582        spinlock_t lock;
 583        /* references are counted using c->ref; channels on this mount point
 584         * incref(c->mchan) == Mnt.c */
 585        struct chan *c;                 /* Channel to file service */
 586        struct kthread *rip;            /* Reader in progress */
 587        struct mntrpc *queue;           /* Queue of pending requests on chan */
 588        uint32_t id;                    /* Multiplexer id for channel check */
 589        struct mnt *list;               /* Free list */
 590        int flags;                      /* cache */
 591        int msize;                      /* data + IOHDRSZ */
 592        char *version;                  /* 9P version */
 593        struct queue *q;                /* input queue */
 594};
 595
 596enum {
 597        RENDLOG = 5,
 598        RENDHASH = 1 << RENDLOG,        /* Hash to lookup rendezvous tags */
 599        MNTLOG = 5,
 600        MNTHASH = 1 << MNTLOG,  /* Hash to walk mount table */
 601        DELTAFD = 20,   /* allocation quantum for process file descriptors */
 602        MAXNFD = 4000,  /* max per process file descriptors */
 603        MAXKEY = 8,     /* keys for signed modules */
 604};
 605#define MOUNTH(p,qid)   ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)])
 606
 607struct mntparam {
 608        struct chan *chan;
 609        struct chan *authchan;
 610        char *spec;
 611};
 612
 613struct pgrp {
 614        struct kref ref;                /* also used as a lock when mounting */
 615        uint32_t pgrpid;
 616        qlock_t debug;                  /* single access via devproc.c */
 617        struct rwlock ns;               /* Namespace n read/one write lock */
 618        qlock_t nsh;
 619        struct mhead *mnthash[MNTHASH];
 620        int progmode;
 621        int nodevs;
 622        int pin;
 623};
 624
 625struct evalue {
 626        char *var;
 627        char *val;
 628        int len;
 629        struct qid qid;
 630        struct evalue *next;
 631};
 632
 633struct egrp {
 634        struct kref ref;
 635        qlock_t qlock;
 636        struct evalue *entries;
 637        uint32_t path;          /* qid.path of next Evalue to be allocated */
 638        uint32_t vers;          /* of Egrp */
 639};
 640
 641struct signerkey {
 642        struct kref ref;
 643        char *owner;
 644        uint16_t footprint;
 645        uint32_t expires;
 646        void *alg;
 647        void *pk;
 648        void (*pkfree) (void *);
 649};
 650
 651struct skeyset {
 652        struct kref ref;
 653        qlock_t qlock;
 654        uint32_t flags;
 655        char *devs;
 656        int nkey;
 657        struct signerkey *keys[MAXKEY];
 658};
 659
 660/*
 661 * fasttick timer interrupts
 662 */
 663enum {
 664        /* Mode */
 665        Trelative,              /* timer programmed in ns from now */
 666        Tabsolute,              /* timer programmed in ns since epoch */
 667        Tperiodic,              /* periodic timer, period in ns */
 668};
 669
 670enum {
 671        PRINTSIZE = 256,
 672        NUMSIZE = 12,   /* size of formatted number */
 673        MB = (1024 * 1024),
 674        READSTR = 2000, /* temporary buffer size for device reads */
 675};
 676
 677extern struct dev devtab[];
 678extern struct dev __devtabend[];
 679
 680struct cmdbuf {
 681        char *buf;
 682        char **f;
 683        int nf;
 684};
 685
 686struct cmdtab {
 687        int index;              /* used by client to switch on result */
 688        char *cmd;              /* command name */
 689        int narg;               /* expected #args; 0 ==> variadic */
 690};
 691
 692/* queue state bits, all can be set in qopen (Qstarve is always set) */
 693enum {
 694        Qmsg            = (1 << 1),     /* message stream */
 695        Qclosed         = (1 << 2),     /* queue has been closed/hungup */
 696        Qcoalesce       = (1 << 3),     /* coalesce empty packets on read */
 697        Qkick           = (1 << 4),     /* always call kick() after qwrite */
 698        Qdropoverflow   = (1 << 5),     /* drop writes that would block */
 699};
 700
 701/* Per-process structs */
 702#define NR_OPEN_FILES_DEFAULT 32
 703#define NR_FILE_DESC_DEFAULT 32
 704
 705/* Bitmask for file descriptors, big for when we exceed the initial small.  We
 706 * could just use the fd_array to check for openness instead of the bitmask,
 707 * but eventually we might want to use the bitmasks for other things (like
 708 * which files are close_on_exec. */
 709
 710typedef struct fd_set {
 711    uint8_t fds_bits[BYTES_FOR_BITMASK(NR_FILE_DESC_MAX)];
 712} fd_set;
 713
 714
 715struct small_fd_set {
 716    uint8_t fds_bits[BYTES_FOR_BITMASK(NR_FILE_DESC_DEFAULT)];
 717};
 718
 719/* Helper macros to manage fd_sets */
 720#define FD_SET(n, p)    ((p)->fds_bits[(n) / 8] |=  (1 << ((n) & 7)))
 721#define FD_CLR(n, p)    ((p)->fds_bits[(n) / 8] &= ~(1 << ((n) & 7)))
 722#define FD_ISSET(n, p)  ((p)->fds_bits[(n) / 8] &   (1 << ((n) & 7)))
 723#define FD_ZERO(p)              memset((void*)(p), 0, sizeof(*(p)))
 724
 725/* Describes an open file.  We need this, since the FD flags are supposed to be
 726 * per file descriptor, not per file (like the file status flags). */
 727struct file_desc {
 728        struct chan             *fd_chan;
 729        unsigned int            fd_flags;
 730        struct fd_tap           *fd_tap;
 731};
 732
 733/* All open files for a process */
 734struct fd_table {
 735        spinlock_t              lock;
 736        bool                    closed;
 737        int                     max_files;      /* max files ptd to by fd */
 738        int                     max_fdset;      /* max of the current fd_set */
 739        int                     hint_min_fd;    /* <= min available fd */
 740        struct file_desc        *fd;            /* initially pts to fd_array */
 741        struct fd_set           *open_fds;      /* init, pts to open_fds_init */
 742        struct small_fd_set     open_fds_init;
 743        struct file_desc        fd_array[NR_OPEN_FILES_DEFAULT];
 744};
 745
 746ssize_t kread_file(struct file_or_chan *file, void *buf, size_t sz);
 747void *kread_whole_file(struct file_or_chan *file);
 748
 749/* Process-related File management functions */
 750void *lookup_fd(struct fd_table *fdt, int fd, bool incref);
 751int insert_obj_fdt(struct fd_table *fdt, void *obj, int low_fd, int fd_flags,
 752                   bool must_use_low);
 753bool close_fd(struct fd_table *fdt, int fd);
 754void close_fdt(struct fd_table *open_files, bool cloexec);
 755void clone_fdt(struct fd_table *src, struct fd_table *dst);
 756
 757#define DEVDOTDOT -1
 758
 759typedef int Devgen(struct chan *, char *unused_char_p_t, struct dirtab *,
 760                   int unused_int, int, struct dir *);
 761
 762/* inferno portfns.h. Not all these are needed. */
 763#define         FPinit() fpinit()       /* remove this if math lib is linked */
 764void FPrestore(void *);
 765void FPsave(void *);
 766struct cname *addelem(struct cname *, char *unused_char_p_t);
 767void addprog(struct proc *);
 768void addrootfile(char *unused_char_p_t, uint8_t * unused_uint8_p_t, uint32_t);
 769struct block *adjustblock(struct block *, int);
 770struct block *block_alloc(size_t, int);
 771int block_add_extd(struct block *b, unsigned int nr_bufs, int mem_flags);
 772int block_append_extra(struct block *b, uintptr_t base, uint32_t off,
 773                       uint32_t len, int mem_flags);
 774void block_copy_metadata(struct block *new_b, struct block *old_b);
 775void block_reset_metadata(struct block *b);
 776void block_add_to_offsets(struct block *b, int delta);
 777void block_transfer_extras(struct block *new, struct block *old);
 778void block_replace_extras(struct block *new, struct block *old);
 779struct block *block_realloc(struct block *b, size_t header_space);
 780size_t block_copy_to_body(struct block *to, void *from, size_t copy_amt);
 781int anyhigher(void);
 782int anyready(void);
 783void _assert(char *unused_char_p_t);
 784struct block *bl2mem(uint8_t * unused_uint8_p_t, struct block *, int);
 785int blocklen(struct block *);
 786char *channame(struct chan *);
 787void cclose(struct chan *);
 788void chan_incref(struct chan *);
 789void chanfree(struct chan *);
 790void chanrec(struct mnt *);
 791void checkalarms(void);
 792void checkb(struct block *, char *unused_char_p_t);
 793struct chan *cclone(struct chan *);
 794void cclose(struct chan *);
 795void closeegrp(struct egrp *);
 796void closemount(struct mount *);
 797void closepgrp(struct pgrp *);
 798void closesigs(struct skeyset *);
 799void debugcmd(struct cmdbuf *cb);
 800struct mhead *newmhead(struct chan *from);
 801int cmount(struct chan *, struct chan *, int unused_int, char *unused_char_p_t);
 802void cnameclose(struct cname *);
 803struct block *concatblock(struct block *);
 804struct block *linearizeblock(struct block *b);
 805void confinit(void);
 806void cons_add_char(char c);
 807struct block *copyblock(struct block *b, int mem_flags);
 808struct chan *cunique(struct chan *);
 809struct chan *createdir(struct chan *, struct mhead *);
 810void cunmount(struct chan *, struct chan *);
 811void cursorenable(void);
 812void cursordisable(void);
 813int cursoron(int);
 814void cursoroff(int);
 815struct chan *devattach(const char *name, char *spec);
 816struct block *devbread(struct chan *, size_t, off64_t);
 817size_t devbwrite(struct chan *, struct block *, off64_t);
 818struct chan *devclone(struct chan *);
 819void devcreate(struct chan *, char *name, int mode, uint32_t perm, char *ext);
 820void devdir(struct chan *, struct qid, char *, int64_t, char *, long,
 821            struct dir *);
 822long devdirread(struct chan *, char *, long, struct dirtab *, int, Devgen *);
 823Devgen devgen;
 824void devinit(void);
 825int devno(const char *name, int user);
 826void devpower(int);
 827struct dev *devbyname(char *unused_char_p_t);
 828struct chan *devopen(struct chan *, int unused_int, struct dirtab *,
 829                     int unused_int2, Devgen *);
 830void devpermcheck(char *unused_char_p_t, uint32_t, int);
 831void devremove(struct chan *);
 832void devreset(void);
 833void devshutdown(void);
 834size_t dev_make_stat(struct chan *c, struct dir *dir, uint8_t *dp, size_t n);
 835size_t devstat(struct chan *, uint8_t *db, size_t n, struct dirtab *,
 836               int ntab, Devgen *);
 837struct walkqid *devwalk(struct chan *, struct chan *, char **unused_char_pp_t,
 838                        int unused_int, struct dirtab *, int unused_intw,
 839                        Devgen *);
 840size_t devwstat(struct chan *, uint8_t *, size_t);
 841char *devchaninfo(struct chan *chan, char *ret, size_t ret_l);
 842void disinit(void *);
 843void disfault(void *, char *unused_char_p_t);
 844int domount(struct chan **, struct mhead **);
 845void drawactive(int);
 846void drawcmap(void);
 847void dumpstack(void);
 848void egrpcpy(struct egrp *, struct egrp *);
 849int emptystr(char *unused_char_p_t);
 850int eqchan(struct chan *, struct chan *, int);
 851int eqqid(struct qid, struct qid);
 852
 853void errstr(char *unused_char_p_t, int);
 854void excinit(void);
 855void exit(int);
 856void reboot(void);
 857void halt(void);
 858int export(int unused_int, char *unused_char_p_t, int);
 859uint64_t fastticks(uint64_t *);
 860uint64_t fastticks2ns(uint64_t);
 861int findmount(struct chan **, struct mhead **, int unused_int, int, struct qid);
 862void free_block_extra(struct block *);
 863size_t freeb(struct block *b);
 864size_t freeblist(struct block *b);
 865void freeskey(struct signerkey *);
 866void getcolor(uint32_t, uint32_t *, uint32_t *, uint32_t *);
 867uint32_t getmalloctag(void *);
 868uint32_t getrealloctag(void *);
 869void printblock(struct block *b);
 870void ilock(spinlock_t *);
 871int iprint(char *unused_char_p_t, ...);
 872void isdir(struct chan *);
 873int islo(void);
 874void iunlock(spinlock_t *);
 875void ixsummary(void);
 876void kbdclock(void);
 877int kbdcr2nl(struct queue *, int);
 878int kbdputc(struct queue *, int);
 879void kbdrepeat(int);
 880void kproc(char *unused_char_p_t, void (*)(void *), void *, int);
 881void kprocchild(struct proc *, void (*)(void *), void *);
 882void (*kproftick) (uint32_t);
 883void ksetenv(char *unused_char_p_t, char *, int);
 884void kstrdup(char **cp, char *name);
 885
 886struct block *mem2bl(uint8_t * unused_uint8_p_t, int);
 887int memusehigh(void);
 888void microdelay(int);
 889uint64_t mk64fract(uint64_t, uint64_t);
 890void mkqid(struct qid *, int64_t, uint32_t, int);
 891void modinit(void);
 892struct chan *mntauth(struct chan *, char *unused_char_p_t);
 893long mntversion(struct chan *, char *unused_char_p_t, int unused_int, int);
 894void mountfree(struct mount *);
 895void mousetrack(int unused_int, int, int, int);
 896uint64_t ms2fastticks(uint32_t);
 897void mul64fract(uint64_t *, uint64_t, uint64_t);
 898void muxclose(struct mnt *);
 899struct chan *namec(char *unused_char_p_t, int unused_int, int, uint32_t,
 900                   void *ext);
 901struct chan *namec_from(struct chan *c, char *name, int amode, int omode,
 902                        uint32_t perm, void *ext);
 903struct chan *newchan(void);
 904struct egrp *newegrp(void);
 905struct mount *newmount(struct mhead *, struct chan *, int unused_int,
 906                       char *unused_char_p_t);
 907struct pgrp *newpgrp(void);
 908struct proc *newproc(void);
 909char *nextelem(char *unused_char_p_t, char *);
 910
 911struct cname *newcname(char *unused_char_p_t);
 912void notkilled(void);
 913uint32_t random_read(void *xp, uint32_t n);
 914uint32_t urandom_read(void *xp, uint32_t n);
 915uint64_t ns2fastticks(uint64_t);
 916int okaddr(uint32_t, uint32_t, int);
 917int omode_to_rwx(int);
 918int omode_to_9p_accmode(int open_flags);
 919int access_bits_to_omode(int access_bits);
 920struct block *packblock(struct block *);
 921struct block *padblock(struct block *, int);
 922
 923void pgrpcpy(struct pgrp *, struct pgrp *);
 924
 925int progfdprint(struct chan *, int unused_int, int, char *unused_char_p_t,
 926                int i);
 927int pullblock(struct block **, int);
 928struct block *pullupblock(struct block *b, size_t n);
 929struct block *pullupqueue(struct queue *b, size_t n);
 930void putmhead(struct mhead *);
 931void putstrn(char *unused_char_p_t, int);
 932void qaddlist(struct queue *, struct block *);
 933struct block *qbread(struct queue *q, size_t len);
 934struct block *qbread_nonblock(struct queue *q, size_t len);
 935ssize_t qbwrite(struct queue *, struct block *);
 936ssize_t qbwrite_nonblock(struct queue *, struct block *);
 937ssize_t qibwrite(struct queue *q, struct block *b);
 938struct queue *qbypass(void (*)(void *, struct block *), void *);
 939int qcanread(struct queue *);
 940void qclose(struct queue *);
 941struct block *qcopy(struct queue *, int unused_int, uint32_t);
 942struct block *qclone(struct queue *q, int header_len, int len,
 943                     uint32_t offset);
 944struct block *blist_clone(struct block *blist, int header_len, int len,
 945                          uint32_t offset);
 946size_t qdiscard(struct queue *q, size_t len);
 947void qflush(struct queue *);
 948void qfree(struct queue *);
 949int qfull(struct queue *);
 950struct block *qget(struct queue *);
 951void qhangup(struct queue *, char *unused_char_p_t);
 952int qisclosed(struct queue *);
 953ssize_t qiwrite(struct queue *, void *, int);
 954int qlen(struct queue *);
 955size_t q_bytes_read(struct queue *q);
 956void qdropoverflow(struct queue *, bool);
 957void q_toggle_qmsg(struct queue *q, bool onoff);
 958void q_toggle_qcoalesce(struct queue *q, bool onoff);
 959struct queue *qopen(int unused_int, int, void (*)(void *), void *);
 960ssize_t qpass(struct queue *, struct block *);
 961ssize_t qpassnolim(struct queue *, struct block *);
 962void qputback(struct queue *, struct block *);
 963size_t qread(struct queue *q, void *va, size_t len);
 964size_t qread_nonblock(struct queue *q, void *va, size_t len);
 965void qreopen(struct queue *);
 966void qsetlimit(struct queue *, size_t);
 967size_t qgetlimit(struct queue *);
 968int qwindow(struct queue *);
 969ssize_t qwrite(struct queue *, void *, int);
 970ssize_t qwrite_nonblock(struct queue *, void *, int);
 971typedef void (*qio_wake_cb_t)(struct queue *q, void *data, int filter);
 972void qio_set_wake_cb(struct queue *q, qio_wake_cb_t func, void *data);
 973bool qreadable(struct queue *q);
 974bool qwritable(struct queue *q);
 975
 976void *realloc(void *, uint32_t);
 977int readmem(unsigned long offset, char *buf, unsigned long n, const void *mem,
 978            size_t mem_len);
 979int readnum(unsigned long off, char *buf, unsigned long n, unsigned long val,
 980            size_t size);
 981int readnum_hex(unsigned long off, char *buf, unsigned long n,
 982                unsigned long val, size_t size);
 983int readstr(unsigned long offset, char *buf, unsigned long n, const char *str);
 984int readnum_int64_t(uint32_t, char *unused_char_p_t, uint32_t, int64_t, int);
 985unsigned long strtoul_from_ubuf(void *ubuf, size_t count, int base);
 986void ready(struct proc *);
 987void renameproguser(char *unused_char_p_t, char *);
 988void renameuser(char *unused_char_p_t, char *);
 989void resrcwait(char *unused_char_p_t);
 990struct proc *runproc(void);
 991void (*serwrite) (char *unused_char_p_t, int);
 992int setcolor(uint32_t, uint32_t, uint32_t, uint32_t);
 993
 994void setmalloctag(void *, uint32_t);
 995int setpri(int);
 996void setrealloctag(void *, uint32_t);
 997char *skipslash(char *unused_char_p_t);
 998void *smalloc(uint32_t);
 999int splhi(void);
1000int spllo(void);
1001void splx(int);
1002void splxpc(int);
1003void swiproc(struct proc *, int);
1004uint32_t _tas(uint32_t *);
1005uint32_t tk2ms(uint32_t);
1006#define         TK2MS(x) ((x)*(1000/HZ))
1007uint64_t tod2fastticks(int64_t);
1008int64_t todget(int64_t *);
1009void todfix(void);
1010void todsetfreq(int64_t);
1011void todinit(void);
1012void todset(int64_t, int64_t, int);
1013int tready(void *);
1014struct block *trimblock(struct block *, int unused_int, int);
1015int uartgetc(void);
1016void uartputc(int);
1017void uartputs(char *unused_char_p_t, int);
1018void unlock(spinlock_t *);
1019void userinit(void);
1020uint32_t userpc(void);
1021void validname(char *, int);
1022void validwstatname(char *);
1023void *xalloc(uint32_t);
1024void *xallocz(uint32_t, int);
1025void xfree(void *);
1026void xhole(uint32_t, uint32_t);
1027void xinit(void);
1028int xmerge(void *, void *);
1029void *xspanalloc(uint32_t, int unused_int, uint32_t);
1030void xsummary(void);
1031
1032void validaddr(void *, uint32_t, int);
1033void *vmemchr(void *, int unused_int, int);
1034void hnputv(void *, int64_t);
1035void hnputl(void *, uint32_t);
1036void hnputs(void *, uint16_t);
1037int64_t nhgetv(void *);
1038uint32_t nhgetl(void *);
1039uint16_t nhgets(void *);
1040
1041char *get_cur_genbuf(void);
1042
1043static inline const char *chan_dev_name(struct chan *c)
1044{
1045        return devtab[c->type].name;
1046}
1047
1048/* hack for now. */
1049#define NOW     tsc2msec(read_tsc())
1050#define seconds() tsc2sec(read_tsc())
1051#define milliseconds() tsc2msec(read_tsc())
1052
1053/* kern/drivers/dev/tab.c */
1054void devtabinit();
1055void devtabreset();
1056
1057/* kern/src/ns/parse.c */
1058struct cmdbuf *parsecmd(char *p, size_t n);
1059void cmderror(struct cmdbuf *cb, char *s);
1060struct cmdtab *lookupcmd(struct cmdbuf *cb, struct cmdtab *ctab, int nctab);
1061
1062/* kern/src/ns/sysfile.c */
1063int newfd(struct chan *c, int low_fd, int oflags, bool must_use_low);
1064struct chan *fdtochan(struct fd_table *fdt, int fd, int mode, int chkmnt,
1065                      int iref);
1066long kchanio(void *vc, void *buf, int n, int mode);
1067int openmode(uint32_t o);
1068void fdclose(struct fd_table *fdt, int fd);
1069int syschdir(struct proc *target, char *path);
1070int sysfchdir(struct proc *target, int fd);
1071int grpclose(struct fd_table *fdt, int fd);
1072int sysclose(int fd);
1073int syscreate(char *path, int mode, uint32_t perm);
1074int sysdup(int old, int low_fd, bool must_use_low);
1075int sys_dup_to(struct proc *from_proc, unsigned int from_fd,
1076               struct proc *to_proc, unsigned int to_fd);
1077int sysfstat(int fd, uint8_t*, int n);
1078int sysfstatakaros(int fd, struct kstat *);
1079char *sysgetcwd(void);
1080int sysfauth(int fd, char *aname);
1081int sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen);
1082int sysfwstat(int fd, uint8_t * buf, int n);
1083long bindmount(struct chan *c, char *old, int flag, char *spec);
1084int sysbind(char *new, char *old, int flags);
1085int syssymlink(char *new_path, char *old_path);
1086int sysmount(int fd, int afd, char *old, int flags, char *spec);
1087int sysunmount(char *old, char *new);
1088int sysopenat(int dirfd, char *path, int vfs_flags, int perm);
1089int sysopen(char *path, int vfs_flags);
1090long unionread(struct chan *c, void *va, long n);
1091void read_exactly_n(struct chan *c, void *vp, long n);
1092long sysread(int fd, void *va, long n);
1093long syspread(int fd, void *va, long n, int64_t off);
1094int sysremove(char *path);
1095int sysrename(char *from_path, char *to_path);
1096int64_t sysseek(int fd, int64_t off, int whence);
1097void validstat(uint8_t * s, int n, int slashok);
1098int sysstat(char *path, uint8_t*, int n);
1099int syslstat(char *path, uint8_t*, int n);
1100int sysstatakaros(char *path, struct kstat *, int flags);
1101long syswrite(int fd, void *va, long n);
1102long syspwrite(int fd, void *va, long n, int64_t off);
1103int syswstat(char *path, uint8_t * buf, int n);
1104struct dir *chandirstat(struct chan *c);
1105struct dir *sysdirstat(char *name);
1106struct dir *sysdirlstat(char *name);
1107struct dir *sysdirfstat(int fd);
1108int sysdirwstat(char *name, struct dir *dir);
1109int sysdirfwstat(int fd, struct dir *dir);
1110long sysdirread(int fd, struct kdirent **d);
1111int sysiounit(int fd);
1112void print_chaninfo(struct chan *ch);
1113int plan9setup(struct proc *new_proc, struct proc *parent, int flags);
1114int iseve(void);
1115int fd_getfl(int fd);
1116int fd_chan_ctl(int fd, int cmd, unsigned long arg1, unsigned long arg2,
1117                unsigned long arg3, unsigned long arg4);
1118int fd_get_fd_flags(struct fd_table *fdt, int fd);
1119int fd_set_fd_flags(struct fd_table *fdt, int fd, int new_fl);
1120
1121/* kern/drivers/dev/srv.c */
1122char *srvname(struct chan *c);
1123
1124/* kern/src/eipconv.c. Put them here or face real include hell. */
1125void printqid(void (*putch) (int, void **), void **putdat, struct qid *q);
1126void printcname(void (*putch) (int, void **), void **putdat, struct cname *c);
1127void printchan(void (*putch) (int, void **), void **putdat, struct chan *c);
1128
1129/* kern/src/ns/util.c */
1130bool caller_is_username(char *uid);
1131bool caller_has_perms(char *fileuid, uint32_t perm, int omode);
1132bool caller_has_dir_perms(struct dir *dir, int omode);
1133void dir_perm_check(struct dir *dir, int omode);
1134
1135static inline int abs(int a)
1136{
1137        if (a < 0)
1138                return -a;
1139        return a;
1140}
1141
1142extern struct username eve;
1143extern unsigned int qiomaxatomic;
1144
1145/* special sections */
1146#define __devtab  __attribute__((__section__(".devtab")))
1147
1148#define DEVVARS_ENTRY(name, fmt)                                               \
1149struct dirtab __attribute__((__section__("devvars"))) __devvars_##name =       \
1150              {#name "!" fmt,                                                  \
1151               {(uint64_t)&(name), 0, QTFILE},                                 \
1152               sizeof((name)),                                                 \
1153               0444}
1154