xfs: Verify correctness of upgrading an fs to support large extent counters
[xfstests-dev.git] / lib / file_lock.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/file.h>
9 #include <sys/param.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <errno.h>
14 #include <sys/sysmacros.h>
15 #include <string.h> /* memset, strerror */
16 #include "file_lock.h"
17
18
19 #ifndef EFSEXCLWR
20 #define EFSEXCLWR       503
21 #endif
22
23 /*
24  * String containing the last system call.
25  *
26  */
27 char Fl_syscall_str[128];
28
29 static char errmsg[256];
30
31 /***********************************************************************
32  *
33  * Test interface to the fcntl system call.
34  * It will loop if the LOCK_NB flags is NOT set.
35  ***********************************************************************/
36 int
37 file_lock(fd, flags, errormsg)
38 int fd;
39 int flags;
40 char **errormsg;
41 {
42         register int cmd, ret;
43         struct flock flocks;
44
45         memset(&flocks, 0, sizeof(struct flock));
46
47         if (flags&LOCK_NB)
48                 cmd = F_SETLK;
49         else
50                 cmd = F_SETLKW;
51
52         flocks.l_whence = 0;
53         flocks.l_start = 0;
54         flocks.l_len = 0;
55
56         if (flags&LOCK_UN)
57                 flocks.l_type = F_UNLCK;
58         else if (flags&LOCK_EX)
59                 flocks.l_type = F_WRLCK;
60         else if (flags&LOCK_SH)
61                 flocks.l_type = F_RDLCK;
62         else {
63                 errno = EINVAL;
64             if ( errormsg != NULL ) {
65                 sprintf(errmsg,
66                     "Programmer error, called file_lock with in valid flags\n");
67                 *errormsg = errmsg;
68             }
69             return -1;
70         }
71
72         sprintf(Fl_syscall_str,
73             "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
74                 fd, cmd, flocks.l_type, flocks.l_whence,
75                 (long long)flocks.l_start, (long long)flocks.l_len);
76
77         while (1) {
78             ret = fcntl(fd, cmd, &flocks);
79
80             if ( ret < 0 ) {
81                 if ( cmd == F_SETLK )
82                     switch (errno) {
83                        /* these errors are okay */
84                         case EACCES:    /* Permission denied */
85                         case EINTR:             /* interrupted system call */
86 #ifdef EFILESH
87                         case EFILESH:   /* file shared */
88 #endif
89                         case EFSEXCLWR: /* File is write protected */
90                             continue;   /* retry getting lock */
91                 }
92                 if ( errormsg != NULL ) {
93                     sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
94                         fd, cmd, errno, strerror(errno));
95                     *errormsg = errmsg;
96                 }
97                 return -1;
98             }
99             break;
100         }
101
102         return ret;
103
104 }       /* end of file_lock */
105
106 /***********************************************************************
107  *
108  * Test interface to the fcntl system call.
109  * It will loop if the LOCK_NB flags is NOT set.
110  ***********************************************************************/
111 int
112 record_lock(fd, flags, start, len, errormsg)
113 int fd;
114 int flags;
115 int start;
116 int len;
117 char **errormsg;
118 {
119         register int cmd, ret;
120         struct flock flocks;
121
122         memset(&flocks, 0, sizeof(struct flock));
123
124         if (flags&LOCK_NB)
125                 cmd = F_SETLK;
126         else
127                 cmd = F_SETLKW;
128
129         flocks.l_whence = 0;
130         flocks.l_start = start;
131         flocks.l_len = len;
132
133         if (flags&LOCK_UN)
134                 flocks.l_type = F_UNLCK;
135         else if (flags&LOCK_EX)
136                 flocks.l_type = F_WRLCK;
137         else if (flags&LOCK_SH)
138                 flocks.l_type = F_RDLCK;
139         else {
140                 errno = EINVAL;
141             if ( errormsg != NULL ) {
142                 sprintf(errmsg,
143                     "Programmer error, called record_lock with in valid flags\n");
144                 *errormsg = errmsg;
145             }
146             return -1;
147         }
148
149         sprintf(Fl_syscall_str,
150             "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
151                 fd, cmd, flocks.l_type, flocks.l_whence,
152                 (long long)flocks.l_start, (long long)flocks.l_len);
153
154         while (1) {
155             ret = fcntl(fd, cmd, &flocks);
156
157             if ( ret < 0 ) {
158                 if ( cmd == F_SETLK )
159                     switch (errno) {
160                        /* these errors are okay */
161                         case EACCES:    /* Permission denied */
162                         case EINTR:             /* interrupted system call */
163 #ifdef EFILESH
164                         case EFILESH:   /* file shared */
165 #endif
166                         case EFSEXCLWR: /* File is write protected */
167                             continue;   /* retry getting lock */
168                 }
169                 if ( errormsg != NULL ) {
170                     sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
171                         fd, cmd, errno, strerror(errno));
172                     *errormsg = errmsg;
173                 }
174                 return -1;
175             }
176             break;
177         }
178
179         return ret;
180
181 }       /* end of record_lock */
182
183