From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qk0-f182.google.com ([209.85.220.182]:33455 "EHLO mail-qk0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752353AbcHQU6E (ORCPT ); Wed, 17 Aug 2016 16:58:04 -0400 Received: by mail-qk0-f182.google.com with SMTP id z190so79703610qkc.0 for ; Wed, 17 Aug 2016 13:58:03 -0700 (PDT) Message-ID: <1471467478.3196.143.camel@redhat.com> Subject: Re: [glibc PATCH] fcntl: put F_OFD_* constants under #ifdef __USE_FILE_OFFSET64 From: Jeff Layton To: Mike Frysinger Cc: "Michael Kerrisk (man-pages)" , libc-alpha@sourceware.org, linux-fsdevel@vger.kernel.org, Carlos O'Donell , Yuriy Kolerov Date: Wed, 17 Aug 2016 16:57:58 -0400 In-Reply-To: <20160817203746.GF21655@vapier.lan> References: <1471445251-2450-1-git-send-email-jlayton@redhat.com> <20160817184333.GC21655@vapier.lan> <1471461304.3196.101.camel@redhat.com> <1471464343.3196.125.camel@redhat.com> <20160817203746.GF21655@vapier.lan> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Wed, 2016-08-17 at 13:37 -0700, Mike Frysinger wrote: > On 17 Aug 2016 16:05, Jeff Layton wrote: > > > > 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 > > 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: > > COMPAT_SYSCALL_DEFINE3(fcntl): > > rejects all 64-bit commands w/EINVAL > passes all other calls to compat_sys_fcntl64 > COMPAT_SYSCALL_DEFINE3(fcntl64): > > rewrites 32-bit flock struct to 64-bit flock struct > passes args to sys_fcntl  > fs/fcntl.c: > > SYSCALL_DEFINE3(fcntl): > passes all args to do_fcntl > SYSCALL_DEFINE3(fcntl64): > > handles 64-bit flock commands > > passes all others commands to do_fcntl > > do_fcntl: > > handles all commands using native sized flock struct > > so 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