more on LFS

Ulrich Drepper (drepper@ipd.info.uni-karlsruhe.de)
14 Oct 1997 00:19:03 +0200


Hi,

Now that glibc is LFS aware it's time for the kernel. I wrote down
the points which will have to change and be added. If I remember
correctly all complains which came up (mainly from Alan :-) are
solved. Please take a look and let's discuss this now and finally
implement it. I don't think it's that much of a problem since
internally 64bit offsets are already used. We only have to define the
new types, add the checks with the maximum limit for the old syscalls
and write the new syscalls.

-- Uli
---------------. drepper at gnu.org ,-. Rubensstrasse 5
Ulrich Drepper \ ,-------------------' \ 76149 Karlsruhe/Germany
Cygnus Solutions `--' drepper at cygnus.com `------------------------

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- each opened file has an attribute "offset maximum". This attribute
is inherited via exec(), fork(), dup(), and fcntl() F_DUP.

- this is no process attribute, different file descriptors can have
different limits.

- resource limits (such as maximum file core file size) are inherited as well
via exec().

- we need new error codes EFBIG and EOVERFLOW

- fcntl()

* For an unlock (F_UNLCK) request: if the object is 32bit and and the
l_len for the set lock is zero and the locked range includes the last
representable byte (i.e., 2GB -1byte), then if the unlock request has
l_len != 0 and the last byte of the requested byte is the last
representable byte (ie.e, 2GB - 1byte), the request is treated as if
l_len is set to zero.

* EOVERFLOW is returned if a returned value cannot be represented
correctly

* EINVAL is returned for F_GETLK, F_SETLK, F_SETLKW if the smallest
offset of any byte cannot be represented (if l_len is zero) or
if the largest offset of any byte is not representable by off_t
(if l_len is nonzero).

- fstat(), lstat(), stat()

* The file size or the inode number cannot be represented in `struct stat'.
EOVERFLOW is returned.

- fstatfs(), statfs()

* The file size or the inode number cannot be represented in `struct statfs'.
EOVERFLOW is returned.

- ftruncate()

* The descriptor is of 32bit type and the requested size is greater
then the established maximum offset for the descriptor

- getrlimit()

* nothing changes if the limits can be represented in the normal way

* if the limit is not representable and matches the saved hard limit the
returned value is RLIM_SAVED_MAX

* otherwise if the limit is not representable the value returned is
RLIM_SAVED_CUR

=> the three values RLIM_INFINITY, RLIM_SAVED_CUR and RLIM_SAVED_MAX should
be distinct

- setrlimit()

* RLIM_INFINITY really means no limits, even if this means >2GN

* if the requested limit is RLIM_SAVED_MAX the value will be set to the
saved hard limit

* if the requested limit is RLIM_SAVED_CUR the value will be set to the
saved soft limit

* In addition, if the sved limit can be represented correctly in an object
of type rlim_t then it will be overwritten with the new limit

- lockf()

See fcntl() F_SETLK etc

- lseek()

EOVERFLOW will be returned if the resulting offset would be a value
not representable by an off_t object

- mmap()

if off + len > maximum offset EOVERFLOW is returned

- open()

If O_LARGEFILE is not given in the file mode 2GB-1 is established
as the maximum file offset. If the file is too large already
EOVERFLOW is returned.

If O_LARGEFILE is set no limit (ok, 2^63-1) is set

- read(), readv()

* no data transfer will occur past the offset maximum

* if the starting position of the read is before the limit and before EOF
and the starting position is greater or equal to the offset maximum
EOVERFLOW is returned (only if nlen > 0)

- readdir()

EOVERFLOW is returned if any of the values returned in the structure
is overflowed

- write(), writev()

* no data transfer will occur past the offset maximum

* if the starting position of the write is before the limit and before EOF
and the starting position is greater or equal to the offset maximum
EFBIG is returned (only if nlen > 0)

NEW CODE:

- F_GETLK64, F_SETLK64, F_SETLKW64 for fcntl() with an appropriate offset
type off64_t

- new value RLIM64_INFINITY, RLIM64_SAVED_CUR, RLIM64_SAVED_MAX with value
like 0x7fffffffffffffff or 0xffffffffffffffff

- types types ino64_t, rlim64_t, struct stat64

- new functions
stat64
fstat64
lstat64
setrlimit64
getrlimit64,
fstatfs64
fstatfs64
ftruncate64
lockf64
lseek64 (OK, we have already llseek)
mmap64
read64
readv64
pread64
readdir64
write64
writev64
pwrite64

which all use the appropriate new types and so have no limits. They
can also be used on 32bit files.