"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-fallocate.c" (15 Mar 2019, 5058 Bytes) of package /linux/privat/stress-ng-0.09.56.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-fallocate.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.50_vs_0.09.51.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 int stress_set_fallocate_bytes(const char *opt)
   28 {
   29     off_t fallocate_bytes;
   30 
   31     fallocate_bytes = (off_t)get_uint64_byte_filesystem(opt, 1);
   32     check_range_bytes("fallocate-bytes", fallocate_bytes,
   33         MIN_FALLOCATE_BYTES, MAX_FALLOCATE_BYTES);
   34     return set_setting("fallocate-bytes", TYPE_ID_OFF_T, &fallocate_bytes);
   35 }
   36 
   37 #if defined(HAVE_FALLOCATE)
   38 
   39 static const int modes[] = {
   40     0,
   41 #if defined(FALLOC_FL_KEEP_SIZE)
   42     FALLOC_FL_KEEP_SIZE,
   43 #endif
   44 #if defined(FALLOC_FL_KEEP_SIZE) && defined(FALLOC_FL_PUNCH_HOLE)
   45     FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
   46 #endif
   47 #if defined(FALLOC_FL_ZERO_RANGE)
   48     FALLOC_FL_ZERO_RANGE,
   49 #endif
   50 #if defined(FALLOC_FL_COLLAPSE_RANGE)
   51     FALLOC_FL_COLLAPSE_RANGE,
   52 #endif
   53 #if defined(FALLOC_FL_INSERT_RANGE)
   54     FALLOC_FL_INSERT_RANGE,
   55 #endif
   56 };
   57 
   58 /*
   59  *  stress_fallocate
   60  *  stress I/O via fallocate and ftruncate
   61  */
   62 static int stress_fallocate(const args_t *args)
   63 {
   64     int fd, ret;
   65     char filename[PATH_MAX];
   66     uint64_t ftrunc_errs = 0;
   67     off_t fallocate_bytes = DEFAULT_FALLOCATE_BYTES;
   68 
   69     if (!get_setting("fallocate-bytes", &fallocate_bytes)) {
   70         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
   71             fallocate_bytes = MAX_FALLOCATE_BYTES;
   72         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
   73             fallocate_bytes = MIN_FALLOCATE_BYTES;
   74     }
   75 
   76     fallocate_bytes /= args->num_instances;
   77     if (fallocate_bytes < (off_t)MIN_FALLOCATE_BYTES)
   78         fallocate_bytes = (off_t)MIN_FALLOCATE_BYTES;
   79     ret = stress_temp_dir_mk_args(args);
   80     if (ret < 0)
   81         return exit_status(-ret);
   82 
   83     (void)stress_temp_filename_args(args,
   84         filename, sizeof(filename), mwc32());
   85     if ((fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
   86         ret = exit_status(errno);
   87         pr_fail_err("open");
   88         (void)stress_temp_dir_rm_args(args);
   89         return ret;
   90     }
   91     (void)unlink(filename);
   92 
   93     do {
   94 #if defined(HAVE_POSIX_FALLOCATE)
   95         ret = posix_fallocate(fd, (off_t)0, fallocate_bytes);
   96 #else
   97         ret = shim_fallocate(fd, 0, (off_t)0, fallocate_bytes);
   98 #endif
   99         if (!g_keep_stressing_flag)
  100             break;
  101         (void)shim_fsync(fd);
  102         if ((ret == 0) && (g_opt_flags & OPT_FLAGS_VERIFY)) {
  103             struct stat buf;
  104 
  105             if (fstat(fd, &buf) < 0)
  106                 pr_fail("%s: fstat on file failed", args->name);
  107             else if (buf.st_size != fallocate_bytes)
  108                 pr_fail("%s: file size %jd does not "
  109                     "match size the expected file "
  110                     "size of %jd\n",
  111                     args->name, (intmax_t)buf.st_size,
  112                     (intmax_t)fallocate_bytes);
  113         }
  114 
  115         if (ftruncate(fd, 0) < 0)
  116             ftrunc_errs++;
  117         if (!g_keep_stressing_flag)
  118             break;
  119         (void)shim_fsync(fd);
  120 
  121         if (g_opt_flags & OPT_FLAGS_VERIFY) {
  122             struct stat buf;
  123 
  124             if (fstat(fd, &buf) < 0)
  125                 pr_fail("%s: fstat on file failed", args->name);
  126             else if (buf.st_size != (off_t)0)
  127                 pr_fail("%s: file size %jd does not "
  128                     "match size the expected file size "
  129                     "of 0\n",
  130                     args->name, (intmax_t)buf.st_size);
  131         }
  132 
  133         if (ftruncate(fd, fallocate_bytes) < 0)
  134             ftrunc_errs++;
  135         (void)shim_fsync(fd);
  136         if (ftruncate(fd, 0) < 0)
  137             ftrunc_errs++;
  138         (void)shim_fsync(fd);
  139 
  140         if (SIZEOF_ARRAY(modes) > 1) {
  141             /*
  142              *  non-portable Linux fallocate()
  143              */
  144             int i;
  145             (void)shim_fallocate(fd, 0, (off_t)0, fallocate_bytes);
  146             if (!g_keep_stressing_flag)
  147                 break;
  148             (void)shim_fsync(fd);
  149 
  150             for (i = 0; i < 64; i++) {
  151                 off_t offset = (mwc64() % fallocate_bytes) & ~0xfff;
  152                 int j = (mwc32() >> 8) % SIZEOF_ARRAY(modes);
  153 
  154                 (void)shim_fallocate(fd, modes[j], offset, 64 * KB);
  155                 if (!g_keep_stressing_flag)
  156                     break;
  157                 (void)shim_fsync(fd);
  158             }
  159             if (ftruncate(fd, 0) < 0)
  160                 ftrunc_errs++;
  161             (void)shim_fsync(fd);
  162         }
  163         inc_counter(args);
  164     } while (keep_stressing());
  165     if (ftrunc_errs)
  166         pr_dbg("%s: %" PRIu64
  167             " ftruncate errors occurred.\n", args->name, ftrunc_errs);
  168     (void)close(fd);
  169     (void)stress_temp_dir_rm_args(args);
  170 
  171     return EXIT_SUCCESS;
  172 }
  173 
  174 stressor_info_t stress_fallocate_info = {
  175     .stressor = stress_fallocate,
  176     .class = CLASS_FILESYSTEM | CLASS_OS
  177 };
  178 #else
  179 stressor_info_t stress_fallocate_info = {
  180     .stressor = stress_not_implemented,
  181     .class = CLASS_FILESYSTEM | CLASS_OS
  182 };
  183 #endif