Whamcloud - gitweb
LU-7117 osp: set ptlrpc_request::rq_allow_replay properly
[fs/lustre-release.git] / lustre / tests / swap_lock_test.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22
23 /*
24  * Copyright 2015 Cray Inc, all rights reserved.
25  * Author: Frank Zago.
26  *
27  * A few portions are extracted from llapi_layout_test.c
28  *
29  * The purpose of this test is to exert the layout swap function, with
30  * locking.
31  *
32  * The program will exit as soon as a non zero error code is returned.
33  */
34
35 #include <stdlib.h>
36 #include <errno.h>
37 #include <getopt.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42 #include <poll.h>
43 #include <time.h>
44
45 #include <lustre/lustreapi.h>
46 #include <lustre/lustre_idl.h>
47
48 #define ERROR(fmt, ...)                                                 \
49         fprintf(stderr, "%s: %s:%d: %s: " fmt "\n",                     \
50                 program_invocation_short_name, __FILE__, __LINE__,      \
51                 __func__, ## __VA_ARGS__);
52
53 #define DIE(fmt, ...)                           \
54         do {                                    \
55                 ERROR(fmt, ## __VA_ARGS__);     \
56                 exit(EXIT_FAILURE);             \
57         } while (0)
58
59 #define ASSERTF(cond, fmt, ...)                                         \
60         do {                                                            \
61                 if (!(cond))                                            \
62                         DIE("assertion '%s' failed: "fmt,               \
63                             #cond, ## __VA_ARGS__);                     \
64         } while (0)
65
66 #define PERFORM(testfn) \
67         do {                                                            \
68                 fprintf(stderr, "Starting test " #testfn " at %lld\n",  \
69                         (unsigned long long)time(NULL));                \
70                 cleanup();                                              \
71                 testfn();                                               \
72                 cleanup();                                              \
73                 fprintf(stderr, "Finishing test " #testfn " at %lld\n", \
74                         (unsigned long long)time(NULL));                \
75         } while (0)
76
77 /* Name of file/directory. Will be set once and will not change. */
78 static char mainpath[PATH_MAX];
79 static const char *maindir = "swap_lock_test_dir_4525654";
80
81 static char fsmountdir[PATH_MAX];       /* Lustre mountpoint */
82 static char *lustre_dir;                /* Test directory inside Lustre */
83
84 /* Cleanup our test directory. */
85 static void cleanup(void)
86 {
87         char cmd[PATH_MAX];
88         int rc;
89
90         rc = snprintf(cmd, sizeof(cmd), "rm -rf -- '%s'", mainpath);
91         ASSERTF(rc > 0 && rc < sizeof(cmd),
92                 "invalid delete command for path '%s'", mainpath);
93         rc = system(cmd);
94         ASSERTF(rc != -1, "Cannot execute rm command");
95         ASSERTF(WEXITSTATUS(rc) == 0,
96                 "rm command returned %d", WEXITSTATUS(rc));
97 }
98
99 /* Create a filename inside the test directory. Will assert on
100  * error. */
101 static char *create_file_name(const char *name)
102 {
103         char *filename;
104         int rc;
105
106         rc = asprintf(&filename, "%s/%s/%s", lustre_dir, maindir, name);
107         ASSERTF(rc > 0, "can't make filename for '%s'", name);
108
109         return filename;
110 }
111
112 /* Create a file of a given size in the test directory, filed with
113  * c. Will assert on error. */
114 int create_file(const char *name, size_t size, unsigned char c)
115 {
116         int fd;
117         char *filename;
118         int rc;
119         char buf[64*1024];
120
121         filename = create_file_name(name);
122
123         fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0600);
124         ASSERTF(fd >= 0, "open failed for '%s': %s",
125                 filename, strerror(errno));
126
127         free(filename);
128
129         /* Fill-up the new file. */
130         memset(buf, c, sizeof(buf));
131
132         while (size) {
133                 size_t to_write = size;
134
135                 if (to_write > sizeof(buf))
136                         to_write = sizeof(buf);
137
138                 rc = write(fd, buf, to_write);
139                 ASSERTF(rc > 0, "writing %zu bytes to '%s' failed: %s",
140                         to_write, name, strerror(errno));
141
142                 size -= to_write;
143         }
144
145         return fd;
146 }
147
148 /* Test basic swap */
149 static void test10(void)
150 {
151         int rc;
152         int fd1;
153         int fd2;
154         size_t foo1_size = 2000;
155         size_t foo2_size = 5000;
156         struct stat stbuf;
157
158         rc = mkdir(mainpath, 0);
159         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
160                 mainpath, strerror(errno));
161
162         fd1 = create_file("foo1", foo1_size, 'x');
163         fd2 = create_file("foo2", foo2_size, 'y');
164
165         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
166         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
167                 strerror(-rc));
168
169         rc = fstat(fd1, &stbuf);
170         ASSERTF(rc == 0, "stat failed on 'foo1': %s", strerror(errno));
171         ASSERTF(stbuf.st_size == foo2_size,
172                 "invalid size found: %llu instead of %zu",
173                 (unsigned long long)stbuf.st_size, foo2_size);
174
175         rc = fstat(fd2, &stbuf);
176         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
177         ASSERTF(stbuf.st_size == foo1_size,
178                 "invalid size found: %llu instead of %zu",
179                 (unsigned long long)stbuf.st_size, foo1_size);
180
181         close(fd1);
182         close(fd2);
183 }
184
185 /* Test self swap. It's a no-op and will always succeed. */
186 static void test11(void)
187 {
188         int rc;
189         int fd1;
190         size_t foo1_size = 2000;
191
192         rc = mkdir(mainpath, 0);
193         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
194                 mainpath, strerror(errno));
195
196         fd1 = create_file("foo1", foo1_size, 'x');
197
198         rc = llapi_fswap_layouts(fd1, fd1, 0, 0, 0);
199         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
200                 strerror(-rc));
201
202         close(fd1);
203 }
204
205 /* Test self swap, on different handles. It's a no-op and will always
206  * succeed. */
207 static void test12(void)
208 {
209         int rc;
210         int fd1;
211         int fd2;
212         size_t foo1_size = 2000;
213
214         rc = mkdir(mainpath, 0);
215         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
216                 mainpath, strerror(errno));
217
218         fd1 = create_file("foo1", foo1_size, 'x');
219         fd2 = dup(fd1);
220         ASSERTF(fd2 != -1, "dup failed:  %s", strerror(errno));
221
222         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
223         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
224                 strerror(-rc));
225
226         close(fd1);
227         close(fd2);
228 }
229
230 /* Swap with a non Lustre file */
231 static void test13(void)
232 {
233         int rc;
234         int fd1;
235         int fd2;
236         size_t foo1_size = 2000;
237
238         rc = mkdir(mainpath, 0);
239         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
240                 mainpath, strerror(errno));
241
242         fd1 = create_file("foo1", foo1_size, 'x');
243
244         fd2 = open("/dev/null", O_RDWR);
245         ASSERTF(fd2 != -1, "open '/dev/null/' failed:  %s", strerror(errno));
246
247         /* Note that the returned error will be different for both
248          * operations. In the first swap, fd1 is on Lustre, so the
249          * ioctl will succeed, but its processing will eventually fail
250          * because fd2 is not on Lustre. In the second swap, the ioctl
251          * request is unknown, so ioctl() will directly fail. */
252         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
253         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts failed: %s",
254                 strerror(-rc));
255
256         rc = llapi_fswap_layouts(fd2, fd1, 0, 0, 0);
257         ASSERTF(rc == -ENOTTY, "llapi_fswap_layouts failed: %s",
258                 strerror(-rc));
259
260         close(fd1);
261         close(fd2);
262 }
263
264 /* Swap with bogus values */
265 static void test14(void)
266 {
267         int rc;
268
269         rc = llapi_fswap_layouts(-6, -2, 0, 0, 0);
270         ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
271                 strerror(-rc));
272
273         /* When run under a shell, rc is -EINVAL. When run under
274          * Lustre test suite, stdin is redirected, and rc is
275          * -ENOTTY. Catch both cases. */
276         rc = llapi_fswap_layouts(0, 0, 0, 0, 0);
277         ASSERTF(rc == -EINVAL || rc == -ENOTTY,
278                 "llapi_fswap_layouts failed: %s",
279                 strerror(-rc));
280
281         rc = llapi_fswap_layouts(456789076, 234567895, 0, 0, 0);
282         ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
283                 strerror(-rc));
284 }
285
286 /* Lease only test. */
287 static void test15(void)
288 {
289         int rc;
290         char *filename;
291         int fd;
292         int i;
293
294         rc = mkdir(mainpath, 0);
295         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
296                 mainpath, strerror(errno));
297
298         filename = create_file_name("foo1");
299
300         fd = create_file("foo1", 1000, 'x');
301
302         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
303         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
304
305         close(fd);
306
307         /* Read lease on read file */
308         fd = open(filename, O_RDONLY);
309         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
310
311         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
312         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
313
314         rc = llapi_lease_check(fd);
315         ASSERTF(rc == LL_LEASE_RDLCK,
316                 "invalid lease type on '%s': %s", filename, strerror(-rc));
317
318         close(fd);
319
320         /* Write lease on write file */
321         fd = open(filename, O_WRONLY);
322         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
323
324         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
325         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
326
327         rc = llapi_lease_check(fd);
328         ASSERTF(rc == LL_LEASE_WRLCK,
329                 "invalid lease type on '%s': %s", filename, strerror(-rc));
330
331         close(fd);
332
333         /* Read lease on read/write file */
334         fd = open(filename, O_RDWR);
335         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
336
337         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
338         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
339
340         rc = llapi_lease_check(fd);
341         ASSERTF(rc == LL_LEASE_RDLCK,
342                 "invalid lease type on '%s': %s", filename, strerror(-rc));
343
344         close(fd);
345
346         /* Write lease on read/write file */
347         fd = open(filename, O_RDWR);
348         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
349
350         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
351         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
352
353         rc = llapi_lease_check(fd);
354         ASSERTF(rc == LL_LEASE_WRLCK,
355                 "invalid lease type on '%s': %s", filename, strerror(-rc));
356
357         close(fd);
358
359         /* Read lease on write only file */
360         fd = open(filename, O_WRONLY);
361         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
362
363         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
364         ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
365                 filename, strerror(-rc));
366
367         rc = llapi_lease_check(fd);
368         ASSERTF(rc == 0,
369                 "invalid lease type on '%s': %s", filename, strerror(-rc));
370
371         close(fd);
372
373         /* Write lease on read only file */
374         fd = open(filename, O_RDONLY);
375         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
376
377         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
378         ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
379                 filename, strerror(-rc));
380
381         rc = llapi_lease_check(fd);
382         ASSERTF(rc == 0,
383                 "invalid lease type on '%s': %s", filename, strerror(-rc));
384
385         close(fd);
386
387         /* Get read lease again */
388         fd = open(filename, O_RDWR);
389         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
390
391         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
392         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
393
394         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
395         ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
396                 filename, strerror(-rc));
397
398         rc = llapi_lease_check(fd);
399         ASSERTF(rc == LL_LEASE_RDLCK,
400                 "invalid lease type on '%s': %s", filename, strerror(-rc));
401
402         close(fd);
403
404         /* Get write lease again */
405         fd = open(filename, O_RDWR);
406         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
407
408         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
409         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
410
411         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
412         ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
413                 filename, strerror(-rc));
414
415         rc = llapi_lease_check(fd);
416         ASSERTF(rc == LL_LEASE_WRLCK,
417                 "invalid lease type on '%s': %s", filename, strerror(-rc));
418
419         close(fd);
420
421         /* Get a lease, release and get again */
422         fd = open(filename, O_RDWR);
423         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
424
425         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
426         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
427
428         rc = llapi_lease_check(fd);
429         ASSERTF(rc == LL_LEASE_RDLCK,
430                 "invalid lease type on '%s': %s", filename, strerror(-rc));
431
432         rc = llapi_lease_put(fd);
433         ASSERTF(rc == LL_LEASE_RDLCK, "was not able to put back lease '%s': %s",
434                 filename, strerror(-rc));
435
436         rc = llapi_lease_check(fd);
437         ASSERTF(rc == 0,
438                 "invalid lease type on '%s': %s", filename, strerror(-rc));
439
440         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
441         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
442
443         close(fd);
444
445         /* Get a write lease, release and get again */
446         fd = open(filename, O_RDWR);
447         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
448
449         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
450         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
451
452         rc = llapi_lease_check(fd);
453         ASSERTF(rc == LL_LEASE_WRLCK,
454                 "invalid lease type on '%s': %s", filename, strerror(-rc));
455
456         rc = llapi_lease_put(fd);
457         ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
458                 filename, strerror(-rc));
459
460         rc = llapi_lease_check(fd);
461         ASSERTF(rc == 0,
462                 "invalid lease type on '%s': %s", filename, strerror(-rc));
463
464         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
465         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
466
467         close(fd);
468
469         /* Get and put lease in a loop */
470         fd = open(filename, O_RDWR);
471         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
472
473         for (i = 0; i < 1000; i++) {
474                 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
475                 ASSERTF(rc == 0, "cannot get lease '%s': %s",
476                         filename, strerror(-rc));
477
478                 rc = llapi_lease_put(fd);
479                 ASSERTF(rc == LL_LEASE_WRLCK,
480                         "was not able to put back lease '%s': %s",
481                         filename, strerror(-rc));
482
483                 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
484                 ASSERTF(rc == 0, "cannot get lease '%s': %s",
485                         filename, strerror(-rc));
486
487                 rc = llapi_lease_put(fd);
488                 ASSERTF(rc == LL_LEASE_RDLCK,
489                         "was not able to put back lease '%s': %s",
490                         filename, strerror(-rc));
491         }
492
493         close(fd);
494
495         /* Get a write lease, release and take a read one */
496         fd = open(filename, O_RDWR);
497         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
498
499         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
500         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
501
502         rc = llapi_lease_check(fd);
503         ASSERTF(rc == LL_LEASE_WRLCK,
504                 "invalid lease type on '%s': %s", filename, strerror(-rc));
505
506         rc = llapi_lease_put(fd);
507         ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
508                 filename, strerror(-rc));
509
510         rc = llapi_lease_check(fd);
511         ASSERTF(rc == 0,
512                 "invalid lease type on '%s': %s", filename, strerror(-rc));
513
514         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
515         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
516
517         close(fd);
518
519         /* Get a read lease, release and take a write one */
520         fd = open(filename, O_RDWR);
521         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
522
523         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
524         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
525
526         rc = llapi_lease_check(fd);
527         ASSERTF(rc == LL_LEASE_RDLCK,
528                 "invalid lease type on '%s': %s", filename, strerror(-rc));
529
530         rc = llapi_lease_put(fd);
531         ASSERTF(rc == LL_LEASE_RDLCK, "was not able to put back lease '%s': %s",
532                 filename, strerror(-rc));
533
534         rc = llapi_lease_check(fd);
535         ASSERTF(rc == 0,
536                 "invalid lease type on '%s': %s", filename, strerror(-rc));
537
538         rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
539         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
540
541         close(fd);
542
543         free(filename);
544 }
545
546 /* Lease on file opened by FID */
547 static void test16(void)
548 {
549         int rc;
550         char *filename;
551         int fd;
552         lustre_fid fid;
553
554         rc = mkdir(mainpath, 0);
555         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
556                 mainpath, strerror(errno));
557
558         filename = create_file_name("foo1");
559
560         fd = create_file("foo1", 1000, 'x');
561
562         rc = llapi_path2fid(filename, &fid);
563         ASSERTF(rc == 0, "llapi_path2fid failed for '%s': %s",
564                 filename, strerror(-rc));
565
566         close(fd);
567
568         fd = llapi_open_by_fid(fsmountdir, &fid,
569                                O_RDWR | O_NOATIME | O_NONBLOCK | O_NOFOLLOW);
570         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
571
572         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
573         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
574
575         close(fd);
576
577         free(filename);
578 }
579
580 /* Lease on directories */
581 static void test17(void)
582 {
583         int rc;
584         int fd;
585
586         /* On a directory */
587         rc = mkdir(mainpath, 0);
588         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
589                 mainpath, strerror(errno));
590
591         fd = open(mainpath, O_DIRECTORY);
592         ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
593
594         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
595         ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
596                 mainpath, strerror(-rc));
597
598         close(fd);
599
600         /* On lustre mountpoint */
601         fd = open(fsmountdir, O_DIRECTORY);
602         ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
603
604         rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
605         ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
606                 mainpath, strerror(-rc));
607
608         close(fd);
609 }
610
611 /* Read then swap */
612 static void test20(void)
613 {
614         int rc;
615         int fd1;
616         int fd2;
617         size_t foo1_size = 2000;
618         size_t foo2_size = 5000;
619         char buf[100];
620         off_t offset;
621         struct stat stbuf;
622
623         rc = mkdir(mainpath, 0);
624         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
625                 mainpath, strerror(errno));
626
627         fd1 = create_file("foo1", foo1_size, 'x');
628         fd2 = create_file("foo2", foo2_size, 'y');
629
630         /* foo2 is bigger than foo1. Read a byte in foo2, past foo1_size. */
631         offset = lseek(fd2, foo1_size + 100, SEEK_SET);
632         ASSERTF(offset == foo1_size + 100, "lseek to pos %zu failed: %s",
633                 foo1_size + 100, strerror(errno));
634
635         rc = read(fd2, buf, 1);
636         ASSERTF(rc == 1, "read 1 byte on foo2 failed: %s, rc=%d",
637                 strerror(errno), rc);
638         ASSERTF(buf[0] == 'y', "invalid data found on foo2: %x", buf[0]);
639
640         /* Now swap */
641         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
642         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
643                 strerror(-rc));
644
645         /* Read from fd1. Its file pointer is now positioned inside
646          * the new data. */
647         rc = read(fd1, buf, 1);
648         ASSERTF(rc == 1, "read 1 byte on foo1 failed: %s", strerror(errno));
649         ASSERTF(buf[0] == 'y', "invalid data found on foo2: %x", buf[0]);
650
651         rc = fstat(fd2, &stbuf);
652         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
653         ASSERTF(stbuf.st_size == foo1_size,
654                 "invalid size found: %llu instead of %zu",
655                 (unsigned long long)stbuf.st_size, foo1_size);
656
657         /* Read from fd2. After the swap, the file pointer is past the
658          * data. */
659         rc = read(fd2, buf, 1);
660         ASSERTF(rc == 0, "unexpected read returned rc=%d (errno %s)",
661                 rc, strerror(errno));
662
663         rc = close(fd1);
664         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
665
666         rc = close(fd2);
667         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
668 }
669
670 /* Test multiple swaps between 2 files */
671 static void test30(void)
672 {
673         int rc;
674         int fd1;
675         int fd2;
676         size_t foo1_size = 2000;
677         size_t foo2_size = 5000;
678         int i;
679         struct stat stbuf;
680
681         rc = mkdir(mainpath, 0);
682         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
683                 mainpath, strerror(errno));
684
685         fd1 = create_file("foo1", foo1_size, 'x');
686         fd2 = create_file("foo2", foo2_size, 'y');
687
688         for (i = 0; i < 1000; i++) {
689                 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
690                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
691                         strerror(-rc));
692
693                 rc = fstat(fd1, &stbuf);
694                 ASSERTF(rc == 0, "stat failed on 'foo1': %s", strerror(errno));
695                 ASSERTF(stbuf.st_size == i % 2 ? foo2_size : foo1_size,
696                         "invalid size found: %llu instead of %zu",
697                         (unsigned long long)stbuf.st_size,
698                         i % 2 ? foo2_size : foo1_size);
699
700                 rc = fstat(fd2, &stbuf);
701                 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
702                 ASSERTF(stbuf.st_size == i % 2 ? foo1_size : foo2_size,
703                         "invalid size found: %llu instead of %zu",
704                         (unsigned long long)stbuf.st_size,
705                         i % 2 ? foo1_size : foo2_size);
706         }
707
708         close(fd1);
709         close(fd2);
710 }
711
712 /* Test multiple swaps between 3 files */
713 static void test31(void)
714 {
715         int rc;
716         int fd1;
717         int fd2;
718         int fd3;
719         size_t foo1_size = 2000;
720         size_t foo2_size = 5000;
721         size_t foo3_size = 8000;
722         int i;
723         struct stat stbuf;
724
725
726         rc = mkdir(mainpath, 0);
727         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
728                 mainpath, strerror(errno));
729
730         fd1 = create_file("foo1", foo1_size, 'x');
731         fd2 = create_file("foo2", foo2_size, 'y');
732         fd3 = create_file("foo3", foo3_size, 'z');
733
734         /* Note: swapping 3 fd this way will be back to original
735          * layouts every 2 loops. */
736         for (i = 0; i < 999; i++) {
737                 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
738                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
739                         strerror(-rc));
740
741                 rc = llapi_fswap_layouts(fd2, fd3, 0, 0, 0);
742                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
743                         strerror(-rc));
744
745                 rc = llapi_fswap_layouts(fd1, fd3, 0, 0, 0);
746                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
747                         strerror(-rc));
748         }
749
750         rc = fstat(fd1, &stbuf);
751         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
752         ASSERTF(stbuf.st_size == foo1_size,
753                 "invalid size found: %llu instead of %zu",
754                 (unsigned long long)stbuf.st_size, foo1_size);
755
756         rc = fstat(fd2, &stbuf);
757         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
758         ASSERTF(stbuf.st_size == foo3_size,
759                 "invalid size found: %llu instead of %zu",
760                 (unsigned long long)stbuf.st_size, foo3_size);
761
762         rc = fstat(fd3, &stbuf);
763         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
764         ASSERTF(stbuf.st_size == foo2_size,
765                 "invalid size found: %llu instead of %zu",
766                 (unsigned long long)stbuf.st_size, foo2_size);
767
768         close(fd1);
769         close(fd2);
770         close(fd3);
771 }
772
773 /* Swap with lease */
774 static void test40(void)
775 {
776         int rc;
777         int fd1;
778         int fd2;
779         size_t foo1_size = 2000;
780         size_t foo2_size = 5000;
781
782         rc = mkdir(mainpath, 0);
783         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
784                 mainpath, strerror(errno));
785
786         fd1 = create_file("foo1", foo1_size, 'x');
787         fd2 = create_file("foo2", foo2_size, 'y');
788
789         rc = llapi_lease_get(fd1, LL_LEASE_RDLCK);
790         ASSERTF(rc == 0, "cannot get lease '%s': %s", mainpath, strerror(-rc));
791
792         rc = llapi_lease_check(fd1);
793         ASSERTF(rc == LL_LEASE_RDLCK,
794                 "invalid lease type on '%s': %s", mainpath, strerror(-rc));
795
796         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
797         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
798                 strerror(-rc));
799
800         rc = llapi_lease_check(fd1);
801         ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
802
803         rc = llapi_lease_put(fd1);
804         ASSERTF(rc == -ENOLCK,
805                 "was able to put back lease: %s", strerror(-rc));
806
807         rc = llapi_lease_check(fd1);
808         ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
809
810         rc = close(fd1);
811         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
812
813         rc = close(fd2);
814         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
815 }
816
817 /* Swap with close but no lease */
818 static void test41(void)
819 {
820         int rc;
821         int fd1;
822         int fd2;
823         size_t foo1_size = 2000;
824         size_t foo2_size = 5000;
825
826         rc = mkdir(mainpath, 0);
827         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
828                 mainpath, strerror(errno));
829
830         fd1 = create_file("foo1", foo1_size, 'x');
831         fd2 = create_file("foo2", foo2_size, 'y');
832
833         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
834         ASSERTF(rc == -ENOLCK, "llapi_fswap_layouts failed: %s",
835                 strerror(-rc));
836
837         /* swap failed, so fd1 has to be closed. */
838         rc = close(fd1);
839         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
840
841         rc = close(fd2);
842         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
843 }
844
845 /* swap with data versions */
846 static void test42(void)
847 {
848         int rc;
849         int fd1;
850         int fd2;
851         size_t foo1_size = 2000;
852         size_t foo2_size = 5000;
853         __u64 dv1 = 0;
854         __u64 dv2 = 0;
855         __u64 new_dv1 = 0;
856         __u64 new_dv2 = 0;
857         __u64 new_new_dv1 = 0;
858         __u64 new_new_dv2 = 0;
859         char *name_fd1;
860         char *name_fd2;
861
862         rc = mkdir(mainpath, 0);
863         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
864                 mainpath, strerror(errno));
865
866         /* Get dataversion for two files.
867          * Make sure values are different so that the following checks make
868          * sense. */
869         fd1 = create_file("foo1", foo1_size, 'x');
870
871         rc = llapi_get_data_version(fd1, &dv1, LL_DV_RD_FLUSH);
872         ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
873         ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
874
875         for (;;) {
876                 fd2 = create_file("foo2", foo2_size, 'y');
877
878                 rc = llapi_get_data_version(fd2, &dv2, LL_DV_RD_FLUSH);
879                 ASSERTF(rc == 0, "cannot get dataversion for fd2: %s",
880                         strerror(-rc));
881                 ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
882
883                 if (dv1 != dv2)
884                         break;
885
886                 close(fd2);
887         }
888
889         /* swaps that should fail */
890         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV1);
891         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
892
893         rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
894                                  SWAP_LAYOUTS_CHECK_DV1);
895         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
896
897         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV2);
898         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
899
900         rc = llapi_fswap_layouts(fd1, fd2, 0, dv2 + 987654,
901                                  SWAP_LAYOUTS_CHECK_DV2);
902         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
903
904         rc = llapi_fswap_layouts(fd1, fd2, 0, 0,
905                                  SWAP_LAYOUTS_CHECK_DV1 |
906                                  SWAP_LAYOUTS_CHECK_DV2);
907         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
908
909         rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
910                                  SWAP_LAYOUTS_CHECK_DV1 |
911                                  SWAP_LAYOUTS_CHECK_DV2);
912         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
913
914         rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, dv2 + 987654,
915                                  SWAP_LAYOUTS_CHECK_DV1 |
916                                  SWAP_LAYOUTS_CHECK_DV2);
917         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
918
919         rc = llapi_fswap_layouts(fd1, fd2, dv1, 0,
920                                  SWAP_LAYOUTS_CHECK_DV1 |
921                                  SWAP_LAYOUTS_CHECK_DV2);
922         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
923
924         rc = llapi_fswap_layouts(fd1, fd2, 0, dv2,
925                                  SWAP_LAYOUTS_CHECK_DV1 |
926                                  SWAP_LAYOUTS_CHECK_DV2);
927         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
928
929         rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2 + 567,
930                                  SWAP_LAYOUTS_CHECK_DV1 |
931                                  SWAP_LAYOUTS_CHECK_DV2);
932         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
933
934         printf("DV = %llx and %llx\n", dv1, dv2);
935
936         /* Finally, a good swap */
937         rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
938                                  SWAP_LAYOUTS_CHECK_DV1 |
939                                  SWAP_LAYOUTS_CHECK_DV2);
940         ASSERTF(rc == 0, "incorrect return from swap: %s", strerror(-rc));
941
942         /* Check dataversion. */
943         rc = llapi_get_data_version(fd1, &new_dv1, LL_DV_RD_FLUSH);
944         ASSERTF(rc == 0,
945                 "cannot get new dataversion for fd1: %s", strerror(-rc));
946         ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
947         ASSERTF(dv1 != new_dv1, "got identical dataversion for fd1: %llx", dv1);
948
949         rc = llapi_get_data_version(fd2, &new_dv2, LL_DV_RD_FLUSH);
950         ASSERTF(rc == 0,
951                 "cannot get new dataversion for fd2: %s", strerror(-rc));
952         ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
953         ASSERTF(dv2 != new_dv2, "got identical dataversion for fd2: %llx", dv1);
954
955         printf("new DV = %llx and %llx\n", new_dv1, new_dv2);
956
957         /* Try again with same parameters. */
958         rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
959                                  SWAP_LAYOUTS_CHECK_DV1 |
960                                  SWAP_LAYOUTS_CHECK_DV2);
961         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
962
963         close(fd1);
964         close(fd2);
965
966         /* Reopen the files and check again the dataversion */
967         name_fd1 = create_file_name("foo1");
968         fd1 = open(name_fd1, O_RDONLY);
969         ASSERTF(fd1 >= 0,
970                 "open failed for '%s': %s", name_fd1, strerror(errno));
971
972         rc = llapi_get_data_version(fd1, &new_new_dv1, LL_DV_RD_FLUSH);
973         ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
974         ASSERTF(new_new_dv1 != 0, "got dataversion 0 for fd1");
975         ASSERTF(new_dv1 == new_new_dv1,
976                 "dataversion changed after re-opening: %llx and %llx",
977                 new_dv1, new_new_dv1);
978
979         name_fd2 = create_file_name("foo2");
980         fd2 = open(name_fd2, O_RDONLY);
981         ASSERTF(fd2 >= 0,
982                 "open failed for '%s': %s", name_fd2, strerror(errno));
983
984         rc = llapi_get_data_version(fd2, &new_new_dv2, LL_DV_RD_FLUSH);
985         ASSERTF(rc == 0, "cannot get dataversion for fd2: %s", strerror(-rc));
986         ASSERTF(new_new_dv2 != 0, "got dataversion 0 for fd2");
987         ASSERTF(new_dv2 == new_new_dv2,
988                 "dataversion changed after re-opening: %llx and %llx",
989                 new_dv2, new_new_dv2);
990
991         printf("DV= %llx and %llx\n", new_new_dv1, new_new_dv2);
992
993         close(fd1);
994         close(fd2);
995
996         free(name_fd1);
997         free(name_fd2);
998 }
999
1000 /* swap group lock, no group */
1001 static void test50(void)
1002 {
1003         int rc;
1004         int fd1;
1005         int fd2;
1006         size_t foo1_size = 2000;
1007         size_t foo2_size = 5000;
1008
1009         rc = mkdir(mainpath, 0);
1010         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1011                 mainpath, strerror(errno));
1012
1013         fd1 = create_file("foo1", foo1_size, 'x');
1014         fd2 = create_file("foo2", foo2_size, 'y');
1015
1016         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1017         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1018                 strerror(-rc));
1019
1020         close(fd1);
1021         close(fd2);
1022 }
1023
1024 /* swap group lock, with group */
1025 static void test51(void)
1026 {
1027         int rc;
1028         int fd1;
1029         int fd2;
1030         size_t foo1_size = 2000;
1031         size_t foo2_size = 5000;
1032
1033         rc = mkdir(mainpath, 0);
1034         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1035                 mainpath, strerror(errno));
1036
1037         fd1 = create_file("foo1", foo1_size, 'x');
1038         fd2 = create_file("foo2", foo2_size, 'y');
1039
1040         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 456789, 0);
1041         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1042                 strerror(-rc));
1043
1044         close(fd1);
1045         close(fd2);
1046 }
1047
1048 /* swap group lock, with existing group locks */
1049 static void test52(void)
1050 {
1051         int rc;
1052         int fd1;
1053         int fd2;
1054         size_t foo1_size = 2000;
1055         size_t foo2_size = 5000;
1056         int gid = 7356;
1057
1058         rc = mkdir(mainpath, 0);
1059         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1060                 mainpath, strerror(errno));
1061
1062         fd1 = create_file("foo1", foo1_size, 'x');
1063         fd2 = create_file("foo2", foo2_size, 'y');
1064
1065         /* lock a descriptor, but swap without */
1066         rc = llapi_group_lock(fd1, gid);
1067         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1068
1069         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1070         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1071                 strerror(-rc));
1072
1073         rc = llapi_group_unlock(fd1, gid);
1074         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1075
1076         close(fd1);
1077         close(fd2);
1078 }
1079
1080 /* Swap group lock, with existing group locks, on second descriptor */
1081 static void test53(void)
1082 {
1083         int rc;
1084         int fd1;
1085         int fd2;
1086         size_t foo1_size = 2000;
1087         size_t foo2_size = 5000;
1088         int gid = 7356;
1089
1090         rc = mkdir(mainpath, 0);
1091         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1092                 mainpath, strerror(errno));
1093
1094         fd1 = create_file("foo1", foo1_size, 'x');
1095         fd2 = create_file("foo2", foo2_size, 'y');
1096
1097         /* lock a descriptor, but swap without */
1098         rc = llapi_group_lock(fd2, gid);
1099         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1100
1101         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1102         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1103                 strerror(-rc));
1104
1105         rc = llapi_group_unlock(fd2, gid);
1106         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1107
1108         close(fd1);
1109         close(fd2);
1110 }
1111
1112 /* swap group lock, lock a descriptor, and try to swap with it. */
1113 static void test54(void)
1114 {
1115         int rc;
1116         int fd1;
1117         int fd2;
1118         size_t foo1_size = 2000;
1119         size_t foo2_size = 5000;
1120         int gid;
1121
1122         rc = mkdir(mainpath, 0);
1123         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1124                 mainpath, strerror(errno));
1125
1126         fd1 = create_file("foo1", foo1_size, 'x');
1127         fd2 = create_file("foo2", foo2_size, 'y');
1128
1129         gid = 7356;
1130         rc = llapi_group_lock(fd1, gid);
1131         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1132
1133         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1134         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1135                 strerror(-rc));
1136
1137         rc = llapi_group_unlock(fd1, gid);
1138         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1139
1140         close(fd1);
1141         close(fd2);
1142 }
1143
1144 /* Swap group lock, lock a descriptor, and try to swap with it, on
1145  * second descriptor. */
1146 static void test55(void)
1147 {
1148         int rc;
1149         int fd1;
1150         int fd2;
1151         size_t foo1_size = 2000;
1152         size_t foo2_size = 5000;
1153         int gid = 7356;
1154
1155         rc = mkdir(mainpath, 0);
1156         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1157                 mainpath, strerror(errno));
1158
1159         fd1 = create_file("foo1", foo1_size, 'x');
1160         fd2 = create_file("foo2", foo2_size, 'y');
1161
1162         rc = llapi_group_lock(fd2, gid);
1163         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1164
1165         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1166         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1167                 strerror(-rc));
1168
1169         rc = llapi_group_unlock(fd2, gid);
1170         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1171
1172         close(fd1);
1173         close(fd2);
1174 }
1175
1176 /* Swap group lock, lock a descriptor, and try to swap with another
1177  * one. */
1178 static void test56(void)
1179 {
1180         int rc;
1181         int fd1;
1182         int fd2;
1183         size_t foo1_size = 2000;
1184         size_t foo2_size = 5000;
1185         int gid1 = 78976;
1186         int gid2 = 3458;
1187
1188         rc = mkdir(mainpath, 0);
1189         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1190                 mainpath, strerror(errno));
1191
1192         fd1 = create_file("foo1", foo1_size, 'x');
1193         fd2 = create_file("foo2", foo2_size, 'y');
1194
1195         rc = llapi_group_lock(fd1, gid1);
1196         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1197
1198         rc = llapi_group_lock(fd2, gid2);
1199         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1200
1201         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1202         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1203                 strerror(-rc));
1204
1205         rc = llapi_group_unlock(fd1, gid1);
1206         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1207
1208         rc = llapi_group_unlock(fd2, gid2);
1209         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1210
1211         close(fd1);
1212         close(fd2);
1213 }
1214
1215 /* Swap group lock, lock both descriptor, and try to swap with another
1216  * one. */
1217 static void test57(void)
1218 {
1219         int rc;
1220         int fd1;
1221         int fd2;
1222         size_t foo1_size = 2000;
1223         size_t foo2_size = 5000;
1224         int gid1 = 78976;
1225         int gid2 = 3458;
1226
1227         rc = mkdir(mainpath, 0);
1228         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1229                 mainpath, strerror(errno));
1230
1231         fd1 = create_file("foo1", foo1_size, 'x');
1232         fd2 = create_file("foo2", foo2_size, 'y');
1233
1234         rc = llapi_group_lock(fd1, gid1);
1235         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1236
1237         rc = llapi_group_lock(fd2, gid2);
1238         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1239
1240         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid1+gid2, 0);
1241         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1242                 strerror(-rc));
1243
1244         rc = llapi_group_unlock(fd1, gid1);
1245         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1246
1247         rc = llapi_group_unlock(fd2, gid2);
1248         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1249
1250         close(fd1);
1251         close(fd2);
1252 }
1253
1254 /* Swap group lock, lock both descriptor with same gid, and try to
1255  * swap with it. */
1256 static void test58(void)
1257 {
1258         int rc;
1259         int fd1;
1260         int fd2;
1261         size_t foo1_size = 2000;
1262         size_t foo2_size = 5000;
1263         int gid = 6458907;
1264
1265         rc = mkdir(mainpath, 0);
1266         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1267                 mainpath, strerror(errno));
1268
1269         fd1 = create_file("foo1", foo1_size, 'x');
1270         fd2 = create_file("foo2", foo2_size, 'y');
1271
1272         rc = llapi_group_lock(fd1, gid);
1273         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1274
1275         rc = llapi_group_lock(fd2, gid);
1276         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1277
1278         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1279         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1280                 strerror(-rc));
1281
1282         rc = llapi_group_unlock(fd1, gid);
1283         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1284
1285         rc = llapi_group_unlock(fd2, gid);
1286         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1287
1288         close(fd1);
1289         close(fd2);
1290 }
1291
1292 /* Swap group lock, lock both descriptor with same gid, and swap with
1293  * none. */
1294 static void test59(void)
1295 {
1296         int rc;
1297         int fd1;
1298         int fd2;
1299         size_t foo1_size = 2000;
1300         size_t foo2_size = 5000;
1301         int gid = 6458907;
1302
1303         rc = mkdir(mainpath, 0);
1304         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1305                 mainpath, strerror(errno));
1306
1307         fd1 = create_file("foo1", foo1_size, 'x');
1308         fd2 = create_file("foo2", foo2_size, 'y');
1309
1310         rc = llapi_group_lock(fd1, gid);
1311         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1312
1313         rc = llapi_group_lock(fd2, gid);
1314         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1315
1316         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1317         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1318                 strerror(-rc));
1319
1320         rc = llapi_group_unlock(fd1, gid);
1321         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1322
1323         rc = llapi_group_unlock(fd2, gid);
1324         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1325
1326         close(fd1);
1327         close(fd2);
1328 }
1329
1330 static void usage(char *prog)
1331 {
1332         fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1333         exit(EXIT_FAILURE);
1334 }
1335
1336 static void process_args(int argc, char *argv[])
1337 {
1338         int c;
1339
1340         while ((c = getopt(argc, argv, "d:")) != -1) {
1341                 switch (c) {
1342                 case 'd':
1343                         lustre_dir = optarg;
1344                         break;
1345                 case '?':
1346                 default:
1347                         fprintf(stderr, "Unknown option '%c'\n", optopt);
1348                         usage(argv[0]);
1349                         break;
1350                 }
1351         }
1352 }
1353
1354 int main(int argc, char *argv[])
1355 {
1356         char fsname[8 + 1];
1357         int rc;
1358
1359         process_args(argc, argv);
1360         if (lustre_dir == NULL)
1361                 lustre_dir = "/mnt/lustre";
1362
1363         rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1364         if (rc != 0) {
1365                 fprintf(stderr, "Error: '%s': not a Lustre filesystem\n",
1366                         lustre_dir);
1367                 return EXIT_FAILURE;
1368         }
1369
1370         /* Play nice with Lustre test scripts. Non-line buffered output
1371          * stream under I/O redirection may appear incorrectly. */
1372         setvbuf(stdout, NULL, _IOLBF, 0);
1373
1374         /* Create a test filename and reuse it. Remove possibly old files. */
1375         rc = snprintf(mainpath, sizeof(mainpath), "%s/%s", lustre_dir, maindir);
1376         ASSERTF(rc > 0 && rc < sizeof(mainpath), "invalid name for mainpath");
1377
1378         atexit(cleanup);
1379
1380         PERFORM(test10);
1381         PERFORM(test11);
1382         PERFORM(test12);
1383         PERFORM(test13);
1384         PERFORM(test14);
1385         PERFORM(test15);
1386         PERFORM(test16);
1387         PERFORM(test17);
1388         PERFORM(test20);
1389         PERFORM(test30);
1390         PERFORM(test31);
1391         PERFORM(test40);
1392         PERFORM(test41);
1393         PERFORM(test42);
1394         PERFORM(test50);
1395         PERFORM(test51);
1396         PERFORM(test52);
1397         PERFORM(test53);
1398         PERFORM(test54);
1399         PERFORM(test55);
1400         PERFORM(test56);
1401         PERFORM(test57);
1402         PERFORM(test58);
1403         PERFORM(test59);
1404
1405         return EXIT_SUCCESS;
1406 }