cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

coda.rst (44463B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3===========================
      4Coda Kernel-Venus Interface
      5===========================
      6
      7.. Note::
      8
      9   This is one of the technical documents describing a component of
     10   Coda -- this document describes the client kernel-Venus interface.
     11
     12For more information:
     13
     14  http://www.coda.cs.cmu.edu
     15
     16For user level software needed to run Coda:
     17
     18  ftp://ftp.coda.cs.cmu.edu
     19
     20To run Coda you need to get a user level cache manager for the client,
     21named Venus, as well as tools to manipulate ACLs, to log in, etc.  The
     22client needs to have the Coda filesystem selected in the kernel
     23configuration.
     24
     25The server needs a user level server and at present does not depend on
     26kernel support.
     27
     28  The Venus kernel interface
     29
     30  Peter J. Braam
     31
     32  v1.0, Nov 9, 1997
     33
     34  This document describes the communication between Venus and kernel
     35  level filesystem code needed for the operation of the Coda file sys-
     36  tem.  This document version is meant to describe the current interface
     37  (version 1.0) as well as improvements we envisage.
     38
     39.. Table of Contents
     40
     41  1. Introduction
     42
     43  2. Servicing Coda filesystem calls
     44
     45  3. The message layer
     46
     47     3.1 Implementation details
     48
     49  4. The interface at the call level
     50
     51     4.1 Data structures shared by the kernel and Venus
     52     4.2 The pioctl interface
     53     4.3 root
     54     4.4 lookup
     55     4.5 getattr
     56     4.6 setattr
     57     4.7 access
     58     4.8 create
     59     4.9 mkdir
     60     4.10 link
     61     4.11 symlink
     62     4.12 remove
     63     4.13 rmdir
     64     4.14 readlink
     65     4.15 open
     66     4.16 close
     67     4.17 ioctl
     68     4.18 rename
     69     4.19 readdir
     70     4.20 vget
     71     4.21 fsync
     72     4.22 inactive
     73     4.23 rdwr
     74     4.24 odymount
     75     4.25 ody_lookup
     76     4.26 ody_expand
     77     4.27 prefetch
     78     4.28 signal
     79
     80  5. The minicache and downcalls
     81
     82     5.1 INVALIDATE
     83     5.2 FLUSH
     84     5.3 PURGEUSER
     85     5.4 ZAPFILE
     86     5.5 ZAPDIR
     87     5.6 ZAPVNODE
     88     5.7 PURGEFID
     89     5.8 REPLACE
     90
     91  6. Initialization and cleanup
     92
     93     6.1 Requirements
     94
     951. Introduction
     96===============
     97
     98  A key component in the Coda Distributed File System is the cache
     99  manager, Venus.
    100
    101  When processes on a Coda enabled system access files in the Coda
    102  filesystem, requests are directed at the filesystem layer in the
    103  operating system. The operating system will communicate with Venus to
    104  service the request for the process.  Venus manages a persistent
    105  client cache and makes remote procedure calls to Coda file servers and
    106  related servers (such as authentication servers) to service these
    107  requests it receives from the operating system.  When Venus has
    108  serviced a request it replies to the operating system with appropriate
    109  return codes, and other data related to the request.  Optionally the
    110  kernel support for Coda may maintain a minicache of recently processed
    111  requests to limit the number of interactions with Venus.  Venus
    112  possesses the facility to inform the kernel when elements from its
    113  minicache are no longer valid.
    114
    115  This document describes precisely this communication between the
    116  kernel and Venus.  The definitions of so called upcalls and downcalls
    117  will be given with the format of the data they handle. We shall also
    118  describe the semantic invariants resulting from the calls.
    119
    120  Historically Coda was implemented in a BSD file system in Mach 2.6.
    121  The interface between the kernel and Venus is very similar to the BSD
    122  VFS interface.  Similar functionality is provided, and the format of
    123  the parameters and returned data is very similar to the BSD VFS.  This
    124  leads to an almost natural environment for implementing a kernel-level
    125  filesystem driver for Coda in a BSD system.  However, other operating
    126  systems such as Linux and Windows 95 and NT have virtual filesystem
    127  with different interfaces.
    128
    129  To implement Coda on these systems some reverse engineering of the
    130  Venus/Kernel protocol is necessary.  Also it came to light that other
    131  systems could profit significantly from certain small optimizations
    132  and modifications to the protocol. To facilitate this work as well as
    133  to make future ports easier, communication between Venus and the
    134  kernel should be documented in great detail.  This is the aim of this
    135  document.
    136
    1372.  Servicing Coda filesystem calls
    138===================================
    139
    140  The service of a request for a Coda file system service originates in
    141  a process P which accessing a Coda file. It makes a system call which
    142  traps to the OS kernel. Examples of such calls trapping to the kernel
    143  are ``read``, ``write``, ``open``, ``close``, ``create``, ``mkdir``,
    144  ``rmdir``, ``chmod`` in a Unix ontext.  Similar calls exist in the Win32
    145  environment, and are named ``CreateFile``.
    146
    147  Generally the operating system handles the request in a virtual
    148  filesystem (VFS) layer, which is named I/O Manager in NT and IFS
    149  manager in Windows 95.  The VFS is responsible for partial processing
    150  of the request and for locating the specific filesystem(s) which will
    151  service parts of the request.  Usually the information in the path
    152  assists in locating the correct FS drivers.  Sometimes after extensive
    153  pre-processing, the VFS starts invoking exported routines in the FS
    154  driver.  This is the point where the FS specific processing of the
    155  request starts, and here the Coda specific kernel code comes into
    156  play.
    157
    158  The FS layer for Coda must expose and implement several interfaces.
    159  First and foremost the VFS must be able to make all necessary calls to
    160  the Coda FS layer, so the Coda FS driver must expose the VFS interface
    161  as applicable in the operating system. These differ very significantly
    162  among operating systems, but share features such as facilities to
    163  read/write and create and remove objects.  The Coda FS layer services
    164  such VFS requests by invoking one or more well defined services
    165  offered by the cache manager Venus.  When the replies from Venus have
    166  come back to the FS driver, servicing of the VFS call continues and
    167  finishes with a reply to the kernel's VFS. Finally the VFS layer
    168  returns to the process.
    169
    170  As a result of this design a basic interface exposed by the FS driver
    171  must allow Venus to manage message traffic.  In particular Venus must
    172  be able to retrieve and place messages and to be notified of the
    173  arrival of a new message. The notification must be through a mechanism
    174  which does not block Venus since Venus must attend to other tasks even
    175  when no messages are waiting or being processed.
    176
    177  **Interfaces of the Coda FS Driver**
    178
    179  Furthermore the FS layer provides for a special path of communication
    180  between a user process and Venus, called the pioctl interface. The
    181  pioctl interface is used for Coda specific services, such as
    182  requesting detailed information about the persistent cache managed by
    183  Venus. Here the involvement of the kernel is minimal.  It identifies
    184  the calling process and passes the information on to Venus.  When
    185  Venus replies the response is passed back to the caller in unmodified
    186  form.
    187
    188  Finally Venus allows the kernel FS driver to cache the results from
    189  certain services.  This is done to avoid excessive context switches
    190  and results in an efficient system.  However, Venus may acquire
    191  information, for example from the network which implies that cached
    192  information must be flushed or replaced. Venus then makes a downcall
    193  to the Coda FS layer to request flushes or updates in the cache.  The
    194  kernel FS driver handles such requests synchronously.
    195
    196  Among these interfaces the VFS interface and the facility to place,
    197  receive and be notified of messages are platform specific.  We will
    198  not go into the calls exported to the VFS layer but we will state the
    199  requirements of the message exchange mechanism.
    200
    201
    2023.  The message layer
    203=====================
    204
    205  At the lowest level the communication between Venus and the FS driver
    206  proceeds through messages.  The synchronization between processes
    207  requesting Coda file service and Venus relies on blocking and waking
    208  up processes.  The Coda FS driver processes VFS- and pioctl-requests
    209  on behalf of a process P, creates messages for Venus, awaits replies
    210  and finally returns to the caller.  The implementation of the exchange
    211  of messages is platform specific, but the semantics have (so far)
    212  appeared to be generally applicable.  Data buffers are created by the
    213  FS Driver in kernel memory on behalf of P and copied to user memory in
    214  Venus.
    215
    216  The FS Driver while servicing P makes upcalls to Venus.  Such an
    217  upcall is dispatched to Venus by creating a message structure.  The
    218  structure contains the identification of P, the message sequence
    219  number, the size of the request and a pointer to the data in kernel
    220  memory for the request.  Since the data buffer is re-used to hold the
    221  reply from Venus, there is a field for the size of the reply.  A flags
    222  field is used in the message to precisely record the status of the
    223  message.  Additional platform dependent structures involve pointers to
    224  determine the position of the message on queues and pointers to
    225  synchronization objects.  In the upcall routine the message structure
    226  is filled in, flags are set to 0, and it is placed on the *pending*
    227  queue.  The routine calling upcall is responsible for allocating the
    228  data buffer; its structure will be described in the next section.
    229
    230  A facility must exist to notify Venus that the message has been
    231  created, and implemented using available synchronization objects in
    232  the OS. This notification is done in the upcall context of the process
    233  P. When the message is on the pending queue, process P cannot proceed
    234  in upcall.  The (kernel mode) processing of P in the filesystem
    235  request routine must be suspended until Venus has replied.  Therefore
    236  the calling thread in P is blocked in upcall.  A pointer in the
    237  message structure will locate the synchronization object on which P is
    238  sleeping.
    239
    240  Venus detects the notification that a message has arrived, and the FS
    241  driver allow Venus to retrieve the message with a getmsg_from_kernel
    242  call. This action finishes in the kernel by putting the message on the
    243  queue of processing messages and setting flags to READ.  Venus is
    244  passed the contents of the data buffer. The getmsg_from_kernel call
    245  now returns and Venus processes the request.
    246
    247  At some later point the FS driver receives a message from Venus,
    248  namely when Venus calls sendmsg_to_kernel.  At this moment the Coda FS
    249  driver looks at the contents of the message and decides if:
    250
    251
    252  *  the message is a reply for a suspended thread P.  If so it removes
    253     the message from the processing queue and marks the message as
    254     WRITTEN.  Finally, the FS driver unblocks P (still in the kernel
    255     mode context of Venus) and the sendmsg_to_kernel call returns to
    256     Venus.  The process P will be scheduled at some point and continues
    257     processing its upcall with the data buffer replaced with the reply
    258     from Venus.
    259
    260  *  The message is a ``downcall``.  A downcall is a request from Venus to
    261     the FS Driver. The FS driver processes the request immediately
    262     (usually a cache eviction or replacement) and when it finishes
    263     sendmsg_to_kernel returns.
    264
    265  Now P awakes and continues processing upcall.  There are some
    266  subtleties to take account of. First P will determine if it was woken
    267  up in upcall by a signal from some other source (for example an
    268  attempt to terminate P) or as is normally the case by Venus in its
    269  sendmsg_to_kernel call.  In the normal case, the upcall routine will
    270  deallocate the message structure and return.  The FS routine can proceed
    271  with its processing.
    272
    273
    274  **Sleeping and IPC arrangements**
    275
    276  In case P is woken up by a signal and not by Venus, it will first look
    277  at the flags field.  If the message is not yet READ, the process P can
    278  handle its signal without notifying Venus.  If Venus has READ, and
    279  the request should not be processed, P can send Venus a signal message
    280  to indicate that it should disregard the previous message.  Such
    281  signals are put in the queue at the head, and read first by Venus.  If
    282  the message is already marked as WRITTEN it is too late to stop the
    283  processing.  The VFS routine will now continue.  (-- If a VFS request
    284  involves more than one upcall, this can lead to complicated state, an
    285  extra field "handle_signals" could be added in the message structure
    286  to indicate points of no return have been passed.--)
    287
    288
    289
    2903.1.  Implementation details
    291----------------------------
    292
    293  The Unix implementation of this mechanism has been through the
    294  implementation of a character device associated with Coda.  Venus
    295  retrieves messages by doing a read on the device, replies are sent
    296  with a write and notification is through the select system call on the
    297  file descriptor for the device.  The process P is kept waiting on an
    298  interruptible wait queue object.
    299
    300  In Windows NT and the DPMI Windows 95 implementation a DeviceIoControl
    301  call is used.  The DeviceIoControl call is designed to copy buffers
    302  from user memory to kernel memory with OPCODES. The sendmsg_to_kernel
    303  is issued as a synchronous call, while the getmsg_from_kernel call is
    304  asynchronous.  Windows EventObjects are used for notification of
    305  message arrival.  The process P is kept waiting on a KernelEvent
    306  object in NT and a semaphore in Windows 95.
    307
    308
    3094.  The interface at the call level
    310===================================
    311
    312
    313  This section describes the upcalls a Coda FS driver can make to Venus.
    314  Each of these upcalls make use of two structures: inputArgs and
    315  outputArgs.   In pseudo BNF form the structures take the following
    316  form::
    317
    318
    319	struct inputArgs {
    320	    u_long opcode;
    321	    u_long unique;     /* Keep multiple outstanding msgs distinct */
    322	    u_short pid;                 /* Common to all */
    323	    u_short pgid;                /* Common to all */
    324	    struct CodaCred cred;        /* Common to all */
    325
    326	    <union "in" of call dependent parts of inputArgs>
    327	};
    328
    329	struct outputArgs {
    330	    u_long opcode;
    331	    u_long unique;       /* Keep multiple outstanding msgs distinct */
    332	    u_long result;
    333
    334	    <union "out" of call dependent parts of inputArgs>
    335	};
    336
    337
    338
    339  Before going on let us elucidate the role of the various fields. The
    340  inputArgs start with the opcode which defines the type of service
    341  requested from Venus. There are approximately 30 upcalls at present
    342  which we will discuss.   The unique field labels the inputArg with a
    343  unique number which will identify the message uniquely.  A process and
    344  process group id are passed.  Finally the credentials of the caller
    345  are included.
    346
    347  Before delving into the specific calls we need to discuss a variety of
    348  data structures shared by the kernel and Venus.
    349
    350
    351
    352
    3534.1.  Data structures shared by the kernel and Venus
    354----------------------------------------------------
    355
    356
    357  The CodaCred structure defines a variety of user and group ids as
    358  they are set for the calling process. The vuid_t and vgid_t are 32 bit
    359  unsigned integers.  It also defines group membership in an array.  On
    360  Unix the CodaCred has proven sufficient to implement good security
    361  semantics for Coda but the structure may have to undergo modification
    362  for the Windows environment when these mature::
    363
    364	struct CodaCred {
    365	    vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, effective, set, fs uid */
    366	    vgid_t cr_gid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
    367	    vgid_t cr_groups[NGROUPS];        /* Group membership for caller */
    368	};
    369
    370
    371  .. Note::
    372
    373     It is questionable if we need CodaCreds in Venus. Finally Venus
    374     doesn't know about groups, although it does create files with the
    375     default uid/gid.  Perhaps the list of group membership is superfluous.
    376
    377
    378  The next item is the fundamental identifier used to identify Coda
    379  files, the ViceFid.  A fid of a file uniquely defines a file or
    380  directory in the Coda filesystem within a cell [1]_::
    381
    382	typedef struct ViceFid {
    383	    VolumeId Volume;
    384	    VnodeId Vnode;
    385	    Unique_t Unique;
    386	} ViceFid;
    387
    388  .. [1] A cell is agroup of Coda servers acting under the aegis of a single
    389	 system control machine or SCM. See the Coda Administration manual
    390	 for a detailed description of the role of the SCM.
    391
    392  Each of the constituent fields: VolumeId, VnodeId and Unique_t are
    393  unsigned 32 bit integers.  We envisage that a further field will need
    394  to be prefixed to identify the Coda cell; this will probably take the
    395  form of a Ipv6 size IP address naming the Coda cell through DNS.
    396
    397  The next important structure shared between Venus and the kernel is
    398  the attributes of the file.  The following structure is used to
    399  exchange information.  It has room for future extensions such as
    400  support for device files (currently not present in Coda)::
    401
    402
    403	struct coda_timespec {
    404		int64_t         tv_sec;         /* seconds */
    405		long            tv_nsec;        /* nanoseconds */
    406	};
    407
    408	struct coda_vattr {
    409		enum coda_vtype va_type;        /* vnode type (for create) */
    410		u_short         va_mode;        /* files access mode and type */
    411		short           va_nlink;       /* number of references to file */
    412		vuid_t          va_uid;         /* owner user id */
    413		vgid_t          va_gid;         /* owner group id */
    414		long            va_fsid;        /* file system id (dev for now) */
    415		long            va_fileid;      /* file id */
    416		u_quad_t        va_size;        /* file size in bytes */
    417		long            va_blocksize;   /* blocksize preferred for i/o */
    418		struct coda_timespec va_atime;  /* time of last access */
    419		struct coda_timespec va_mtime;  /* time of last modification */
    420		struct coda_timespec va_ctime;  /* time file changed */
    421		u_long          va_gen;         /* generation number of file */
    422		u_long          va_flags;       /* flags defined for file */
    423		dev_t           va_rdev;        /* device special file represents */
    424		u_quad_t        va_bytes;       /* bytes of disk space held by file */
    425		u_quad_t        va_filerev;     /* file modification number */
    426		u_int           va_vaflags;     /* operations flags, see below */
    427		long            va_spare;       /* remain quad aligned */
    428	};
    429
    430
    4314.2.  The pioctl interface
    432--------------------------
    433
    434
    435  Coda specific requests can be made by application through the pioctl
    436  interface. The pioctl is implemented as an ordinary ioctl on a
    437  fictitious file /coda/.CONTROL.  The pioctl call opens this file, gets
    438  a file handle and makes the ioctl call. Finally it closes the file.
    439
    440  The kernel involvement in this is limited to providing the facility to
    441  open and close and pass the ioctl message and to verify that a path in
    442  the pioctl data buffers is a file in a Coda filesystem.
    443
    444  The kernel is handed a data packet of the form::
    445
    446	struct {
    447	    const char *path;
    448	    struct ViceIoctl vidata;
    449	    int follow;
    450	} data;
    451
    452
    453
    454  where::
    455
    456
    457	struct ViceIoctl {
    458		caddr_t in, out;        /* Data to be transferred in, or out */
    459		short in_size;          /* Size of input buffer <= 2K */
    460		short out_size;         /* Maximum size of output buffer, <= 2K */
    461	};
    462
    463
    464
    465  The path must be a Coda file, otherwise the ioctl upcall will not be
    466  made.
    467
    468  .. Note:: The data structures and code are a mess.  We need to clean this up.
    469
    470
    471**We now proceed to document the individual calls**:
    472
    473
    4744.3.  root
    475----------
    476
    477
    478  Arguments
    479     in
    480
    481	empty
    482
    483     out::
    484
    485		struct cfs_root_out {
    486		    ViceFid VFid;
    487		} cfs_root;
    488
    489
    490
    491  Description
    492    This call is made to Venus during the initialization of
    493    the Coda filesystem. If the result is zero, the cfs_root structure
    494    contains the ViceFid of the root of the Coda filesystem. If a non-zero
    495    result is generated, its value is a platform dependent error code
    496    indicating the difficulty Venus encountered in locating the root of
    497    the Coda filesystem.
    498
    4994.4.  lookup
    500------------
    501
    502
    503  Summary
    504    Find the ViceFid and type of an object in a directory if it exists.
    505
    506  Arguments
    507     in::
    508
    509		struct  cfs_lookup_in {
    510		    ViceFid     VFid;
    511		    char        *name;          /* Place holder for data. */
    512		} cfs_lookup;
    513
    514
    515
    516     out::
    517
    518		struct cfs_lookup_out {
    519		    ViceFid VFid;
    520		    int vtype;
    521		} cfs_lookup;
    522
    523
    524
    525  Description
    526    This call is made to determine the ViceFid and filetype of
    527    a directory entry.  The directory entry requested carries name 'name'
    528    and Venus will search the directory identified by cfs_lookup_in.VFid.
    529    The result may indicate that the name does not exist, or that
    530    difficulty was encountered in finding it (e.g. due to disconnection).
    531    If the result is zero, the field cfs_lookup_out.VFid contains the
    532    targets ViceFid and cfs_lookup_out.vtype the coda_vtype giving the
    533    type of object the name designates.
    534
    535  The name of the object is an 8 bit character string of maximum length
    536  CFS_MAXNAMLEN, currently set to 256 (including a 0 terminator.)
    537
    538  It is extremely important to realize that Venus bitwise ors the field
    539  cfs_lookup.vtype with CFS_NOCACHE to indicate that the object should
    540  not be put in the kernel name cache.
    541
    542  .. Note::
    543
    544     The type of the vtype is currently wrong.  It should be
    545     coda_vtype. Linux does not take note of CFS_NOCACHE.  It should.
    546
    547
    5484.5.  getattr
    549-------------
    550
    551
    552  Summary Get the attributes of a file.
    553
    554  Arguments
    555     in::
    556
    557		struct cfs_getattr_in {
    558		    ViceFid VFid;
    559		    struct coda_vattr attr; /* XXXXX */
    560		} cfs_getattr;
    561
    562
    563
    564     out::
    565
    566		struct cfs_getattr_out {
    567		    struct coda_vattr attr;
    568		} cfs_getattr;
    569
    570
    571
    572  Description
    573    This call returns the attributes of the file identified by fid.
    574
    575  Errors
    576    Errors can occur if the object with fid does not exist, is
    577    unaccessible or if the caller does not have permission to fetch
    578    attributes.
    579
    580  .. Note::
    581
    582     Many kernel FS drivers (Linux, NT and Windows 95) need to acquire
    583     the attributes as well as the Fid for the instantiation of an internal
    584     "inode" or "FileHandle".  A significant improvement in performance on
    585     such systems could be made by combining the lookup and getattr calls
    586     both at the Venus/kernel interaction level and at the RPC level.
    587
    588  The vattr structure included in the input arguments is superfluous and
    589  should be removed.
    590
    591
    5924.6.  setattr
    593-------------
    594
    595
    596  Summary
    597    Set the attributes of a file.
    598
    599  Arguments
    600     in::
    601
    602		struct cfs_setattr_in {
    603		    ViceFid VFid;
    604		    struct coda_vattr attr;
    605		} cfs_setattr;
    606
    607
    608
    609
    610     out
    611
    612	empty
    613
    614  Description
    615    The structure attr is filled with attributes to be changed
    616    in BSD style.  Attributes not to be changed are set to -1, apart from
    617    vtype which is set to VNON. Other are set to the value to be assigned.
    618    The only attributes which the FS driver may request to change are the
    619    mode, owner, groupid, atime, mtime and ctime.  The return value
    620    indicates success or failure.
    621
    622  Errors
    623    A variety of errors can occur.  The object may not exist, may
    624    be inaccessible, or permission may not be granted by Venus.
    625
    626
    6274.7.  access
    628------------
    629
    630
    631  Arguments
    632     in::
    633
    634		struct cfs_access_in {
    635		    ViceFid     VFid;
    636		    int flags;
    637		} cfs_access;
    638
    639
    640
    641     out
    642
    643	empty
    644
    645  Description
    646    Verify if access to the object identified by VFid for
    647    operations described by flags is permitted.  The result indicates if
    648    access will be granted.  It is important to remember that Coda uses
    649    ACLs to enforce protection and that ultimately the servers, not the
    650    clients enforce the security of the system.  The result of this call
    651    will depend on whether a token is held by the user.
    652
    653  Errors
    654    The object may not exist, or the ACL describing the protection
    655    may not be accessible.
    656
    657
    6584.8.  create
    659------------
    660
    661
    662  Summary
    663    Invoked to create a file
    664
    665  Arguments
    666     in::
    667
    668		struct cfs_create_in {
    669		    ViceFid VFid;
    670		    struct coda_vattr attr;
    671		    int excl;
    672		    int mode;
    673		    char        *name;          /* Place holder for data. */
    674		} cfs_create;
    675
    676
    677
    678
    679     out::
    680
    681		struct cfs_create_out {
    682		    ViceFid VFid;
    683		    struct coda_vattr attr;
    684		} cfs_create;
    685
    686
    687
    688  Description
    689    This upcall is invoked to request creation of a file.
    690    The file will be created in the directory identified by VFid, its name
    691    will be name, and the mode will be mode.  If excl is set an error will
    692    be returned if the file already exists.  If the size field in attr is
    693    set to zero the file will be truncated.  The uid and gid of the file
    694    are set by converting the CodaCred to a uid using a macro CRTOUID
    695    (this macro is platform dependent).  Upon success the VFid and
    696    attributes of the file are returned.  The Coda FS Driver will normally
    697    instantiate a vnode, inode or file handle at kernel level for the new
    698    object.
    699
    700
    701  Errors
    702    A variety of errors can occur. Permissions may be insufficient.
    703    If the object exists and is not a file the error EISDIR is returned
    704    under Unix.
    705
    706  .. Note::
    707
    708     The packing of parameters is very inefficient and appears to
    709     indicate confusion between the system call creat and the VFS operation
    710     create. The VFS operation create is only called to create new objects.
    711     This create call differs from the Unix one in that it is not invoked
    712     to return a file descriptor. The truncate and exclusive options,
    713     together with the mode, could simply be part of the mode as it is
    714     under Unix.  There should be no flags argument; this is used in open
    715     (2) to return a file descriptor for READ or WRITE mode.
    716
    717  The attributes of the directory should be returned too, since the size
    718  and mtime changed.
    719
    720
    7214.9.  mkdir
    722-----------
    723
    724
    725  Summary
    726    Create a new directory.
    727
    728  Arguments
    729     in::
    730
    731		struct cfs_mkdir_in {
    732		    ViceFid     VFid;
    733		    struct coda_vattr attr;
    734		    char        *name;          /* Place holder for data. */
    735		} cfs_mkdir;
    736
    737
    738
    739     out::
    740
    741		struct cfs_mkdir_out {
    742		    ViceFid VFid;
    743		    struct coda_vattr attr;
    744		} cfs_mkdir;
    745
    746
    747
    748
    749  Description
    750    This call is similar to create but creates a directory.
    751    Only the mode field in the input parameters is used for creation.
    752    Upon successful creation, the attr returned contains the attributes of
    753    the new directory.
    754
    755  Errors
    756    As for create.
    757
    758  .. Note::
    759
    760     The input parameter should be changed to mode instead of
    761     attributes.
    762
    763  The attributes of the parent should be returned since the size and
    764  mtime changes.
    765
    766
    7674.10.  link
    768-----------
    769
    770
    771  Summary
    772    Create a link to an existing file.
    773
    774  Arguments
    775     in::
    776
    777		struct cfs_link_in {
    778		    ViceFid sourceFid;          /* cnode to link *to* */
    779		    ViceFid destFid;            /* Directory in which to place link */
    780		    char        *tname;         /* Place holder for data. */
    781		} cfs_link;
    782
    783
    784
    785     out
    786
    787	empty
    788
    789  Description
    790    This call creates a link to the sourceFid in the directory
    791    identified by destFid with name tname.  The source must reside in the
    792    target's parent, i.e. the source must be have parent destFid, i.e. Coda
    793    does not support cross directory hard links.  Only the return value is
    794    relevant.  It indicates success or the type of failure.
    795
    796  Errors
    797    The usual errors can occur.
    798
    799
    8004.11.  symlink
    801--------------
    802
    803
    804  Summary
    805    create a symbolic link
    806
    807  Arguments
    808     in::
    809
    810		struct cfs_symlink_in {
    811		    ViceFid     VFid;          /* Directory to put symlink in */
    812		    char        *srcname;
    813		    struct coda_vattr attr;
    814		    char        *tname;
    815		} cfs_symlink;
    816
    817
    818
    819     out
    820
    821	none
    822
    823  Description
    824    Create a symbolic link. The link is to be placed in the
    825    directory identified by VFid and named tname.  It should point to the
    826    pathname srcname.  The attributes of the newly created object are to
    827    be set to attr.
    828
    829  .. Note::
    830
    831     The attributes of the target directory should be returned since
    832     its size changed.
    833
    834
    8354.12.  remove
    836-------------
    837
    838
    839  Summary
    840    Remove a file
    841
    842  Arguments
    843     in::
    844
    845		struct cfs_remove_in {
    846		    ViceFid     VFid;
    847		    char        *name;          /* Place holder for data. */
    848		} cfs_remove;
    849
    850
    851
    852     out
    853
    854	none
    855
    856  Description
    857    Remove file named cfs_remove_in.name in directory
    858    identified by   VFid.
    859
    860
    861  .. Note::
    862
    863     The attributes of the directory should be returned since its
    864     mtime and size may change.
    865
    866
    8674.13.  rmdir
    868------------
    869
    870
    871  Summary
    872    Remove a directory
    873
    874  Arguments
    875     in::
    876
    877		struct cfs_rmdir_in {
    878		    ViceFid     VFid;
    879		    char        *name;          /* Place holder for data. */
    880		} cfs_rmdir;
    881
    882
    883
    884     out
    885
    886	none
    887
    888  Description
    889    Remove the directory with name 'name' from the directory
    890    identified by VFid.
    891
    892  .. Note:: The attributes of the parent directory should be returned since
    893	    its mtime and size may change.
    894
    895
    8964.14.  readlink
    897---------------
    898
    899
    900  Summary
    901    Read the value of a symbolic link.
    902
    903  Arguments
    904     in::
    905
    906		struct cfs_readlink_in {
    907		    ViceFid VFid;
    908		} cfs_readlink;
    909
    910
    911
    912     out::
    913
    914		struct cfs_readlink_out {
    915		    int count;
    916		    caddr_t     data;           /* Place holder for data. */
    917		} cfs_readlink;
    918
    919
    920
    921  Description
    922    This routine reads the contents of symbolic link
    923    identified by VFid into the buffer data.  The buffer data must be able
    924    to hold any name up to CFS_MAXNAMLEN (PATH or NAM??).
    925
    926  Errors
    927    No unusual errors.
    928
    929
    9304.15.  open
    931-----------
    932
    933
    934  Summary
    935    Open a file.
    936
    937  Arguments
    938     in::
    939
    940		struct cfs_open_in {
    941		    ViceFid     VFid;
    942		    int flags;
    943		} cfs_open;
    944
    945
    946
    947     out::
    948
    949		struct cfs_open_out {
    950		    dev_t       dev;
    951		    ino_t       inode;
    952		} cfs_open;
    953
    954
    955
    956  Description
    957    This request asks Venus to place the file identified by
    958    VFid in its cache and to note that the calling process wishes to open
    959    it with flags as in open(2).  The return value to the kernel differs
    960    for Unix and Windows systems.  For Unix systems the Coda FS Driver is
    961    informed of the device and inode number of the container file in the
    962    fields dev and inode.  For Windows the path of the container file is
    963    returned to the kernel.
    964
    965
    966  .. Note::
    967
    968     Currently the cfs_open_out structure is not properly adapted to
    969     deal with the Windows case.  It might be best to implement two
    970     upcalls, one to open aiming at a container file name, the other at a
    971     container file inode.
    972
    973
    9744.16.  close
    975------------
    976
    977
    978  Summary
    979    Close a file, update it on the servers.
    980
    981  Arguments
    982     in::
    983
    984		struct cfs_close_in {
    985		    ViceFid     VFid;
    986		    int flags;
    987		} cfs_close;
    988
    989
    990
    991     out
    992
    993	none
    994
    995  Description
    996    Close the file identified by VFid.
    997
    998  .. Note::
    999
   1000     The flags argument is bogus and not used.  However, Venus' code
   1001     has room to deal with an execp input field, probably this field should
   1002     be used to inform Venus that the file was closed but is still memory
   1003     mapped for execution.  There are comments about fetching versus not
   1004     fetching the data in Venus vproc_vfscalls.  This seems silly.  If a
   1005     file is being closed, the data in the container file is to be the new
   1006     data.  Here again the execp flag might be in play to create confusion:
   1007     currently Venus might think a file can be flushed from the cache when
   1008     it is still memory mapped.  This needs to be understood.
   1009
   1010
   10114.17.  ioctl
   1012------------
   1013
   1014
   1015  Summary
   1016    Do an ioctl on a file. This includes the pioctl interface.
   1017
   1018  Arguments
   1019     in::
   1020
   1021		struct cfs_ioctl_in {
   1022		    ViceFid VFid;
   1023		    int cmd;
   1024		    int len;
   1025		    int rwflag;
   1026		    char *data;                 /* Place holder for data. */
   1027		} cfs_ioctl;
   1028
   1029
   1030
   1031     out::
   1032
   1033
   1034		struct cfs_ioctl_out {
   1035		    int len;
   1036		    caddr_t     data;           /* Place holder for data. */
   1037		} cfs_ioctl;
   1038
   1039
   1040
   1041  Description
   1042    Do an ioctl operation on a file.  The command, len and
   1043    data arguments are filled as usual.  flags is not used by Venus.
   1044
   1045  .. Note::
   1046
   1047     Another bogus parameter.  flags is not used.  What is the
   1048     business about PREFETCHING in the Venus code?
   1049
   1050
   1051
   10524.18.  rename
   1053-------------
   1054
   1055
   1056  Summary
   1057    Rename a fid.
   1058
   1059  Arguments
   1060     in::
   1061
   1062		struct cfs_rename_in {
   1063		    ViceFid     sourceFid;
   1064		    char        *srcname;
   1065		    ViceFid destFid;
   1066		    char        *destname;
   1067		} cfs_rename;
   1068
   1069
   1070
   1071     out
   1072
   1073	none
   1074
   1075  Description
   1076    Rename the object with name srcname in directory
   1077    sourceFid to destname in destFid.   It is important that the names
   1078    srcname and destname are 0 terminated strings.  Strings in Unix
   1079    kernels are not always null terminated.
   1080
   1081
   10824.19.  readdir
   1083--------------
   1084
   1085
   1086  Summary
   1087    Read directory entries.
   1088
   1089  Arguments
   1090     in::
   1091
   1092		struct cfs_readdir_in {
   1093		    ViceFid     VFid;
   1094		    int count;
   1095		    int offset;
   1096		} cfs_readdir;
   1097
   1098
   1099
   1100
   1101     out::
   1102
   1103		struct cfs_readdir_out {
   1104		    int size;
   1105		    caddr_t     data;           /* Place holder for data. */
   1106		} cfs_readdir;
   1107
   1108
   1109
   1110  Description
   1111    Read directory entries from VFid starting at offset and
   1112    read at most count bytes.  Returns the data in data and returns
   1113    the size in size.
   1114
   1115
   1116  .. Note::
   1117
   1118     This call is not used.  Readdir operations exploit container
   1119     files.  We will re-evaluate this during the directory revamp which is
   1120     about to take place.
   1121
   1122
   11234.20.  vget
   1124-----------
   1125
   1126
   1127  Summary
   1128    instructs Venus to do an FSDB->Get.
   1129
   1130  Arguments
   1131     in::
   1132
   1133		struct cfs_vget_in {
   1134		    ViceFid VFid;
   1135		} cfs_vget;
   1136
   1137
   1138
   1139     out::
   1140
   1141		struct cfs_vget_out {
   1142		    ViceFid VFid;
   1143		    int vtype;
   1144		} cfs_vget;
   1145
   1146
   1147
   1148  Description
   1149    This upcall asks Venus to do a get operation on an fsobj
   1150    labelled by VFid.
   1151
   1152  .. Note::
   1153
   1154     This operation is not used.  However, it is extremely useful
   1155     since it can be used to deal with read/write memory mapped files.
   1156     These can be "pinned" in the Venus cache using vget and released with
   1157     inactive.
   1158
   1159
   11604.21.  fsync
   1161------------
   1162
   1163
   1164  Summary
   1165    Tell Venus to update the RVM attributes of a file.
   1166
   1167  Arguments
   1168     in::
   1169
   1170		struct cfs_fsync_in {
   1171		    ViceFid VFid;
   1172		} cfs_fsync;
   1173
   1174
   1175
   1176     out
   1177
   1178	none
   1179
   1180  Description
   1181    Ask Venus to update RVM attributes of object VFid. This
   1182    should be called as part of kernel level fsync type calls.  The
   1183    result indicates if the syncing was successful.
   1184
   1185  .. Note:: Linux does not implement this call. It should.
   1186
   1187
   11884.22.  inactive
   1189---------------
   1190
   1191
   1192  Summary
   1193    Tell Venus a vnode is no longer in use.
   1194
   1195  Arguments
   1196     in::
   1197
   1198		struct cfs_inactive_in {
   1199		    ViceFid VFid;
   1200		} cfs_inactive;
   1201
   1202
   1203
   1204     out
   1205
   1206	none
   1207
   1208  Description
   1209    This operation returns EOPNOTSUPP.
   1210
   1211  .. Note:: This should perhaps be removed.
   1212
   1213
   12144.23.  rdwr
   1215-----------
   1216
   1217
   1218  Summary
   1219    Read or write from a file
   1220
   1221  Arguments
   1222     in::
   1223
   1224		struct cfs_rdwr_in {
   1225		    ViceFid     VFid;
   1226		    int rwflag;
   1227		    int count;
   1228		    int offset;
   1229		    int ioflag;
   1230		    caddr_t     data;           /* Place holder for data. */
   1231		} cfs_rdwr;
   1232
   1233
   1234
   1235
   1236     out::
   1237
   1238		struct cfs_rdwr_out {
   1239		    int rwflag;
   1240		    int count;
   1241		    caddr_t     data;   /* Place holder for data. */
   1242		} cfs_rdwr;
   1243
   1244
   1245
   1246  Description
   1247    This upcall asks Venus to read or write from a file.
   1248
   1249
   1250  .. Note::
   1251
   1252    It should be removed since it is against the Coda philosophy that
   1253    read/write operations never reach Venus.  I have been told the
   1254    operation does not work.  It is not currently used.
   1255
   1256
   1257
   12584.24.  odymount
   1259---------------
   1260
   1261
   1262  Summary
   1263    Allows mounting multiple Coda "filesystems" on one Unix mount point.
   1264
   1265  Arguments
   1266     in::
   1267
   1268		struct ody_mount_in {
   1269		    char        *name;          /* Place holder for data. */
   1270		} ody_mount;
   1271
   1272
   1273
   1274     out::
   1275
   1276		struct ody_mount_out {
   1277		    ViceFid VFid;
   1278		} ody_mount;
   1279
   1280
   1281
   1282  Description
   1283    Asks Venus to return the rootfid of a Coda system named
   1284    name.  The fid is returned in VFid.
   1285
   1286  .. Note::
   1287
   1288     This call was used by David for dynamic sets.  It should be
   1289     removed since it causes a jungle of pointers in the VFS mounting area.
   1290     It is not used by Coda proper.  Call is not implemented by Venus.
   1291
   1292
   12934.25.  ody_lookup
   1294-----------------
   1295
   1296
   1297  Summary
   1298    Looks up something.
   1299
   1300  Arguments
   1301     in
   1302
   1303	irrelevant
   1304
   1305
   1306     out
   1307
   1308	irrelevant
   1309
   1310
   1311  .. Note:: Gut it. Call is not implemented by Venus.
   1312
   1313
   13144.26.  ody_expand
   1315-----------------
   1316
   1317
   1318  Summary
   1319    expands something in a dynamic set.
   1320
   1321  Arguments
   1322     in
   1323
   1324	irrelevant
   1325
   1326     out
   1327
   1328	irrelevant
   1329
   1330  .. Note:: Gut it. Call is not implemented by Venus.
   1331
   1332
   13334.27.  prefetch
   1334---------------
   1335
   1336
   1337  Summary
   1338    Prefetch a dynamic set.
   1339
   1340  Arguments
   1341
   1342     in
   1343
   1344	Not documented.
   1345
   1346     out
   1347
   1348	Not documented.
   1349
   1350  Description
   1351    Venus worker.cc has support for this call, although it is
   1352    noted that it doesn't work.  Not surprising, since the kernel does not
   1353    have support for it. (ODY_PREFETCH is not a defined operation).
   1354
   1355
   1356  .. Note:: Gut it. It isn't working and isn't used by Coda.
   1357
   1358
   1359
   13604.28.  signal
   1361-------------
   1362
   1363
   1364  Summary
   1365    Send Venus a signal about an upcall.
   1366
   1367  Arguments
   1368     in
   1369
   1370	none
   1371
   1372     out
   1373
   1374	not applicable.
   1375
   1376  Description
   1377    This is an out-of-band upcall to Venus to inform Venus
   1378    that the calling process received a signal after Venus read the
   1379    message from the input queue.  Venus is supposed to clean up the
   1380    operation.
   1381
   1382  Errors
   1383    No reply is given.
   1384
   1385  .. Note::
   1386
   1387     We need to better understand what Venus needs to clean up and if
   1388     it is doing this correctly.  Also we need to handle multiple upcall
   1389     per system call situations correctly.  It would be important to know
   1390     what state changes in Venus take place after an upcall for which the
   1391     kernel is responsible for notifying Venus to clean up (e.g. open
   1392     definitely is such a state change, but many others are maybe not).
   1393
   1394
   13955.  The minicache and downcalls
   1396===============================
   1397
   1398
   1399  The Coda FS Driver can cache results of lookup and access upcalls, to
   1400  limit the frequency of upcalls.  Upcalls carry a price since a process
   1401  context switch needs to take place.  The counterpart of caching the
   1402  information is that Venus will notify the FS Driver that cached
   1403  entries must be flushed or renamed.
   1404
   1405  The kernel code generally has to maintain a structure which links the
   1406  internal file handles (called vnodes in BSD, inodes in Linux and
   1407  FileHandles in Windows) with the ViceFid's which Venus maintains.  The
   1408  reason is that frequent translations back and forth are needed in
   1409  order to make upcalls and use the results of upcalls.  Such linking
   1410  objects are called cnodes.
   1411
   1412  The current minicache implementations have cache entries which record
   1413  the following:
   1414
   1415  1. the name of the file
   1416
   1417  2. the cnode of the directory containing the object
   1418
   1419  3. a list of CodaCred's for which the lookup is permitted.
   1420
   1421  4. the cnode of the object
   1422
   1423  The lookup call in the Coda FS Driver may request the cnode of the
   1424  desired object from the cache, by passing its name, directory and the
   1425  CodaCred's of the caller.  The cache will return the cnode or indicate
   1426  that it cannot be found.  The Coda FS Driver must be careful to
   1427  invalidate cache entries when it modifies or removes objects.
   1428
   1429  When Venus obtains information that indicates that cache entries are
   1430  no longer valid, it will make a downcall to the kernel.  Downcalls are
   1431  intercepted by the Coda FS Driver and lead to cache invalidations of
   1432  the kind described below.  The Coda FS Driver does not return an error
   1433  unless the downcall data could not be read into kernel memory.
   1434
   1435
   14365.1.  INVALIDATE
   1437----------------
   1438
   1439
   1440  No information is available on this call.
   1441
   1442
   14435.2.  FLUSH
   1444-----------
   1445
   1446
   1447
   1448  Arguments
   1449    None
   1450
   1451  Summary
   1452    Flush the name cache entirely.
   1453
   1454  Description
   1455    Venus issues this call upon startup and when it dies. This
   1456    is to prevent stale cache information being held.  Some operating
   1457    systems allow the kernel name cache to be switched off dynamically.
   1458    When this is done, this downcall is made.
   1459
   1460
   14615.3.  PURGEUSER
   1462---------------
   1463
   1464
   1465  Arguments
   1466    ::
   1467
   1468	  struct cfs_purgeuser_out {/* CFS_PURGEUSER is a venus->kernel call */
   1469	      struct CodaCred cred;
   1470	  } cfs_purgeuser;
   1471
   1472
   1473
   1474  Description
   1475    Remove all entries in the cache carrying the Cred.  This
   1476    call is issued when tokens for a user expire or are flushed.
   1477
   1478
   14795.4.  ZAPFILE
   1480-------------
   1481
   1482
   1483  Arguments
   1484    ::
   1485
   1486	  struct cfs_zapfile_out {  /* CFS_ZAPFILE is a venus->kernel call */
   1487	      ViceFid CodaFid;
   1488	  } cfs_zapfile;
   1489
   1490
   1491
   1492  Description
   1493    Remove all entries which have the (dir vnode, name) pair.
   1494    This is issued as a result of an invalidation of cached attributes of
   1495    a vnode.
   1496
   1497  .. Note::
   1498
   1499     Call is not named correctly in NetBSD and Mach.  The minicache
   1500     zapfile routine takes different arguments. Linux does not implement
   1501     the invalidation of attributes correctly.
   1502
   1503
   1504
   15055.5.  ZAPDIR
   1506------------
   1507
   1508
   1509  Arguments
   1510    ::
   1511
   1512	  struct cfs_zapdir_out {   /* CFS_ZAPDIR is a venus->kernel call */
   1513	      ViceFid CodaFid;
   1514	  } cfs_zapdir;
   1515
   1516
   1517
   1518  Description
   1519    Remove all entries in the cache lying in a directory
   1520    CodaFid, and all children of this directory. This call is issued when
   1521    Venus receives a callback on the directory.
   1522
   1523
   15245.6.  ZAPVNODE
   1525--------------
   1526
   1527
   1528
   1529  Arguments
   1530    ::
   1531
   1532	  struct cfs_zapvnode_out { /* CFS_ZAPVNODE is a venus->kernel call */
   1533	      struct CodaCred cred;
   1534	      ViceFid VFid;
   1535	  } cfs_zapvnode;
   1536
   1537
   1538
   1539  Description
   1540    Remove all entries in the cache carrying the cred and VFid
   1541    as in the arguments. This downcall is probably never issued.
   1542
   1543
   15445.7.  PURGEFID
   1545--------------
   1546
   1547
   1548  Arguments
   1549    ::
   1550
   1551	  struct cfs_purgefid_out { /* CFS_PURGEFID is a venus->kernel call */
   1552	      ViceFid CodaFid;
   1553	  } cfs_purgefid;
   1554
   1555
   1556
   1557  Description
   1558    Flush the attribute for the file. If it is a dir (odd
   1559    vnode), purge its children from the namecache and remove the file from the
   1560    namecache.
   1561
   1562
   1563
   15645.8.  REPLACE
   1565-------------
   1566
   1567
   1568  Summary
   1569    Replace the Fid's for a collection of names.
   1570
   1571  Arguments
   1572    ::
   1573
   1574	  struct cfs_replace_out { /* cfs_replace is a venus->kernel call */
   1575	      ViceFid NewFid;
   1576	      ViceFid OldFid;
   1577	  } cfs_replace;
   1578
   1579
   1580
   1581  Description
   1582    This routine replaces a ViceFid in the name cache with
   1583    another.  It is added to allow Venus during reintegration to replace
   1584    locally allocated temp fids while disconnected with global fids even
   1585    when the reference counts on those fids are not zero.
   1586
   1587
   15886.  Initialization and cleanup
   1589==============================
   1590
   1591
   1592  This section gives brief hints as to desirable features for the Coda
   1593  FS Driver at startup and upon shutdown or Venus failures.  Before
   1594  entering the discussion it is useful to repeat that the Coda FS Driver
   1595  maintains the following data:
   1596
   1597
   1598  1. message queues
   1599
   1600  2. cnodes
   1601
   1602  3. name cache entries
   1603
   1604     The name cache entries are entirely private to the driver, so they
   1605     can easily be manipulated.   The message queues will generally have
   1606     clear points of initialization and destruction.  The cnodes are
   1607     much more delicate.  User processes hold reference counts in Coda
   1608     filesystems and it can be difficult to clean up the cnodes.
   1609
   1610  It can expect requests through:
   1611
   1612  1. the message subsystem
   1613
   1614  2. the VFS layer
   1615
   1616  3. pioctl interface
   1617
   1618     Currently the pioctl passes through the VFS for Coda so we can
   1619     treat these similarly.
   1620
   1621
   16226.1.  Requirements
   1623------------------
   1624
   1625
   1626  The following requirements should be accommodated:
   1627
   1628  1. The message queues should have open and close routines.  On Unix
   1629     the opening of the character devices are such routines.
   1630
   1631    -  Before opening, no messages can be placed.
   1632
   1633    -  Opening will remove any old messages still pending.
   1634
   1635    -  Close will notify any sleeping processes that their upcall cannot
   1636       be completed.
   1637
   1638    -  Close will free all memory allocated by the message queues.
   1639
   1640
   1641  2. At open the namecache shall be initialized to empty state.
   1642
   1643  3. Before the message queues are open, all VFS operations will fail.
   1644     Fortunately this can be achieved by making sure than mounting the
   1645     Coda filesystem cannot succeed before opening.
   1646
   1647  4. After closing of the queues, no VFS operations can succeed.  Here
   1648     one needs to be careful, since a few operations (lookup,
   1649     read/write, readdir) can proceed without upcalls.  These must be
   1650     explicitly blocked.
   1651
   1652  5. Upon closing the namecache shall be flushed and disabled.
   1653
   1654  6. All memory held by cnodes can be freed without relying on upcalls.
   1655
   1656  7. Unmounting the file system can be done without relying on upcalls.
   1657
   1658  8. Mounting the Coda filesystem should fail gracefully if Venus cannot
   1659     get the rootfid or the attributes of the rootfid.  The latter is
   1660     best implemented by Venus fetching these objects before attempting
   1661     to mount.
   1662
   1663  .. Note::
   1664
   1665     NetBSD in particular but also Linux have not implemented the
   1666     above requirements fully.  For smooth operation this needs to be
   1667     corrected.
   1668
   1669
   1670