This patch will make mode_t 16-bits->32-bits, off_t 32-bits->64-bits,
ino_t 32-bits->64-bits, and nlink_t 16-bits->32-bits. As uid_t and
gid_t were already 32-bits we can drop the big_{mode,off,ino,uid,
gid,nlink}_t types from struct stat. This has huge consequences:
. lseek now has to accept a 64-bit argument and returns a 64-bit
result. Therefore we need a new lseek and return proper results
based on the used version (i.e., translate).
. some fcntl functions take and return a struct flock which holds 2
off_t fields. Like lseek, we need to distinguish between old and
new versions.
. getdents uses struct dirent which has among other fields an ino_t
and off_t field. Consequently we need a new getdents system call
and have to translate when we encounter an old call.
. truncate and ftruncate also take off_t arguments and therefore
require a new version.
To add insult to injury VFS itself uses getdents. This has as
consequence that we have 2^3 combinations of version for getdents; old
and new version of libc (new system calls), new and old version of VFS
(when booting an old image), old and new version of an FS. We can
distinguish between these cases as follows; libc will use new system
call numbers that have not yet been in use. When using a new number,
VFS knows libc is new, otherwise it's an old libc. Vice versa, libc
first tries the new number and if that fails due to ENOSYS (unknown
system call number) it knows it's dealing with an old VFS. Finally,
since we now have VFS-FS protocol versioning and by bumping the version
to 1, VFS knows an FS is old when it reports version 0 and an FS knows
VFS is old when VFS reports it's using version 0.
0 = old version, 1 = new version
libc | VFS | FS | approach
----------------------------
0 | 0 | 0 | Nothing to do
----------------------------
0 | 0 | 1 | VFS reports protocol version 0, FS falls back
| to using the old getdents function
----------------------------
0 | 1 | 0 | VFS reports protocol version 1, FS version 0.
| libc requires old getdents so there is nothing
| to do. VFS itself needs new getdents and will
| translate.
----------------------------
0 | 1 | 1 | VFS reports protocol version 1, FS version 1.
| VFS intercepts getdents results and translates
| them on the fly before returning results to libc
----------------------------
1 | 0 | 0 | libc first tries new system call number and
| then fall back to the old number. libc first
| translates the results to the new getdents before
| returning.
----------------------------
1 | 0 | 1 | VFS reports protocol version 0, so FS uses fall
| back. libc translates.
----------------------------
1 | 1 | 0 | VFS reports protocol version 1, FS version 0. VFS
| will intercept all results and translate on the
| fly.
----------------------------
1 | 1 | 1 | Nothing to do.
As VFS can distinguish between old and new system calls of (f)truncate,
lseek, and fcntl, it will translate the arguments and results if
necessary. Likewise libc falls back to using the old calls and
translating the results to the new version if necessary.
Change-Id: Id5bc819e6ef90f317dbddb21020e0a65028225ce
The next commit will make mode_t 32-bits, ino_t 64-bits, nlink_t
32-bits, and off_t 64-bits. However, in the protocol there is no
room for that.
When analyzing the usage of these data types we can see that of
mode_t we currently use 15 bits and that future flags (if copied
from NetBSD) are only of importance to VFS and not to the actual
file system on disk. Therefore we can get away with keeping the
protocol version of mode_t (pmode_t) 16 bits.
At this point it is unlikely that MINIX will support file systems
that can hold more than 2^32 files. Keeping the protocol version of
ino_t (pino_t) 32-bits and exposing it as 64-bits to the rest of the
system is fine.
uid_t and gid_t are already 32-bits, but in behind the scenes they're
16-bits. This is sufficient since we don't support uid/gids larger
than 2^16-1.
off_t will become 64-bits, but the protocol had room reserved
for that since it was revised years ago.
So to make the difference clear between what the protocol supports
and what is exposed to the system, we define protocol version of
these data types.
Change-Id: Ifb883aafb222142e69d6dcc3049a47170b78b3ee
REQ_PEEK behaves just like REQ_READ except that it does not copy
data anywhere, just obtains the blocks from the FS into the cache.
To be used by the future mmap implementation.
Change-Id: I1b56de304f0a7152b69a72c8962d04258adb44f9
. 'anonymous' cache blocks (retrieved with NO_DEV as dev
parameter) were used to implement read()s from holes in
inodes that should return zeroes
. this is an awkward special case in the cache code though
and there's a more direct way to implement the same functionality:
instead of copying from a new, anonymous, zero block, to
the user target buffer, simply sys_safememset the user target
buffer directly. as this was the only use of this feature,
this is all that's needed to simplify the cache code a little.
Add primary cache management feature to libminixfs as mfs and ext2
currently do separately, remove cache code from mfs and ext2, and make
them use the libminixfs interface. This makes all fields of the buf
struct private to libminixfs and FS clients aren't supposed to access
them at all. Only the opaque 'void *data' field (the FS block contents,
used to be called bp) is to be accessed by the FS client.
The main purpose is to implement the interface to the 2ndary vm cache
just once, get rid of some code duplication, and add a little
abstraction to reduce the code inertia of the whole caching business.
Some minor sanity checking and prohibition done by mfs in this code
as removed from the generic primary cache code as a result:
- checking all inodes are not in use when allocating/resizing
the cache
- checking readonly filesystems aren't written to
- checking the superblock isn't written to on mounted filesystems
The minixfslib code relies on fs_blockstats() in the client filesystem to
return some FS usage information.
.enable all compile time warnings and make them errors
.refactor functions with unused parameters
.fix null pointer dereference before checking for null
.proper variable initialization
.use safe string copy functions
.fix massive memory corruption bug in fs_getdents
. all invocations were S or D, so can safely be dropped
to prepare for the segmentless world
. still assign D to the SCP_SEG field in the message
to make previous kernels usable