1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2021 RedHat Inc. All Rights Reserved.
5 * mmap a file, alloc blocks, reading&writing blocks with overlapping. For example:
7 * |<--- block --->|<--- block --->|
9 * +---------------+---------------+
10 * |AAAA| ........ |AAAA| ........ |
11 * +---------------+---------------+
14 * `-----------------------+ |
17 * +---------------+---------------+----+
18 * |AAAA| ........ |AAAA| ... |AAAA|AAAA|
19 * +---------------+---------------+----+
21 #include <sys/types.h>
31 void usage(char *progname)
33 fprintf(stderr, "usage: %s [-b blocksize ] [-c count] [-l length] filename\n"
34 "\tmmap $count * $blocksize bytes memory, pwritev $length bytes in each block. blocksize=4096, count=2, length=12 by default.\n"
35 "e.g: %s -b 4096 -c 2 -l 12 filename\n",
40 int main(int argc, char **argv)
42 char *filename = NULL;
52 while ((c = getopt(argc, argv, "b:l:c:")) != -1) {
57 bsize = strtoul(optarg, &endp, 0);
60 count = strtoul(optarg, &endp, 0);
63 length = strtoul(optarg, &endp, 0);
70 if (optind == argc - 1)
71 filename = argv[optind];
75 if (length >= bsize) {
76 printf("-l length must be less than -b blocksize\n");
80 fd = open(filename, O_RDWR);
82 fprintf(stderr, "open %s failed:%s\n", filename, strerror(errno));
85 base = mmap(NULL, bsize * count, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
86 if (base == MAP_FAILED) {
87 fprintf(stderr, "mmap failed %s\n", strerror(errno));
91 /* Write each of blocks */
93 memset(buf, 0xAA, length);
94 for (i=0; i<count; i++) {
95 ret = pwrite(fd, buf, length, i * bsize);
97 fprintf(stderr, "pwrite failed %s\n", strerror(errno));
102 /* Copy from the beginning of each blocks ... */
103 iov = malloc(sizeof(struct iovec) * count);
104 for (i=0; i<count; i++) {
105 iov[i].iov_base = base + i * bsize;
106 iov[i].iov_len = length;
108 /* ... Write to the last block with offset ($bsize - $length) */
109 ret = pwritev(fd, iov, count, bsize * count - length);
111 fprintf(stderr, "pwritev failed %s\n", strerror(errno));
116 cmp_buf = malloc(length);
117 for (i=0; i<count; i++) {
118 ret = pread(fd, cmp_buf, length, bsize * count + (i - 1) * length);
120 fprintf(stderr, "pread failed %s\n", strerror(errno));
123 if (memcmp(buf, cmp_buf, length))
124 printf("Find corruption\n");
127 munmap(base, bsize * count);