These modes were not documented in the manpage, the autodetect
logic was reversed (only terminals with baud < 1200 would get the fast
flag) and even the source was confused claiming this fast setting was
for terminals with baud > 300.

The only thing that changes is the automatic short range scan output
down when entering a new sector. Now the full report is shown always
but can still be somewhat customized.

By default, install command preserves mtime, and files in the source tree
always have older mtime than a file created by touch command, in this case
${.OBJDIR}/openssl/.dummy, even though it's created earlier by dependency.
Since .dummy is newer, header files get created in objdir at install target
and that requires write permission on ${.OBJDIR}.

The only bug that could not be resolved by the previous commit is related
to the use of dynamic buffer sizing for the buffer that straddles the
EOF of the file. For example, if a file is 32768+4127 bytes then the
second buffer cache buffer would have a size of 4127 bytes instead of
32768 bytes. Because the EOF point can move around and NFS does not
keep good track of it buffers with weird sizes could build up in the
system and interfere with operations against backing VM pages.

In particular truncations followed by seek-write extensions would
interfere with mmap()'s areas around the original (now non-applicable)
truncation point.

It was not possible to fix this bug while still keeping the dynamic
buffer sizing, so this patch converts NFS's buffer cache operations
to use fixed-sized buffers in all cases. This leads to more wasted
memory when dealing with small files and further optimizations may be
attempted in the future, but it seems to solve issues with BIO/VM
interactions.

* Fsx now survives an overnight pass.

* Buildworld now survives multiple passes when using a writable NFS /usr/obj.

* Fix umount sequencing. Sometimes the rxthread would get into a
reconnect loop and not exit.

* Remove vfs_setdirty(), it is no longer used.
Remove vfs_page_set_valid(), it is no longer used.
Remove vfs_bio_set_valid(), it is no longer used.

* When acquiring a buffer with getblk() whos size differs from the
buffer already cached, no longer destroy the VM pages backing
the buffer after completing the write. Instead just release
the buffer so a new, larger one can be constructed.

NFS buffers which straddle file EOF can remain cached after the
file has been extended via seek/write or ftruncate, and their
underlying VM pages may become dirty via mmap. If the buffer
is acquired later the underlying VM pages beyond the buffer's
original b_bcount size must be retained, not destroyed.

* No longer try to clear the pmap modified bit from misc vm_page_*()
functions. In cases where we desire the pmap modified bit to be
clear, it should *already* have been cleared in the run-up to the
I/O. Clearing it later may cause the buffer cache to lose track
of the fact that underlying VM pages may have been modified again.

NFS buffers use b_dirtyoff/b_dirtyend to determine what to actually
write. If the VM page is modified again the current write operation
will not cover all the dirty parts of the buffer and another write
will have to be issued. Clearing the pmap modified bit at later
stages did not properly track changes in b_dirtyoff/b_dirtyend and
resulted in dirty data being lost.

In addition, this function now detects the case where a buffer has
B_NEEDCOMMIT set but the underlying VM page is dirty. This
function necessarily only clears the dirty bits associated
with the buffer because buffer sizes are not necessarily page aligned,
which is different from clearing ALL the dirty bits as the putpages
code is able to do. So the B_NEEDCOMMIT test is only against those
dirty bits associated with the buffer. If this is found to be the
case the B_NEEDCOMMIT flag is cleared.

This fixes a race where VM pages backing a dirty buffer which has gone
through the phase-1 commit are dirtied via a mmap, and NFS then goes
through with the phase-2 commit and throws the data away when it really
needed to go back and do another phase-1 commit.

* In vnode_generic_put_pages() no longer clear the VM page dirty bits
associated with bits of a file which extend past file EOF in the
page straddling the EOF. We used to do this with the idea that
we would only clear the dirty bits up to the file EOF later on
in the I/O completion code.

However, this was too fragile. If a page ended up with any dirty
bits left set it would remain endless dirty and be reflushed forever.

