"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-sync-file.c" (15 Mar 2019, 5572 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-sync-file.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 #if defined(HAVE_SYNC_FILE_RANGE)
   28 static const int sync_modes[] = {
   29     SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE,
   30     SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER,
   31     SYNC_FILE_RANGE_WRITE,
   32     SYNC_FILE_RANGE_WAIT_BEFORE,
   33     SYNC_FILE_RANGE_WAIT_AFTER,
   34     0   /* No-op */
   35 };
   36 #endif
   37 
   38 int stress_set_sync_file_bytes(const char *opt)
   39 {
   40     off_t sync_file_bytes;
   41 
   42     sync_file_bytes = (off_t)get_uint64_byte_filesystem(opt, 1);
   43     check_range_bytes("sync_file-bytes", sync_file_bytes,
   44         MIN_SYNC_FILE_BYTES, MAX_SYNC_FILE_BYTES);
   45     return set_setting("sync_file-bytes", TYPE_ID_OFF_T, &sync_file_bytes);
   46 }
   47 
   48 #if defined(HAVE_SYNC_FILE_RANGE)
   49 
   50 /*
   51  *  shrink and re-allocate the file to be sync'd
   52  *
   53  */
   54 static int stress_sync_allocate(
   55     const args_t *args,
   56     const int fd,
   57     const off_t sync_file_bytes)
   58 {
   59     int ret;
   60 
   61     ret = ftruncate(fd, 0);
   62     if (ret < 0) {
   63         pr_err("%s: ftruncate failed: errno=%d (%s)\n",
   64             args->name, errno, strerror(errno));
   65         return -errno;
   66     }
   67 
   68 #if defined(HAVE_FDATASYNC)
   69     ret = shim_fdatasync(fd);
   70     if (ret < 0) {
   71         pr_err("%s: fdatasync failed: errno=%d (%s)\n",
   72             args->name, errno, strerror(errno));
   73         return -errno;
   74     }
   75 #endif
   76 
   77     ret = shim_fallocate(fd, 0, (off_t)0, sync_file_bytes);
   78     if (ret < 0) {
   79         pr_err("%s: fallocate failed: errno=%d (%s)\n",
   80             args->name, errno, strerror(errno));
   81         return -errno;
   82     }
   83     return 0;
   84 }
   85 
   86 /*
   87  *  stress_sync_file
   88  *  stress the sync_file_range system call
   89  */
   90 static int stress_sync_file(const args_t *args)
   91 {
   92     int fd, ret;
   93     off_t sync_file_bytes = DEFAULT_SYNC_FILE_BYTES;
   94     char filename[PATH_MAX];
   95 
   96     if (!get_setting("sync_file-bytes", &sync_file_bytes)) {
   97         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
   98             sync_file_bytes = MAX_SYNC_FILE_BYTES;
   99         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  100             sync_file_bytes = MIN_SYNC_FILE_BYTES;
  101     }
  102     sync_file_bytes /= args->num_instances;
  103     if (sync_file_bytes < (off_t)MIN_SYNC_FILE_BYTES)
  104         sync_file_bytes = (off_t)MIN_SYNC_FILE_BYTES;
  105 
  106     ret = stress_temp_dir_mk_args(args);
  107     if (ret < 0)
  108         return exit_status(-ret);
  109 
  110     (void)stress_temp_filename_args(args,
  111         filename, sizeof(filename), mwc32());
  112     if ((fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
  113         ret = exit_status(errno);
  114         pr_fail_err("open");
  115         (void)stress_temp_dir_rm_args(args);
  116         return ret;
  117     }
  118     (void)unlink(filename);
  119 
  120     do {
  121         shim_off64_t i, offset;
  122         const size_t mode_index = mwc32() % SIZEOF_ARRAY(sync_modes);
  123         const int mode = sync_modes[mode_index];
  124 
  125         if (stress_sync_allocate(args, fd, sync_file_bytes) < 0)
  126             break;
  127         for (offset = 0; g_keep_stressing_flag &&
  128              (offset < (shim_off64_t)sync_file_bytes); ) {
  129             shim_off64_t sz = (mwc32() & 0x1fc00) + KB;
  130 
  131             ret = shim_sync_file_range(fd, offset, sz, mode);
  132             if (ret < 0) {
  133                 if (errno == ENOSYS) {
  134                     pr_inf("%s: skipping stressor, sync_file_range is not implemented\n",
  135                         args->name);
  136                     goto err;
  137                 }
  138                 pr_fail_err("sync_file_range (forward)");
  139                 break;
  140             }
  141             offset += sz;
  142         }
  143         if (!g_keep_stressing_flag)
  144             break;
  145 
  146         if (stress_sync_allocate(args, fd, sync_file_bytes) < 0)
  147             break;
  148         for (offset = 0; g_keep_stressing_flag &&
  149              (offset < (shim_off64_t)sync_file_bytes); ) {
  150             shim_off64_t sz = (mwc32() & 0x1fc00) + KB;
  151 
  152             ret = shim_sync_file_range(fd, sync_file_bytes - offset, sz, mode);
  153             if (ret < 0) {
  154                 if (errno == ENOSYS) {
  155                     pr_inf("%s: skipping stressor, sync_file_range is not implemented\n",
  156                         args->name);
  157                     goto err;
  158                 }
  159                 pr_fail_err("sync_file_range (reverse)");
  160                 break;
  161             }
  162             offset += sz;
  163         }
  164         if (!g_keep_stressing_flag)
  165             break;
  166 
  167         if (stress_sync_allocate(args, fd, sync_file_bytes) < 0)
  168             break;
  169         for (i = 0; i < g_keep_stressing_flag &&
  170              ((shim_off64_t)(sync_file_bytes / (128 * KB))); i++) {
  171             offset = (mwc64() % sync_file_bytes) & ~((128 * KB) - 1);
  172             ret = shim_sync_file_range(fd, offset, 128 * KB, mode);
  173             if (ret < 0) {
  174                 if (errno == ENOSYS) {
  175                     pr_inf("%s: skipping stressor, sync_file_range is not implemented\n",
  176                         args->name);
  177                     goto err;
  178                 }
  179                 pr_fail_err("sync_file_range (random)");
  180                 break;
  181             }
  182         }
  183         inc_counter(args);
  184     } while (keep_stressing());
  185 
  186 err:
  187     (void)close(fd);
  188     (void)stress_temp_dir_rm_args(args);
  189 
  190     return EXIT_SUCCESS;
  191 }
  192 
  193 stressor_info_t stress_sync_file_info = {
  194     .stressor = stress_sync_file,
  195     .class = CLASS_IO | CLASS_FILESYSTEM | CLASS_OS
  196 };
  197 #else
  198 stressor_info_t stress_sync_file_info = {
  199     .stressor = stress_not_implemented,
  200     .class = CLASS_IO | CLASS_FILESYSTEM | CLASS_OS
  201 };
  202 #endif