Re: [glibc PATCH] fcntl: put F_OFD_* constants under #ifdef __USE_FILE_OFFSET64
From: Jeff Layton <hidden>
Date: 2016-08-17 20:58:04
On Wed, 2016-08-17 at 13:37 -0700, Mike Frysinger wrote:
On 17 Aug 2016 16:05, Jeff Layton wrote:quoted
The way it works now is that when you define _FILE_OFFSET_BITS=64 and call fcntl(fd, F_SETLK, fl) glibc swaps in a struct flock64 for your struct flock, and F_SETLK64 for the F_SETLK.does it ? doesn't seem like it does to me. here's glibc's fcntl.c: io/fcntl.c - generic stub that sets ENOSYS sysdeps/unix/sysv/linux/fcntl.c - just calls syscall(fcntl) sysdeps/unix/sysv/linux/generic/wordsize-32/fcntl.c - just calls syscall(fcntl64) sysdeps/unix/sysv/linux/i386/fcntl.c - same as above <all the other 32-bit arches include the i386 file>
Ok, I was being a little cavalier with my description. This is what
really happens (from x86 struct flock definition):
struct flock
{
short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
#ifndef __USE_FILE_OFFSET64
__off_t l_start; /* Offset where the lock begins. */
__off_t l_len; /* Size of the locked area; zero means until EOF. */
#else
__off64_t l_start; /* Offset where the lock begins. */
__off64_t l_len; /* Size of the locked area; zero means until EOF. */
#endif
__pid_t l_pid; /* Process holding the lock. */
};
So, l_start and l_len get redefined into larger sizes when LFS is
enabled. The F_GETLK/F_SETLK/F_SETLKW are also redefined to their *64
equivalents in that case using the preprocessor.
the kernel is where it gets interesting:
Yes indeed. It's quite the twisty maze...
fs/compat.c:quoted
COMPAT_SYSCALL_DEFINE3(fcntl): rejects all 64-bit commands w/EINVALpasses all other calls to compat_sys_fcntl64 COMPAT_SYSCALL_DEFINE3(fcntl64):quoted
rewrites 32-bit flock struct to 64-bit flock structpasses args to sys_fcntl fs/fcntl.c:quoted
SYSCALL_DEFINE3(fcntl):passes all args to do_fcntl SYSCALL_DEFINE3(fcntl64):quoted
handles 64-bit flock commands passes all others commands to do_fcntl do_fcntl: handles all commands using native sized flock structso for a 32-bit system (e.g. i386), you must match LFS & command usage. if LFS is turned on, then using 32-bit commands w/struct flock fails. if LFS is turned off, then using 64-bit commands w/struct flock fails. -mike
Yes. The command is what tells the kernel the sort of struct flock it has been given. The problem here is that we assume that it's sizeof(struct flock64), but it could a non-LFS struct flock. -- Jeff Layton [off-list ref]