1 #ifndef FCNTL_COMMON_H__
2 #define FCNTL_COMMON_H__
3
4 #include <inttypes.h>
5
6 #include "tst_test.h"
7 #include "tst_kernel.h"
8
9 #include "lapi/syscalls.h"
10 #include "lapi/abisize.h"
11 #include "lapi/fcntl.h"
12
13 #if defined(TST_ABI64)
14 #define FCNTL_COMPAT(fd, cmd, flock) \
15 SAFE_FCNTL(fd, cmd, flock)
16
17 #else
18 struct my_flock64 {
19 short l_type;
20 short l_whence;
21 off64_t l_start;
22 off64_t l_len;
23 pid_t l_pid;
24 #if defined(__sparc__)
25 short padding;
26 #endif
27 };
28
29 /*
30 * F_OFD_* commands always require flock64 struct. Older GLibc (pre 2.29) would
31 * pass the flock sturct directly to the kernel even if it had 32-bit
32 * offsets.
33 *
34 * If we are on 32-bit abi we need to use the fcntl64 compat syscall.
35 *
36 * See:
37 * glibc: 06ab719d30 Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)
38 * kernel: fs/fcntl.c
39 */
fcntl_compat(const char * file,const int line,const char * cmd_name,int fd,int cmd,struct flock * lck)40 static inline int fcntl_compat(const char *file, const int line, const char *cmd_name,
41 int fd, int cmd, struct flock *lck)
42 {
43 struct my_flock64 l64 = {
44 .l_type = lck->l_type,
45 .l_whence = lck->l_whence,
46 .l_start = lck->l_start,
47 .l_len = lck->l_len,
48 .l_pid = lck->l_pid,
49 };
50
51 const int ret = tst_syscall(__NR_fcntl64, fd, cmd, &l64);
52
53 lck->l_type = l64.l_type;
54 lck->l_whence = l64.l_whence;
55 lck->l_start = l64.l_start;
56 lck->l_len = l64.l_len;
57 lck->l_pid = l64.l_pid;
58
59 if (ret != -1)
60 return ret;
61
62 tst_brk_(file, line, TBROK | TERRNO,
63 "fcntl64(%d, %s, { %d, %d, %"PRId64", %"PRId64", %d })",
64 fd,
65 cmd_name,
66 l64.l_type, l64.l_whence, l64.l_start, l64.l_len, l64.l_pid);
67
68 return ret;
69 }
70
71 #define FCNTL_COMPAT(fd, cmd, flock) \
72 fcntl_compat(__FILE__, __LINE__, #cmd, fd, cmd, flock)
73 #endif
74
75 #endif /* FCNTL_COMMON_H__ */
76