We now clear the dirty bits for the entire page after a putpages
operation completes without error, and don't bother doing it
prior to I/O initiation.

* Call nfs_meta_setsize() for both seek+write extensions (holes) and for
ftruncate extensions (holes).

nfs_meta_setsize() now deterministically adjusts the size of the buffer
that was straddling the PRIOR EOF point, fixing an issue where
write-extending a file to near the end of a nfs buffer boundary (32K),
then seek-write extending it further by creating a hole, then
mmap()ing the end of the first chunk and modifying data past the
original write-extend point... would lose the extra data because
the original buffer was still intact and was still sized for the
original EOF. This was difficult to reproduce because it only occurred
if all the dirty bits got cleared when the original buffer is flushed,
meaning the original write-extend point had to be within 511 bytes of
the end of a 32K boundary.

* VOP_ACCESS() is used for more then just access(). UFS and other
filesystems (but not HAMMER) were calling it in the open/create/rename/
unlink paths. The uid/gid must be used in those cases, not the ruid/rgid.

Add a VOP_EACCESS() macro which passes the appropriate flag to use the
uid/gid instead of the ruid/rgid, and adjust the filesystems to use this
macro.

* General getpages operations must clear dirty bits non-inclusive of
the end of the range. A read which partially overlaps dirty VM
pages shouldn't happen in the first place but if it were to happen
we don't want to lose the dirty status on the DEV_BSIZE'd chunk
straddling the end of the read.

* General truncation support. Replace previous fix with a call to
a new inline, vm_page_clear_dirty_beg_nonincl(). Similar to
the getpages() issue, we do not want to lose the dirty status
on the DEV_BSIZE'd chunk straddling the beginning of a truncation.

(side note: Only effecs NFS as all other filesystems DEV_BSIZE-align
their operations, but a good general fix in anycase).

* Short reads were not causing the remainder of the buffer to be
zero'd out in all cases, causing the fsx filesystem test to fail.

* An EOF condition was sometimes improperly reporting a non-zero
bp->b_resid. Race against the server where the client's idea of
the file size differs from the server could result in a non-zero
bp->b_resid after a BIO.

Zero out the remaining space and and set bp->b_resid to 0. The
NFS client code always specifies buffers within the bounds of
the file.

* When truncating a file to non-zero length, if the filesystem calls
vnode_pager_setsize() with a truncation offset that is not a
multiple of DEV_BSIZE vnode_pager_setsize() will improperly clear
the dirty bit for the overlapping DEV_BSIZE'd block in the VM page
straddling the truncation point.

This only effects NFS. The fsx filesystem test was failing due to
a lost dirty page after a truncation.

0 - full fsync semantics
1 - asynchronous
2 - synchronous fsync on close if fsync called prior to close
3 - asynchronous fsync on close if fsync called prior to close
4 - ignore fsync (30-second system sync takes care of it)

* This is likely a temporary measure until HAMMER gets a REDO log.
It is mainly to facilitate testing and to reduce the pounding
disks take from pkgsrc bulk builds (pkg_add seems to insist on
calling fsync() a lot for no reason).

When unmarshalling a request, the server constructs a ucred
structure (nfsrv_descript.nd_cr) from the credential data in the
RPC. It initializes only the effective uid and gid and leaves
the real and saved uid/gid unitialized. This effectively sets
the real/effective ids to root because nd_cr is first
bzero()'ed.

As a consequence, now that accept(2) checks real uid/gid, all
accept calls to NFS files incorrectly succeed.

Fix this by initializing the real and saved uid/gid in nd_cr to
the same values as the real uid/gid (only the real uid/gid are
RPC'ed to the server).

NOTE: accept(2) and faccessat(2) to NFS files are still broken
in part because the client sends the effective uid/gid to the
server. I'll fix this once I've groked the uid magic in the NFS
code.