io: Fix record locking contants for powerpc64 with __USE_FILE_OFFSET64

Message ID 20230828213721.2957677-1-aurelien@aurel32.net
State New
Headers
Series io: Fix record locking contants for powerpc64 with __USE_FILE_OFFSET64 |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Testing passed

Commit Message

Aurelien Jarno Aug. 28, 2023, 9:37 p.m. UTC
  Commit 5f828ff824e3b7cd1 ("io: Fix F_GETLK, F_SETLK, and F_SETLKW for
powerpc64") fixed an issue with the value of the lock constants on
powerpc64 when not using __USE_FILE_OFFSET64, but it ended-up also
changing the value when using __USE_FILE_OFFSET64 causing an ABI
breakage.

Fix that by also checking that define, restoring the pre
4d0fe291aed3a476a commit values:

Default values:
- F_GETLK: 5
- F_SETLK: 6
- F_SETLKW: 7

With -D_FILE_OFFSET_BITS=64:
- F_GETLK: 12
- F_SETLK: 13
- F_SETLKW: 14

Resolves: BZ #30804.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
  

Comments

Florian Weimer Aug. 29, 2023, 7:59 a.m. UTC | #1
* Aurelien Jarno:

> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
> index f7615a447e..d8a291a331 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
> @@ -33,7 +33,7 @@
>  # define __O_LARGEFILE	0200000
>  #endif
>  
> -#if __WORDSIZE == 64
> +#if __WORDSIZE == 64 && !defined __USE_FILE_OFFSET64
>  # define F_GETLK	5
>  # define F_SETLK	6
>  # define F_SETLKW	7

I find this puzzling.  Why would __USE_FILE_OFFSET64 have an effect if
__WORDSIZE is 64?

Thanks,
Florian
  
Adhemerval Zanella Aug. 29, 2023, 1:20 p.m. UTC | #2
On 29/08/23 04:59, Florian Weimer via Libc-alpha wrote:
> * Aurelien Jarno:
> 
>> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
>> index f7615a447e..d8a291a331 100644
>> --- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
>> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
>> @@ -33,7 +33,7 @@
>>  # define __O_LARGEFILE	0200000
>>  #endif
>>  
>> -#if __WORDSIZE == 64
>> +#if __WORDSIZE == 64 && !defined __USE_FILE_OFFSET64
>>  # define F_GETLK	5
>>  # define F_SETLK	6
>>  # define F_SETLKW	7
> 
> I find this puzzling.  Why would __USE_FILE_OFFSET64 have an effect if
> __WORDSIZE is 64?

This is a historical artifact from powerpc64. Instead of following other 64-bit
architectures and define F_GETLK the same whether _FILE_OFFSET_BITS is defined,
the port used powerpc definitiosn that required different values to support LFS.

This patch is not wrong, but at same time not really required.  The powercp64
fcntl will handle F_GETLK/F_SETLK/F_SETLKW with the historical values with
the FCNTL_ADJUST_CMD macro, so old binaries will continue to work as expected.
  
Aurelien Jarno Aug. 29, 2023, 4:30 p.m. UTC | #3
On 2023-08-29 10:20, Adhemerval Zanella Netto wrote:
> 
> 
> On 29/08/23 04:59, Florian Weimer via Libc-alpha wrote:
> > * Aurelien Jarno:
> > 
> >> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
> >> index f7615a447e..d8a291a331 100644
> >> --- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
> >> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
> >> @@ -33,7 +33,7 @@
> >>  # define __O_LARGEFILE	0200000
> >>  #endif
> >>  
> >> -#if __WORDSIZE == 64
> >> +#if __WORDSIZE == 64 && !defined __USE_FILE_OFFSET64
> >>  # define F_GETLK	5
> >>  # define F_SETLK	6
> >>  # define F_SETLKW	7
> > 
> > I find this puzzling.  Why would __USE_FILE_OFFSET64 have an effect if
> > __WORDSIZE is 64?
> 
> This is a historical artifact from powerpc64. Instead of following other 64-bit
> architectures and define F_GETLK the same whether _FILE_OFFSET_BITS is defined,
> the port used powerpc definitiosn that required different values to support LFS.
> 
> This patch is not wrong, but at same time not really required.  The powercp64
> fcntl will handle F_GETLK/F_SETLK/F_SETLKW with the historical values with
> the FCNTL_ADJUST_CMD macro, so old binaries will continue to work as expected.

It does break some binaries, for instance File-FcntlLock [1] with the
following scenario:
- perl is built against glibc 2.37
- system is upgraded to glibc 2.38
- File-FcntlLock is built against glibc 2.38: it does not work as the
  value of F_GETLK has changed from 12 to 5 [2].

In short these constants are not exclusively used by the glibc. They
might be referenced in some libraries, and changing their values break
things.

[1] https://metacpan.org/dist/File-FcntlLock
[2] https://metacpan.org/release/JTT/File-FcntlLock-0.22/source/FcntlLock.xs#L74
  
Adhemerval Zanella Aug. 29, 2023, 5:06 p.m. UTC | #4
On 29/08/23 13:30, Aurelien Jarno wrote:
> On 2023-08-29 10:20, Adhemerval Zanella Netto wrote:
>>
>>
>> On 29/08/23 04:59, Florian Weimer via Libc-alpha wrote:
>>> * Aurelien Jarno:
>>>
>>>> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
>>>> index f7615a447e..d8a291a331 100644
>>>> --- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
>>>> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
>>>> @@ -33,7 +33,7 @@
>>>>  # define __O_LARGEFILE	0200000
>>>>  #endif
>>>>  
>>>> -#if __WORDSIZE == 64
>>>> +#if __WORDSIZE == 64 && !defined __USE_FILE_OFFSET64
>>>>  # define F_GETLK	5
>>>>  # define F_SETLK	6
>>>>  # define F_SETLKW	7
>>>
>>> I find this puzzling.  Why would __USE_FILE_OFFSET64 have an effect if
>>> __WORDSIZE is 64?
>>
>> This is a historical artifact from powerpc64. Instead of following other 64-bit
>> architectures and define F_GETLK the same whether _FILE_OFFSET_BITS is defined,
>> the port used powerpc definitiosn that required different values to support LFS.
>>
>> This patch is not wrong, but at same time not really required.  The powercp64
>> fcntl will handle F_GETLK/F_SETLK/F_SETLKW with the historical values with
>> the FCNTL_ADJUST_CMD macro, so old binaries will continue to work as expected.
> 
> It does break some binaries, for instance File-FcntlLock [1] with the
> following scenario:
> - perl is built against glibc 2.37
> - system is upgraded to glibc 2.38
> - File-FcntlLock is built against glibc 2.38: it does not work as the
>   value of F_GETLK has changed from 12 to 5 [2].
> 
> In short these constants are not exclusively used by the glibc. They
> might be referenced in some libraries, and changing their values break
> things.
> 
> [1] https://metacpan.org/dist/File-FcntlLock
> [2] https://metacpan.org/release/JTT/File-FcntlLock-0.22/source/FcntlLock.xs#L74
> 

Sigh, you are correct. And it is also means that default and LFS objects are 
essentially incompatible on powerpc64 in this regard for this very reason, but 
I agree that we should keep the compatibility.

Could add a LFS test, just to make sure the lock constants are correct:

diff --git a/io/Makefile b/io/Makefile
index 6ccc0e8691..8a3c83a3bb 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -192,6 +192,7 @@ tests := \
   tst-fchownat \
   tst-fcntl \
   tst-fcntl-lock \
+  tst-fcntl-lock-lfs \
   tst-fstatat \
   tst-fts \
   tst-fts-lfs \
diff --git a/io/tst-fcntl-lock-lfs.c b/io/tst-fcntl-lock-lfs.c
new file mode 100644
index 0000000000..f2a909fb02
--- /dev/null
+++ b/io/tst-fcntl-lock-lfs.c
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include <io/tst-fcntl-lock.c>

It won't really trigger this issue, but it a extra sanity test.
  
Andreas Schwab Aug. 30, 2023, 9:19 a.m. UTC | #5
On Aug 29 2023, Aurelien Jarno wrote:

> It does break some binaries, for instance File-FcntlLock [1] with the
> following scenario:
> - perl is built against glibc 2.37
> - system is upgraded to glibc 2.38
> - File-FcntlLock is built against glibc 2.38: it does not work as the
>   value of F_GETLK has changed from 12 to 5 [2].

It happens all the time that an API change breaks some combination of
recompiled and not recompiled objects.  But it is not an ABI break, only
a QoI issue.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
index f7615a447e..d8a291a331 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
@@ -33,7 +33,7 @@ 
 # define __O_LARGEFILE	0200000
 #endif
 
-#if __WORDSIZE == 64
+#if __WORDSIZE == 64 && !defined __USE_FILE_OFFSET64
 # define F_GETLK	5
 # define F_SETLK	6
 # define F_SETLKW	7