generic: add fstests for idmapped mounts
[xfstests-dev.git] / src / makeextents.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2004 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6
7 /*
8  * Write a bunch of holes to create a bunch of extents.
9  */
10  
11 #include "global.h"
12
13 char *progname;
14 uint64_t num_holes = 1000;
15 uint64_t curr_holes;
16 int verbose_opt = 0;
17 char *filename;
18 int status_num = 100;
19 int wsync;
20 int preserve;
21 unsigned int blocksize;
22 uint64_t fileoffset;
23
24 #define JUMP_SIZE (128 * 1024)
25 #define NUMHOLES_TO_SIZE(i) (i * JUMP_SIZE)
26 #define SIZE_TO_NUMHOLES(s) (s / JUMP_SIZE)
27
28 void
29 usage(void)
30 {
31         fprintf(stderr, "%s [-b blocksize] [-n num-holes] [-s status-num]"
32                         " [-o start-offset] [-vwp] file\n", progname);
33         exit(1);
34 }
35
36 int
37 main(int argc, char *argv[])
38 {
39         int c;
40         int fd;
41         int oflags;
42         uint64_t i;
43         uint64_t offset;
44         int blocksize = 512;
45         unsigned char *buffer = NULL;
46         struct stat stat;
47
48         progname = argv[0];
49
50         while ((c = getopt(argc, argv, "b:n:o:ps:vw")) != -1) {
51                 switch (c) {
52                 case 'b':
53                         blocksize = atoi(optarg);
54                         break;
55                 case 'n':
56                         num_holes = atoll(optarg);
57                         break;
58                 case 'v':
59                         verbose_opt = 1;
60                         break;
61                 case 'w':
62                         wsync = 1;
63                         break;
64                 case 'p':
65                         preserve = 1;
66                         break;
67                 case 's':
68                         status_num = atoi(optarg);
69                         break;
70                 case 'o':
71                         fileoffset = strtoull(optarg, NULL, 16);
72                         break;
73                 case '?':
74                         usage();
75                 }
76         }
77         if (optind == argc-1)
78                 filename = argv[optind];
79         else
80                 usage();
81
82         buffer = malloc(blocksize);
83         if (buffer == NULL) {
84             fprintf(stderr, "%s: blocksize to big to allocate buffer\n", progname);
85             return 1;
86         }
87
88         oflags = O_RDWR | O_CREAT;
89         oflags |=   (preserve ? 0 : O_TRUNC) |
90                     (wsync ? O_SYNC : 0);
91         
92         if ((fd = open(filename, oflags, 0666)) < 0) {
93                 perror("open");
94                 return 1;
95         }
96
97         if (fstat(fd, &stat) < 0) {
98                 perror("stat");
99                 return 1;
100         }
101         if (preserve) {
102                 curr_holes = SIZE_TO_NUMHOLES(stat.st_size);
103                 if (num_holes < curr_holes) {
104                         /* we need to truncate back */
105                         if (ftruncate(fd, NUMHOLES_TO_SIZE(num_holes)) < 0) {
106                                 perror("ftruncate");
107                                 return 1;
108                         }
109                         if (verbose_opt) {
110                                 printf("truncating back to %llu\n",
111                                        (unsigned long long)
112                                         NUMHOLES_TO_SIZE(num_holes));
113                         }
114                         return 0;
115                 }
116         }
117         else {
118                 curr_holes = 0;
119         }
120         if (curr_holes != 0 && verbose_opt) {
121                 printf("creating %llu more holes\n",
122                         (unsigned long long)num_holes - curr_holes);
123         }
124                 
125         /* create holes by seeking and writing */
126         for (i = curr_holes; i < num_holes; i++) {
127
128                 offset = NUMHOLES_TO_SIZE(i) + fileoffset;
129
130                 if (lseek64(fd, offset, SEEK_SET) < 0) {
131                         perror("lseek");
132                         return 1;
133                 }
134
135                 if (write(fd, buffer, blocksize) < blocksize) {
136                         perror("write");
137                         return 1;
138                 }
139
140                 if (verbose_opt && ((i+1) % status_num == 0)) {
141                         printf("seeked and wrote %llu times\n",
142                                 (unsigned long long)i + 1);
143                 }
144         }
145
146         close(fd);
147
148         return 0;
149 }