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