syscalls/fcntl: make OFD commands use fcntl64() syscall on 32-bit
PATCH v2 1/1 syscalls/fcntl: make OFD commands use fcntl64() syscall on 32-bit
OFD commands require 64-bit argument (struct flock64). Until glibc commit 06ab719d30b0 ("Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)") we relied on glibc passing arg directly to syscall.
This creates problem for 32-bit version of the test, because old glibc is passing arg directly, while new one is casting it to struct flock.
We could add a configure check for glibc version, but that may not help with other libc libraries.
We could do a runtime check that exploits non-zero l_pid returning EINVAL. This however complicates SAFE_FCNTL macro substantially.
This patch changes 32-bit version of test to use syscall directly.
---
Changes in v2:
- use struct flock64 as well on 64-bit, since it should be identical to struct flock, it allows us to drop couple ifdefs
testcases/kernel/syscalls/fcntl/fcntl34.c | 5 ++-- testcases/kernel/syscalls/fcntl/fcntl36.c | 9 ++++---- testcases/kernel/syscalls/fcntl/fcntl_common.h | 32 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 testcases/kernel/syscalls/fcntl/fcntl_common.h
testcases/kernel/syscalls/fcntl/fcntl34.c +3 -2
@@ -28,6 +28,7 @@#include "lapi/fcntl.h" #include "tst_safe_pthread.h" #include "tst_test.h" +#include "fcntl_common.h" static int thread_cnt;static const int max_thread_cnt =32 ;
@@ -76,13 +77,13 @@ void *thread_fn_01(void *arg)for (i =0 ; i < writes_num; ++i) { lck.l_type =F_WRLCK ; -SAFE_FCNTL (fd,F_OFD_SETLKW , &lck); +my_fcntl (fd,F_OFD_SETLKW , &lck);SAFE_LSEEK (fd,0 ,SEEK_END );SAFE_WRITE (1 , fd, buf, write_size); lck.l_type =F_UNLCK ; -SAFE_FCNTL (fd,F_OFD_SETLKW , &lck); +my_fcntl (fd,F_OFD_SETLKW , &lck);sched_yield (); }
testcases/kernel/syscalls/fcntl/fcntl36.c +5 -4
@@ -57,6 +57,7 @@#include "lapi/fcntl.h" #include "tst_safe_pthread.h" #include "tst_test.h" +#include "fcntl_common.h" static int thread_cnt;static int fail_flag =0 ;
@@ -99,13 +100,13 @@ static void *fn_ofd_w(void *arg)memset (buf, wt, pa->length); lck.l_type =F_WRLCK ; -SAFE_FCNTL (fd,F_OFD_SETLKW , &lck); +my_fcntl (fd,F_OFD_SETLKW , &lck);SAFE_LSEEK (fd, pa->offset,SEEK_SET );SAFE_WRITE (1 , fd, buf, pa->length); lck.l_type =F_UNLCK ; -SAFE_FCNTL (fd,F_OFD_SETLKW , &lck); +my_fcntl (fd,F_OFD_SETLKW , &lck); wt++;if (wt >=255 )
@@ -178,7 +179,7 @@ static void *fn_ofd_r(void *arg)memset (buf,0 , pa->length); lck.l_type =F_RDLCK ; -SAFE_FCNTL (fd,F_OFD_SETLKW , &lck); +my_fcntl (fd,F_OFD_SETLKW , &lck);/* rlock acquired */ SAFE_LSEEK (fd, pa->offset,SEEK_SET );
@@ -209,7 +210,7 @@ static void *fn_ofd_r(void *arg) } lck.l_type =F_UNLCK ; -SAFE_FCNTL (fd,F_OFD_SETLK , &lck); +my_fcntl (fd,F_OFD_SETLK , &lck);sched_yield (); }
testcases/kernel/syscalls/fcntl/fcntl_common.h new file +32 -0
@@ -0,0 +1,32 @@ +#include "lapi/syscalls.h" + +/* +* glibc commit: +* 06ab719d30b0 ("Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)") +* changed behavior of arg parameter for OFD commands. It is no +* longer passing arg directly to syscall, but expects it to be +* 'struct flock'. +* +* On 64-bit or _FILE_OFFSET_BITS == 64 we can use fcntl() and +* struct flock64 with any glibc version. struct flock and flock64 +* should be identical. +* +* On 32-bit, older glibc would pass arg directly, recent one treats +* it as 'struct flock' and converts it to 'struct flock64'. +* So, to support both version, on 32-bit we use fcntl64 syscall +* directly with struct flock64. +*/ +#if __WORDSIZE ==64 || _FILE_OFFSET_BITS ==64 +static int my_fcntl (int fd,int cmd,void *lck) +{ +return SAFE_FCNTL (fd, cmd, lck); +} +#else +static int my_fcntl (int fd,int cmd,void *lck) +{ +int ret =tst_syscall (__NR_fcntl64, fd, cmd, lck); +if (ret ==-1 ) +tst_brk (TBROK |TERRNO ,"fcntl64" ); +return ret; +} +#endif
Signature · 1 line
1.8.3.1
PATCH v2 1/1 syscalls/fcntl: make OFD commands use fcntl64() syscall on 32-bit
Quoted 12 lines · Jan Stancek
OFD commands require 64-bit argument (struct flock64). Until glibc commit
06ab719d30b0("Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)") we relied on glibc passing arg directly to syscall.This creates problem for 32-bit version of the test, because old glibc is passing arg directly, while new one is casting it to struct flock.
We could add a configure check for glibc version, but that may not help with other libc libraries.
Quoted 7 lines
We could do a runtime check that exploits non-zero
l_pidreturning EINVAL. This however complicatesSAFE_FCNTLmacro substantially.This patch changes 32-bit version of test to use syscall directly.
Signed-off-by Jan Stancek <[email protected]>
Signature · 5 lines
Regards, Li Wang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.linux.it/pipermail/ltp/attachments/20181018/efd86850/attachment.html>
PATCH v2 1/1 syscalls/fcntl: make OFD commands use fcntl64() syscall on 32-bit
----- Original Message -----
Quoted 17 lines · Jan Stancek
Quoted 16 lines
OFD commands require 64-bit argument (struct flock64). Until glibc commit
06ab719d30b0("Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)") we relied on glibc passing arg directly to syscall.This creates problem for 32-bit version of the test, because old glibc is passing arg directly, while new one is casting it to struct flock.
We could add a configure check for glibc version, but that may not help with other libc libraries.
We could do a runtime check that exploits non-zero
l_pidreturning EINVAL. This however complicatesSAFE_FCNTLmacro substantially.
Quoted 6 lines
Quoted 4 lines
This patch changes 32-bit version of test to use syscall directly.
Signed-off-by Jan Stancek <[email protected]>Reviewed-by Li Wang <[email protected]>
Pushed.
Thanks,
Jan