"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-file-ioctl.c" (15 Mar 2019, 6846 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-file-ioctl.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(FIONBIO) && defined(O_NONBLOCK)) || \
   28     (defined(FIOASYNC) && defined(O_ASYNC))
   29 static void check_flag(
   30     const args_t *args,
   31     const char *ioctl_name,
   32     const int fd,
   33     const int flag,
   34     const int ret,
   35     const bool set)
   36 {
   37 #if defined(F_GETFL)
   38     if (ret == 0) {
   39         int flags;
   40 
   41         flags = fcntl(fd, F_GETFL, 0);
   42         /*
   43          *  The fcntl failed, so checking is not a valid
   44          *  thing to sanity check with.
   45          */
   46         if (errno != 0)
   47             return;
   48         if ((set && !(flags & flag)) ||
   49             (!set && (flags & flag)))
   50             pr_fail("%s: ioctl %s failed, unexpected flags when checked with F_GETFL\n",
   51                 args->name, ioctl_name);
   52     }
   53 #else
   54     (void)args;
   55     (void)ioctl_name;
   56     (void)fd;
   57     (void)flag;
   58     (void)ret;
   59 #endif
   60 }
   61 #endif
   62 
   63 /*
   64  *  stress_file_ioctl
   65  *  stress file ioctls
   66  */
   67 static int stress_file_ioctl(const args_t *args)
   68 {
   69     char filename[PATH_MAX];
   70     int ret, fd;
   71 #if defined(FICLONE) || defined(FICLONERANGE)
   72     int dfd;
   73 #endif
   74     const off_t file_sz = 8192;
   75     uint32_t rnd = mwc32();
   76 
   77     ret = stress_temp_dir_mk_args(args);
   78     if (ret < 0)
   79         return exit_status(-ret);
   80 
   81     (void)stress_temp_filename_args(args, filename, sizeof(filename), rnd);
   82     fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
   83     if (fd < 0) {
   84         pr_err("%s: cannot create %s\n", args->name, filename);
   85         return exit_status(errno);
   86     }
   87     (void)unlink(filename);
   88 
   89 #if defined(FICLONE) || defined(FICLONERANGE)
   90     (void)stress_temp_filename_args(args, filename, sizeof(filename), rnd + 1);
   91     dfd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
   92     if (dfd < 0) {
   93         (void)close(fd);
   94         pr_err("%s: cannot create %s\n", args->name, filename);
   95         return exit_status(errno);
   96     }
   97     (void)unlink(filename);
   98 #endif
   99 
  100     (void)shim_fallocate(fd, 0, 0, file_sz);
  101 #if defined(FICLONE) || defined(FICLONERANGE)
  102     (void)shim_fallocate(dfd, 0, 0, file_sz);
  103 #endif
  104     (void)shim_fsync(fd);
  105 
  106     do {
  107         int exercised = 0;
  108 
  109 #if defined(FIOCLEX)
  110         {
  111             ret = ioctl(fd, FIOCLEX);
  112             (void)ret;
  113 
  114             exercised++;
  115         }
  116 #endif
  117 #if defined(FIONCLEX)
  118         {
  119             ret = ioctl(fd, FIONCLEX);
  120             (void)ret;
  121 
  122             exercised++;
  123         }
  124 #endif
  125 #if defined(FIONBIO)
  126         {
  127             int opt;
  128 
  129             opt = 1;
  130             ret = ioctl(fd, FIONBIO, &opt);
  131 #if defined(O_NONBLOCK)
  132             check_flag(args, "FIONBIO", fd, O_NONBLOCK, ret, true);
  133 #else
  134             (void)ret;
  135 #endif
  136 
  137             opt = 0;
  138             ret = ioctl(fd, FIONBIO, &opt);
  139 #if defined(O_NONBLOCK)
  140             check_flag(args, "FIONBIO", fd, O_NONBLOCK, ret, false);
  141 #else
  142             (void)ret;
  143 #endif
  144             exercised++;
  145         }
  146 #endif
  147 
  148 #if defined(FIOASYNC)
  149         {
  150             int opt;
  151 
  152             opt = 1;
  153             ret = ioctl(fd, FIOASYNC, &opt);
  154 #if defined(O_ASYNC)
  155             check_flag(args, "FIONASYNC", fd, O_ASYNC, ret, true);
  156 #else
  157             (void)ret;
  158 #endif
  159 
  160             opt = 0;
  161             ret = ioctl(fd, FIOASYNC, &opt);
  162 #if defined(O_ASYNC)
  163             check_flag(args, "FIONASYNC", fd, O_ASYNC, ret, false);
  164 #else
  165             (void)ret;
  166 #endif
  167             exercised++;
  168         }
  169 #endif
  170 
  171 #if defined(FIOQSIZE)
  172         {
  173             shim_loff_t sz;
  174             struct stat buf;
  175 
  176             ret = fstat(fd, &buf);
  177             if (ret == 0) {
  178                 ret = ioctl(fd, FIOQSIZE, &sz);
  179                 if ((ret == 0) && (file_sz != buf.st_size))
  180                     pr_fail("%s: ioctl FIOQSIZE failed, size "
  181                         "%jd (filesize) vs %jd (reported)\n",
  182                         args->name,
  183                         (intmax_t)file_sz, (intmax_t)sz);
  184             }
  185             exercised++;
  186         }
  187 #endif
  188 
  189 /* Disable this at the moment, it is fragile */
  190 #if 0
  191 #if defined(FIFREEZE) && defined(FITHAW)
  192         {
  193             ret = ioctl(fd, FIFREEZE);
  194             (void)ret;
  195             ret = ioctl(fd, FITHAW);
  196             (void)ret;
  197 
  198             exercised++;
  199         }
  200 #endif
  201 #endif
  202 
  203 #if defined(FIGETBSZ)
  204         {
  205             int isz;
  206 
  207             ret = ioctl(fd, FIGETBSZ, &isz);
  208             if ((ret == 0) && (isz < 1))
  209                 pr_fail("%s: ioctl FIGETBSZ returned unusual "
  210                     "block size %d\n", args->name, isz);
  211 
  212             exercised++;
  213         }
  214 #endif
  215 
  216 #if defined(FICLONE)
  217         {
  218             ret = ioctl(dfd, FICLONE, fd);
  219             (void)ret;
  220 
  221             exercised++;
  222         }
  223 #endif
  224 
  225 #if defined(FICLONERANGE)
  226         {
  227             struct file_clone_range fcr;
  228 
  229             (void)memset(&fcr, 0, sizeof(fcr));
  230             fcr.src_fd = fd;
  231             fcr.src_offset = 0;
  232             fcr.src_length = file_sz;
  233             fcr.dest_offset = 0;
  234 
  235             ret = ioctl(dfd, FICLONERANGE, &fcr);
  236             (void)ret;
  237 
  238             exercised++;
  239         }
  240 #endif
  241 
  242 #if defined(FIDEDUPERANGE)
  243         {
  244             const size_t sz = sizeof(struct file_dedupe_range) +
  245                       sizeof(struct file_dedupe_range_info);
  246             char buf[sz] ALIGNED(64);
  247 
  248             struct file_dedupe_range *d = (struct file_dedupe_range *)buf;
  249 
  250             d->src_offset = 0;
  251             d->src_length = file_sz;
  252             d->dest_count = 1;
  253             d->reserved1 = 0;
  254             d->reserved2 = 0;
  255             d->info[0].dest_fd = dfd;
  256             d->info[0].dest_offset = 0;
  257             /* Zero the return values */
  258             d->info[0].bytes_deduped = 0;
  259             d->info[0].status = 0;
  260             d->info[0].reserved = 0;
  261             ret = ioctl(fd, FIDEDUPERANGE, d);
  262             (void)ret;
  263 
  264             exercised++;
  265         }
  266 #endif
  267 
  268 #if defined(FIONREAD)
  269         {
  270             int isz = 0;
  271 
  272             ret = ioctl(fd, FIONREAD, &isz);
  273             (void)ret;
  274 
  275             exercised++;
  276         }
  277 #endif
  278 
  279 #if defined(FIONWRITE)
  280         {
  281             int isz = 0;
  282 
  283             ret = ioctl(fd, FIONWRITE, &isz);
  284             (void)ret;
  285 
  286             exercised++;
  287         }
  288 #endif
  289 
  290 #if defined(FS_IOC_RESVSP)
  291         {
  292             unsigned long isz = file_sz * 2;
  293 
  294             ret = ioctl(fd, FS_IOC_RESVP, &isz);
  295             (void)ret;
  296 
  297             exercised++;
  298         }
  299 #endif
  300 
  301 #if defined(FS_IOC_RESVSP64)
  302         {
  303             unsigned long isz = file_sz * 2;
  304 
  305             ret = ioctl(fd, FS_IOC_RESVP64, &isz);
  306             (void)ret;
  307 
  308             exercised++;
  309         }
  310 #endif
  311 
  312 #if defined(FIBMAP)
  313         {
  314             int block = 0;
  315 
  316             ret = ioctl(fd, FIBMAP, &block);
  317             (void)ret;
  318 
  319             exercised++;
  320         }
  321 #endif
  322         if (!exercised) {
  323             pr_inf("%s: no available file ioctls to exercise\n",
  324                 args->name);
  325             ret = EXIT_NOT_IMPLEMENTED;
  326             goto tidy;
  327         }
  328 
  329         inc_counter(args);
  330     } while (keep_stressing());
  331 
  332     ret = EXIT_SUCCESS;
  333 
  334 tidy:
  335 #if defined(FICLONE) || defined(FICLONERANGE)
  336     (void)close(dfd);
  337 #endif
  338     (void)close(fd);
  339     (void)stress_temp_dir_rm_args(args);
  340 
  341     return ret;
  342 }
  343 
  344 stressor_info_t stress_file_ioctl_info = {
  345     .stressor = stress_file_ioctl,
  346     .class = CLASS_FILESYSTEM | CLASS_OS
  347 };