xfs: test that reflink forces the log if mounted with wsync
[xfstests-dev.git] / src / truncfile.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6  
7 #include "global.h"
8
9 long filesize;
10 int blocksize;
11 int count;
12 int verbose;
13 off64_t fileoffset;
14
15 void usage(char *progname);
16 void writeblk(int fd);
17 void truncfile(int fd);
18
19 void
20 usage(char *progname)
21 {
22         fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-c count] [-s seed] [-o fileoffset (hex)] [-v] filename\n",
23                         progname);
24         exit(1);
25 }
26
27 int
28 main(int argc, char *argv[])
29 {
30         int seed, i, ch, fd;
31         char *filename = NULL;
32
33         filesize = 256*1024*1024;
34         blocksize = 512;
35         count = filesize/blocksize;
36         verbose = 0;
37         fileoffset = 0;
38         seed = time(NULL);
39         while ((ch = getopt(argc, argv, "b:l:s:c:o:v")) != EOF) {
40                 switch(ch) {
41                 case 'b':       blocksize  = atoi(optarg);      break;
42                 case 'l':       filesize   = atol(optarg);      break;
43                 case 's':       seed       = atoi(optarg);      break;
44                 case 'c':       count      = atoi(optarg);      break;
45                 case 'o':       fileoffset = strtoll(optarg, NULL, 16); break;
46                 case 'v':       verbose++;                      break;
47                 default:        usage(argv[0]);                 break;
48                 }
49         }
50         if (optind == argc-1)
51                 filename = argv[optind];
52         else
53                 usage(argv[0]);
54         printf("Seed = %d (use \"-s %d\" to re-execute this test)\n", seed, seed);
55         srandom(seed);
56
57         /*
58          * Open the file, write rand block in random places, truncate the file,
59          * repeat ad-nauseum, then close the file.
60          */
61         if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
62                 perror("open");
63                 return 1;
64         }
65         for (i = 0; i < count; i++) {
66                 writeblk(fd);
67                 truncfile(fd);
68                 if (verbose && ((i % 100) == 0)) {
69                         printf(".");
70                         fflush(stdout);
71                 }
72         }
73         if (close(fd) < 0) {
74                 perror("close");
75                 return 1;
76         }
77         return 0;
78 }
79
80 void
81 writeblk(int fd)
82 {
83         off_t offset;
84         static char *buffer = NULL;
85
86         if ((buffer == NULL) && ((buffer = calloc(1, blocksize)) == NULL)) {
87                 perror("malloc");
88                 exit(1);
89         }
90
91         offset = random() % filesize;
92         if (lseek64(fd, (off64_t)(fileoffset + offset), SEEK_SET) < 0) {
93                 perror("lseek");
94                 exit(1);
95         }
96         *(long *)buffer = *(long *)(buffer+256) = (long)offset;
97         if (write(fd, buffer, blocksize) < blocksize) {
98                 perror("write");
99                 exit(1);
100         }
101         if (verbose > 1)
102                 printf("writing   data at offset=%llx\n",
103                        (unsigned long long)(fileoffset + offset));
104 }
105
106 void
107 truncfile(int fd)
108 {
109         off_t offset;
110
111         offset = random() % filesize;
112         if (ftruncate64(fd, (off64_t)(fileoffset + offset)) < 0) {
113                 perror("truncate");
114                 exit(1);
115         }
116         if (verbose > 1)
117                 printf("truncated file to offset %llx\n",
118                        (unsigned long long)(fileoffset + offset));
119 }