This patch changes the prefetch API so that file systems must now
provide a set of block numbers, rather than a set of buffers. The
result is a leaner and more well-defined API; linear computation of
the range of blocks to prefetch; duplicates no longer interfering
with the prefetch process; guaranteed inclusion of the block needed
next into the prefetch range; and, limits and policy decisions better
established by libminixfs now actually being moved into libminixfs.
Change-Id: I7e44daf2d2d164bc5e2f1473ad717f3ff0f0a77f
- The lmfs_get_block*(3) API calls may now return an error. The idea
is to encourage a next generation of file system services to do a
better job at dealing with block read errors than the MFS-derived
implementations do. These existing file systems have been changed
to panic immediately upon getting a block read error, in order to
let unchecked errors cause corruption. Note that libbdev already
retries failing I/O operations a few times first.
- The libminixfs block device I/O module (bio.c) now deals properly
with end-of-file conditions on block devices. Since a device or
partition size may not be a multiple of the root file system's block
size, support for partial block retrival has been added, with a new
internal lmfs_get_partial_block(3) call. A new test program,
test85, tests the new handling of EOF conditions when reading,
writing, and memory-mapping a block device.
Change-Id: I05e35b6b8851488328a2679da635ebba0c6d08ce
This patch changes the libminixfs API and implementation such that the
library is at all times aware of how many total and used blocks there
are in the file system. This removes the last upcall of libminixfs
into file systems (fs_blockstats). In the process, make this part of
the libminixfs API a little prettier and more robust. Change file
systems accordingly. Since this change only adds to MFS being unable
to deal with zones and blocks having different sizes, fail to mount
such file systems immediately rather than triggering an assert later.
Change-Id: I078e589c7e1be1fa691cf391bf5dfddd1baf2c86
With this change, the lmfs_get_block*(3) functions allow the caller to
specify that it only wants the block if it is in the cache or the
secondary VM cache. If the block is not found there, the functions
return NULL. Previously, the PREFETCH method would be used to this
end instead, which was both abuse in name and less efficient.
Change-Id: Ieb5a15b67fa25d2008a8eeef9d126ac908fc2395
When VM asks a file system to provide a block to satisfy a page fault
on a file memory mapping, the file system previously had no way to
inform VM that the block is a hole, since there is no corresponding
block on the underlying device. To work around this, MFS and ext2
would actually allocate a block for the hole when asked by VM, which
not only defeats the point of holes in the first place, but also does
not work on read-only file systems. With this patch, a new libminixfs
call allows the file system to inform VM about holes. This issue does
raise the question as to whether the VM cache is using the right data
structures, since there are now two places where we have to fake a
device offset. This will have to be revisited in the future.
The patch changes file systems accordingly, and adds a test to test74.
Change-Id: Ib537d56b3f30a8eb05bc1f63c92b5c7428d18f4c
This patch employs one solution to resolve two independent but related
issues. Both issues are the result of one fundamental aspect of the
way VM's memory mapping works: VM uses its cache to map in blocks for
memory-mapped file regions, and for blocks already in the VM cache, VM
does not go to the file system before mapping them in. To preserve
consistency between the FS and VM caches, VM relies on being informed
about all updates to file contents through the block cache. The two
issues are both the result of VM not being properly informed about
such updates:
1. Once a file system provides libminixfs with an inode association
(inode number + inode offset) for a disk block, this association
is not broken until a new inode association is provided for it.
If a block is freed and reallocated as a metadata (non-inode)
block, its old association is maintained, and may be supplied to
VM's secondary cache. Due to reuse of inodes, it is possible
that the same inode association becomes valid for an actual file
block again. In that case, when that new file is memory-mapped,
under certain circumstances, VM may end up using the metadata
block to satisfy a page fault on the file, due to the stale inode
association. The result is a corrupted memory mapping, with the
application seeing data other than the current file contents
mapped in at the file block.
2. When a hole is created in a file, the underlying block is freed
from the device, but VM is not informed of this update, and thus,
if VM's cache contains the block with its previous inode
association, this block will remain there. As a result, if an
application subsequently memory-maps the file, VM will map in the
old block at the position of the hole, rather than an all-zeroes
block. Thus, again, the result is a corrupted memory mapping.
This patch resolves both issues by making the file system inform the
minixfs library about blocks being freed, so that libminixfs can
break the inode association for that block, both in its own cache and
in the VM cache. Since libminixfs does not know whether VM has the
block in its cache or not, it makes a call to VM for each block being
freed. Thus, this change introduces more calls to VM, but it solves
the correctness issues at hand; optimizations may be introduced
later. On the upside, all freed blocks are now marked as clean,
which should result in fewer blocks being written back to the device,
and the blocks are removed from the caches entirely, which should
result in slightly better cache usage.
This patch is necessary but not sufficient to resolve the situation
with respect to memory mapping of file holes in general. Therefore,
this patch extends test 74 with a (rather particular but effective)
test for the first issue, but not yet with a test for the second one.
This fixes#90.
Change-Id: Iad8b134d2f88a884f15d3fc303e463280749c467
There are currently no devices out there that require this change.
The change is merely needed to support subsequent changes.
Change-Id: I64214c5f46ff4a2260815d15c15e4a17709b9036
Previously, there was a tiny chance that tickdelay(3) would return
early or that it would fail to reinstate a previous alarm.
- sys_setalarm(2) now returns TMR_NEVER instead of 0 for the time
left if no previous alarm was set;
- sys_setalarm(2) now also returns the current time, to allow the
caller to determine whether it got an alarm notification for the
alarm it set or for a previous alarm that has just gone off;
- tickdelay(3) now makes use of these facilities.
Change-Id: Id4f8fe19a61ca8574f43131964e6f0317f613f49
Extended by David van Moolenbroek to continue using static buffers
for short inode names, so as to prevent important file system
services such as procfs from running out of memory at runtime.
Change-Id: I6f841741ee9944fc87dbdb78b5cdaa2abee9da76
Previously, procfs would retrieve the rproc and rprocpub tables from
RS in two separate calls. This allowed for a race condition where the
tables could change in between the calls, resulting in a panic in
procfs under certain circumstances. RS now implements a new method
for getsysinfo that allows the retrieval of both tables at once.
Change-Id: I5ec22d25898361270c90e805a43fc6d76ad9e29d
This patch adds support for Unix98 pseudo terminals, that is,
posix_openpt(3), grantpt(3), unlockpt(3), /dev/ptmx, and /dev/pts/.
The latter is implemented with a new pseudo file system, PTYFS.
In effect, this patch adds secure support for unprivileged pseudo
terminal allocation, allowing programs such as tmux(1) to be used by
non-root users as well. Test77 has been extended with new tests, and
no longer needs to run as root.
The new functionality is optional. To revert to the old behavior,
remove the "ptyfs" entry from /etc/fstab.
Technical nodes:
o The reason for not implementing the NetBSD /dev/ptm approach is that
implementing the corresponding ioctl (TIOCPTMGET) would require
adding a number of extremely hairy exceptions to VFS, including the
PTY driver having to create new file descriptors for its own device
nodes.
o PTYFS is required for Unix98 PTYs in order to avoid that the PTY
driver has to be aware of old-style PTY naming schemes and even has
to call chmod(2) on a disk-backed file system. PTY cannot be its
own PTYFS since a character driver may currently not also be a file
system. However, PTYFS may be subsumed into a DEVFS in the future.
o The Unix98 PTY behavior differs somewhat from NetBSD's, in that
slave nodes are created on ptyfs only upon the first call to
grantpt(3). This approach obviates the need to revoke access as
part of the grantpt(3) call.
o Shutting down PTY may leave slave nodes on PTYFS, but once PTY is
restarted, these leftover slave nodes will be removed before they
create a security risk. Unmounting PTYFS will make existing PTY
slaves permanently unavailable, and absence of PTYFS will block
allocation of new Unix98 PTYs until PTYFS is (re)mounted.
Change-Id: I822b43ba32707c8815fd0f7d5bb7a438f51421c1
Previously, services would obtain the user ID of "service" through
getpwnam(3). While this approach is conceptually better, it also
imposes linking against libc which in turn causes problems with
printf(3), which already led to PFS no longer dropping privileges at
all. For now, we hardcode SERVICE_UID and use that instead.
In the future, two changes should allow removal of SERVICE_UID again:
- "service edit" should cause RS to request that a service (such as
PFS) drop privileges through SEF, using the user ID resolved by
service(8), or something similar;
- a future devfs should make it possible for inet to start without
root privileges altogether.
Change-Id: Ie02a1e888cde325806fc0ae76909943ac42c9b96
The new implementation of this library provides abstractions for
network drivers, and should be used for all network drivers from now
on. It provides the following functionality:
- a function call table abstraction, hiding the details of the
datalink protocol with simple parameters;
- a state machine for sending and receiving packets, freeing the
actual driver from keeping track of pending requests;
- an abstraction for copying data from and to the network driver,
freeing the actual driver from dealing with I/O vectors while at
the same time providing a copy implementation which is more
efficient than most current driver implementations;
- a generalized implementation of zero-copy port-based I/O;
- a clearer set of policies and defaults.
While the concept is very similar to lib{block,char,fs,input}driver,
one main difference is that libnetdriver now also takes care of SEF
initialization, mainly so that aspects such as recovery policies and
live-update aspects can be changed for all network drivers in a
single place. As always, for the case that the provided message loop
is too restrictive, a set of more low-level message processing
functions is provided.
The netdriver API has been designed so as to allow alleviation of one
current protocol bottleneck: the fact that at most one send request
and one receive request may be pending at any time. Changing this
aspect will however require a significant rewrite of libnetdriver,
and possibly debugging of drivers that are not able to cope with (in
particular) queuing multiple packets for transmission at once.
Beyond that, the design of the new API is based on the current
protocol, and may be changed/extended later to allow for non-ethernet
network drivers, exposure of link status, multicast address
configuration, suspend and resume, and any other features that are in
fact long overdue.
Change-Id: I47ec47e05852c42f92af04549d41524f928efec2
This patch adds (very limited) support for memory-mapping pages on
file systems that are mounted on the special "none" device and that
do not implement PEEK support by themselves. This includes hgfs,
vbfs, and procfs.
The solution is implemented in libvtreefs, and consists of allocating
pages, filling them with content by calling the file system's READ
functionality, passing the pages to VM, and freeing them again. A new
VM flag is used to indicate that these pages should be mapped in only
once, and thus not cached beyond their single use. This prevents
stale data from getting mapped in without the involvement of the file
system, which would be problematic on file systems where file contents
may become outdated at any time. No VM caching means no sharing and
poor performance, but mmap no longer fails on these file systems.
Compared to a libc-based approach, this patch retains the on-demand
nature of mmap. Especially tail(1) is known to map in a large file
area only to use a small portion of it.
All file systems now need to be given permission for the SETCACHEPAGE
and CLEARCACHE calls to VM.
A very basic regression test is added to test74.
Change-Id: I17afc4cb97315b515cad1542521b98f293b6b559
- rename start_vtreefs to run_vtreefs, since the function returns upon
termination these days;
- add get_inode_slots function to retrieve the number of indexed slots;
- add support for extra per-inode data for arbitrary storage.
Change-Id: If2d365d7b478a1cecc9e20fb2b3e70c1a1cf7243
The entire infrastructure relied on an ACK feature, and as such, it
has been broken for years now, with no easy way to repair it.
Change-Id: I783c2a21276967af115a642199f31fef0f14a572
- synchronize request type with ioctl by making it unsigned long;
- unbreak VFS requests, as they were being sent to PM;
- use proper ioctl direction flags (and new numbers) for requests;
- remove some needless header inclusions;
- svrctl is in libc, make its message name reflect this;
- keep backward compatibility: svrctl is part of the userland ABI.
Change-Id: I44902e8d0d11b8ebc1ef3bda94d2202481743c9b
The new functionality aims to save each file system server from having
to implement its own block I/O routines just so that it can serve as a
root file system. The new source file (bio.c) lists the requirements
that file system servers have to fulfill in order to use the routines.
Change-Id: Ia0190fd5c30e8c2097ed8f4b0e3ccde1827e0b92
The file system may not be expecting these upcalls at arbitrary
moments, while they serve only as a performance optimization anyway.
Change-Id: I0748fd1f6c2645ddbb64466093ee36025aac45e0
This library provides new abstractions for the upper (VFS) side of
file system services, and should be used for all file system service
implementations from now on. It provides the following functionality:
- a function call table abstraction, hiding the details of the
VFS-FS protocol with simple parameters;
- a (currently limited) number of per-function steps required for
all file system implementations, such as copying in and out path
names and result buffers;
- a default implementation for multicomponent path lookups, such
that the file system merely has to implement resolution of single
components at a time;
- an abstraction for copying data from and to the file system, which
allows transparent intraprocess copying as required for the lookup
implementation;
- a set of functions to simplify getdents implementations.
The message loop provided by the library is currently for use by
single-threaded file system implementations only. Multithreaded file
system services may use the more low-level message processing
functionality.
Protocol-level optimizations such as including names in protocol
messages may be hidden entirely in this library. In addition, in the
future, the lookup implementation may be replaced by a single-
component lookup VFS/FS protocol request as part of a VFS name cache
implementation; this, too, can be hidden entirely in this library.
Change-Id: Ib34f0d0e021dfa3426ce8826efcf3eaa94d3ef3e
. get rid of includes in libcompat_minix:
. move configfile.h to minix/include/
. all others are unneeded as they point to other files
. merge the .c files with libc
Change-Id: I5e840c66fb9bc484f377926aa9d66473bbd16259
This concerns all services, a.k.a drivers, filesystem drivers, network
(inet, lwip, uds) servers, and the system servers.
Change-Id: I626fd15c795e15af42df2d10d47fb4a703665d63