+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <dirent.h>
-#include <malloc.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <attr/attributes.h>
-
-typedef unsigned int uint_t;
-
-/*
- * Loop over directory sizes:
- * make m directories
- * touch n files in each directory
- * write y bytes to all files in each directory
- * set DMF attribute on x files in each directory
- * Change directory sizes by multiplication or addition.
- * Allow control of starting & stopping sizes, name length, target directory.
- * Print size and wallclock time (ms per file).
- * Output can be used to make graphs (gnuplot)
- */
-
-static uint_t addval;
-static uint_t dirchars;
-static char *directory;
-static uint_t firstsize;
-static uint_t lastsize;
-static uint_t minchars;
-static double mulval;
-static uint_t nchars;
-static uint_t ndirs;
-static uint_t pfxchars;
-static off64_t fsize;
-static char *buffer;
-static size_t bsize;
-
-static int mkfile(char *, char *);
-static void filename(int, int, char *);
-static int hexchars(uint_t);
-static uint_t nextsize(uint_t);
-static double now(void);
-static void usage(void);
-
-/*
- * Maximum size allowed, this is pretty nuts.
- * The largest one we've ever built has been about 2 million.
- */
-#define MAX_DIR_SIZE (16 * 1024 * 1024)
-#define DFL_FIRST_SIZE 1
-#define DFL_LAST_SIZE (1024 * 1024)
-#define MAX_DIR_COUNT 1024
-#define MIN_DIR_COUNT 1
-
-#define DMFATTRLEN 22
-#define DMFATTRNAME "SGI_DMI_DMFATTR"
-
-int
-main(int argc, char **argv)
-{
- int c;
- uint_t cursize;
- int i;
- int j;
- char name[NAME_MAX + 1];
- char attr[DMFATTRLEN];
- double stime;
-
- while ((c = getopt(argc, argv, "a:b:c:d:f:l:m:n:s:")) != -1) {
- switch (c) {
- case 'a':
- addval = (uint_t)atoi(optarg);
- break;
- case 'b':
- bsize = (size_t)atol(optarg);
- break;
- case 'c':
- nchars = (uint_t)atoi(optarg);
- break;
- case 'd':
- directory = optarg;
- break;
- case 'f':
- firstsize = (uint_t)atoi(optarg);
- break;
- case 'l':
- lastsize = (uint_t)atoi(optarg);
- break;
- case 'm':
- mulval = atof(optarg);
- break;
- case 'n':
- ndirs = (uint_t)atoi(optarg);
- break;
- case 's':
- fsize = (off64_t)atol(optarg);
- break;
- case '?':
- default:
- usage();
- exit(1);
- }
- }
- if (!addval && !mulval)
- mulval = 2.0;
- else if ((addval && mulval) || mulval < 0.0) {
- usage();
- exit(1);
- }
- if (!bsize)
- bsize = 1024 * 1024;
- buffer = memalign(getpagesize(), bsize);
- memset(buffer, 0xfeed, bsize);
- memset(attr, 0xaaaaaaa, sizeof(attr));
-
- if (!directory)
- directory = ".";
- else {
- if (mkdir(directory, 0777) < 0 && errno != EEXIST) {
- perror(directory);
- exit(1);
- }
- if (chdir(directory) < 0) {
- perror(directory);
- exit(1);
- }
- }
- if (firstsize == 0)
- firstsize = DFL_FIRST_SIZE;
- else if (firstsize > MAX_DIR_SIZE)
- firstsize = MAX_DIR_SIZE;
- if (lastsize == 0)
- lastsize = DFL_LAST_SIZE;
- else if (lastsize > MAX_DIR_SIZE)
- lastsize = MAX_DIR_SIZE;
- if (lastsize < firstsize)
- lastsize = firstsize;
- minchars = hexchars(lastsize - 1);
- if (nchars < minchars)
- nchars = minchars;
- else if (nchars >= NAME_MAX + 1)
- nchars = NAME_MAX;
- if (ndirs > MAX_DIR_COUNT)
- ndirs = MAX_DIR_COUNT;
- if (ndirs < MIN_DIR_COUNT)
- ndirs = MIN_DIR_COUNT;
- dirchars = hexchars(ndirs);
- pfxchars = nchars - minchars;
- if (pfxchars)
- memset(&name[dirchars + 1], 'a', pfxchars);
-
- cursize = firstsize;
- for (j = 0; j < ndirs; j++) {
- filename(0, j, name);
- name[dirchars] = '\0';
- mkdir(name, 0777);
- stime = now();
- for (i = 0; i < cursize; i++) {
- filename((i + j) % cursize, j, name);
- close(mkfile(name, attr));
- }
- printf("%d %.3f\n", cursize,
- (now() - stime) * 1.0e3 / (cursize * ndirs));
- cursize = nextsize(cursize);
- }
- return 0;
-}
-
-static int
-mkfile(char *name, char *attr)
-{
- int fd;
- ssize_t wrote, wsize;
- off64_t bytes = fsize;
-
- if ((fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_DIRECT, 0666)) < 0) {
- perror("open");
- exit(1);
- }
- if (attr_setf(fd, DMFATTRNAME, attr, DMFATTRLEN, ATTR_ROOT) < 0) {
- perror("attr_setf");
- exit(1);
- }
- while (bytes > 0) {
- wsize = (bsize < bytes) ? bsize : bytes;
- if ((wrote = write(fd, buffer, wsize)) < 0) {
- perror("write");
- exit(1);
- }
- bytes -= wrote;
- }
- return fd;
-}
-
-static void
-filename(int idx, int dir, char *name)
-{
- static char hexc[16] = "0123456789abcdef";
- int i;
-
- for (i = dirchars - 1; i >= 0; i--)
- *name++ = hexc[(dir >> (4 * i)) & 0xf];
- *name++ = '/';
- name += pfxchars; /* skip pfx a's */
- for (i = minchars - 1; i >= 0; i--)
- *name++ = hexc[(idx >> (4 * i)) & 0xf];
- *name = '\0';
-}
-
-static int
-hexchars(uint_t maxval)
-{
- if (maxval < 16)
- return 1;
- if (maxval < 16 * 16)
- return 2;
- if (maxval < 16 * 16 * 16)
- return 3;
- if (maxval < 16 * 16 * 16 * 16)
- return 4;
- if (maxval < 16 * 16 * 16 * 16 * 16)
- return 5;
- if (maxval < 16 * 16 * 16 * 16 * 16 * 16)
- return 6;
- if (maxval < 16 * 16 * 16 * 16 * 16 * 16 * 16)
- return 7;
- return 8;
-}
-
-static uint_t
-nextsize(uint_t cursize)
-{
- double n;
-
- n = cursize;
- if (addval)
- n += addval;
- else
- n *= mulval;
- if (n > (double)lastsize + 0.5)
- return lastsize + 1; /* i.e. out of bounds */
- else if ((uint_t)n == cursize)
- return cursize + 1;
- else
- return (uint_t)n;
-}
-
-static double
-now(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- return (double)tv.tv_sec + 1.0e-6 * (double)tv.tv_usec;
-}
-
-static void
-usage(void)
-{
- fprintf(stderr,
- "usage: dirperf [-d dir] [-a addstep | -m mulstep] [-f first] "
- "[-l last] [-c nchars] [-n ndirs] [-s size]\n");
-}