// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2021 RedHat Inc. All Rights Reserved. * * mmap a file, alloc blocks, reading&writing blocks with overlapping. For example: * * |<--- block --->|<--- block --->| * len len * +---------------+---------------+ * |AAAA| ........ |AAAA| ........ | * +---------------+---------------+ * | | * | `------------+ * `-----------------------+ | * | | * V V * +---------------+---------------+----+ * |AAAA| ........ |AAAA| ... |AAAA|AAAA| * +---------------+---------------+----+ */ #include #include #include #include #include #include #include #include #include void usage(char *progname) { fprintf(stderr, "usage: %s [-b blocksize ] [-c count] [-l length] filename\n" "\tmmap $count * $blocksize bytes memory, pwritev $length bytes in each block. blocksize=4096, count=2, length=12 by default.\n" "e.g: %s -b 4096 -c 2 -l 12 filename\n", progname, progname); exit(1); } int main(int argc, char **argv) { char *filename = NULL; size_t bsize = 4096; size_t count = 2; size_t length = 12; int fd, i, c; void *base; char *buf, *cmp_buf; struct iovec *iov; int ret = 0; while ((c = getopt(argc, argv, "b:l:c:")) != -1) { char *endp; switch (c) { case 'b': bsize = strtoul(optarg, &endp, 0); break; case 'c': count = strtoul(optarg, &endp, 0); break; case 'l': length = strtoul(optarg, &endp, 0); break; default: usage(argv[0]); } } if (optind == argc - 1) filename = argv[optind]; else usage(argv[0]); if (length >= bsize) { printf("-l length must be less than -b blocksize\n"); usage(argv[0]); } fd = open(filename, O_RDWR); if (fd == -1) { fprintf(stderr, "open %s failed:%s\n", filename, strerror(errno)); exit(1); } base = mmap(NULL, bsize * count, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (base == MAP_FAILED) { fprintf(stderr, "mmap failed %s\n", strerror(errno)); exit(1); } /* Write each of blocks */ buf = malloc(length); memset(buf, 0xAA, length); for (i=0; i