"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-dir.c" (15 Mar 2019, 3913 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-dir.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.52_vs_0.09.54.

    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 /*
   28  *  stress_set_dir_dirs()
   29  *      set number of dir directories from given option string
   30  */
   31 int stress_set_dir_dirs(const char *opt)
   32 {
   33     uint64_t dir_dirs;
   34 
   35     dir_dirs = get_uint64(opt);
   36     check_range("dir-dirs", dir_dirs,
   37         MIN_DIR_DIRS, MAX_DIR_DIRS);
   38     return set_setting("dir-dirs", TYPE_ID_UINT64, &dir_dirs);
   39 }
   40 
   41 #if defined(__DragonFly__)
   42 #define d_reclen d_namlen
   43 #endif
   44 
   45 /*
   46  *  stress_dir_sync()
   47  *  attempt to sync a directory
   48  */
   49 static void stress_dir_sync(const char *path)
   50 {
   51 #if defined(O_DIRECTORY)
   52     int fd;
   53 
   54     fd = open(path, O_RDONLY | O_DIRECTORY);
   55     if (fd < 0)
   56         return;
   57 
   58     /*
   59      *  The interesting part of fsync is that in
   60      *  theory we can fsync a read only file and
   61      *  this could be a directory too. So try and
   62      *  sync.
   63      */
   64     (void)shim_fsync(fd);
   65     (void)close(fd);
   66 #else
   67     (void)path;
   68 #endif
   69 }
   70 
   71 /*
   72  *  stress_dir_read()
   73  *  read all dentries
   74  */
   75 static void stress_dir_read(
   76     const args_t *args,
   77     const char *path)
   78 {
   79     DIR *dp;
   80     struct dirent *de;
   81 
   82     dp = opendir(path);
   83     if (!dp)
   84         return;
   85 
   86     while ((de = readdir(dp)) != NULL) {
   87         if (de->d_reclen == 0) {
   88             pr_fail("%s: read a zero sized directory entry\n", args->name);
   89             break;
   90         }
   91     }
   92 
   93     (void)closedir(dp);
   94 }
   95 
   96 /*
   97  *  stress_dir_tidy()
   98  *  remove all dentries
   99  */
  100 static void stress_dir_tidy(
  101     const args_t *args,
  102     const uint64_t n)
  103 {
  104     uint64_t i;
  105 
  106     for (i = 0; i < n; i++) {
  107         char path[PATH_MAX];
  108         uint64_t gray_code = (i >> 1) ^ i;
  109 
  110         (void)stress_temp_filename_args(args,
  111             path, sizeof(path), gray_code);
  112         (void)rmdir(path);
  113     }
  114 }
  115 
  116 /*
  117  *  stress_dir
  118  *  stress directory mkdir and rmdir
  119  */
  120 static int stress_dir(const args_t *args)
  121 {
  122     int ret;
  123     uint64_t dir_dirs = DEFAULT_DIR_DIRS;
  124     char dirname[PATH_MAX];
  125 
  126     stress_temp_dir(dirname, sizeof(dirname), args->name, args->pid, args->instance);
  127 
  128     (void)get_setting("dir-dirs", &dir_dirs);
  129 
  130     ret = stress_temp_dir_mk_args(args);
  131     if (ret < 0)
  132         return exit_status(-ret);
  133 
  134     do {
  135         uint64_t i, n = dir_dirs;
  136 
  137         for (i = 0; i < n; i++) {
  138             char path[PATH_MAX];
  139             uint64_t gray_code = (i >> 1) ^ i;
  140 
  141             (void)stress_temp_filename_args(args,
  142                 path, sizeof(path), gray_code);
  143             if (mkdir(path, S_IRUSR | S_IWUSR) < 0) {
  144                 if ((errno != ENOSPC) && (errno != ENOMEM)) {
  145                     pr_fail_err("mkdir");
  146                     n = i;
  147                     break;
  148                 }
  149             }
  150 
  151             if (!keep_stressing())
  152                 goto abort;
  153 
  154             inc_counter(args);
  155         }
  156         stress_dir_sync(dirname);
  157         stress_dir_read(args, dirname);
  158         stress_dir_tidy(args, n);
  159         stress_dir_sync(dirname);
  160         if (!g_keep_stressing_flag)
  161             break;
  162         (void)sync();
  163     } while (keep_stressing());
  164 
  165 abort:
  166     /* force unlink of all files */
  167     pr_tidy("%s: removing %" PRIu64 " directories\n",
  168         args->name, dir_dirs);
  169     stress_dir_tidy(args, dir_dirs);
  170     (void)stress_temp_dir_rm_args(args);
  171 
  172     return ret;
  173 }
  174 
  175 stressor_info_t stress_dir_info = {
  176     .stressor = stress_dir,
  177     .class = CLASS_FILESYSTEM | CLASS_OS
  178 };