"Fossies" - the Fresh Open Source Software Archive

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

    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_LIB_PTHREAD) && \
   28     defined(HAVE_LIBGEN_H) && \
   29     defined(FS_IOC_GETFLAGS) && \
   30     defined(FS_IOC_SETFLAGS) && \
   31     defined(FS_IOC_SETFLAGS) && \
   32     defined(O_DIRECTORY)
   33 
   34 #define MAX_INODE_FLAG_THREADS      (4)
   35 
   36 static volatile bool keep_running;
   37 static sigset_t set;
   38 static shim_pthread_spinlock_t spinlock;
   39 
   40 /*
   41  *  stress_inode_flags_ioctl()
   42  *  try and toggle an inode flag on/off
   43  */
   44 static void stress_inode_flags_ioctl(
   45     const args_t *args,
   46     const int fd,
   47     const int flag)
   48 {
   49     int ret, attr;
   50 
   51     if (!keep_stressing())
   52         return;
   53 
   54     ret = ioctl(fd, FS_IOC_GETFLAGS, &attr);
   55     if (ret != 0)
   56         return;
   57 
   58     attr |= flag;
   59     ret = ioctl(fd, FS_IOC_SETFLAGS, &attr);
   60     (void)ret;
   61 
   62     attr &= ~flag;
   63     ret = ioctl(fd, FS_IOC_SETFLAGS, &attr);
   64     (void)ret;
   65 }
   66 
   67 /*
   68  *  stress_inode_flags_ioctl_sane()
   69  *  set flags to a sane state so that file can be removed
   70  */
   71 static inline void stress_inode_flags_ioctl_sane(const int fd)
   72 {
   73     int ret;
   74     const int flag = 0;
   75 
   76     ret = ioctl(fd, FS_IOC_SETFLAGS, &flag);
   77     (void)ret;
   78 }
   79 
   80 /*
   81  *  stress_inode_flags_stressor()
   82  *  exercise inode flags, see man ioctl_flags for
   83  *  more details of these flags. Some are never going
   84  *  to be implemented and some are just relevant to
   85  *  specific file systems. We just want to try and
   86  *  toggle these on and off to see if they break rather
   87  *  than fail.
   88  */
   89 static void stress_inode_flags_stressor(
   90     const args_t *args,
   91     char *filename)
   92 {
   93     char pathname[PATH_MAX];
   94     char *path;
   95     int fdfile, fddir;
   96 
   97     (void)shim_strlcpy(pathname, filename, PATH_MAX);
   98     path = dirname(pathname);
   99 
  100     fddir = open(path, O_RDONLY | O_DIRECTORY);
  101     if (fddir < 0) {
  102         pr_err("%s: cannot open %s: errno=%d (%s)\n",
  103             args->name, path, errno, strerror(errno));
  104         return;
  105     }
  106     fdfile = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  107     if (fdfile < 0) {
  108         pr_err("%s: cannot open %s: errno=%d (%s)\n",
  109             args->name, filename, errno, strerror(errno));
  110         (void)close(fddir);
  111         return;
  112     }
  113 
  114     while (keep_running && keep_stressing()) {
  115         int ret;
  116 
  117         stress_inode_flags_ioctl(args, fddir, 0);
  118 #if defined(FS_DIRSYNC_FL)
  119         stress_inode_flags_ioctl(args, fddir, FS_DIRSYNC_FL);
  120 #endif
  121 #if defined(FS_PROJINHERIT_FL)
  122         stress_inode_flags_ioctl(args, fddir, FS_PROJINHERIT_FL);
  123 #endif
  124 #if defined(FS_SYNC_FL)
  125         stress_inode_flags_ioctl(args, fddir, FS_SYNC_FL);
  126 #endif
  127 #if defined(FS_TOPDIR_FL)
  128         stress_inode_flags_ioctl(args, fddir, FS_TOPDIR_FL);
  129 #endif
  130 #if defined(FS_APPEND_LF)
  131         stress_inode_flags_ioctl(args, fdfile, FS_APPEND_FL);
  132 #endif
  133 #if defined(FS_COMPR_FL)
  134         stress_inode_flags_ioctl(args, fdfile, FS_COMPR_FL);
  135 #endif
  136 #if defined(FS_IMMUTABLE_FL)
  137         stress_inode_flags_ioctl(args, fdfile, FS_IMMUTABLE_FL);
  138 #endif
  139 #if defined(FS_JOURNAL_DATA_FL)
  140         stress_inode_flags_ioctl(args, fdfile, FS_JOURNAL_DATA_FL);
  141 #endif
  142 #if defined(FS_NOCOW_FL)
  143         stress_inode_flags_ioctl(args, fdfile, FS_NOCOW_FL);
  144 #endif
  145 #if defined(FS_NODUMP_FL)
  146         stress_inode_flags_ioctl(args, fdfile, FS_NODUMP_FL);
  147 #endif
  148 #if defined(FS_NOTAIL_FL)
  149         stress_inode_flags_ioctl(args, fdfile, FS_NOTAIL_FL);
  150 #endif
  151 #if defined(FS_PROJINHERIT_FL)
  152         stress_inode_flags_ioctl(args, fdfile, FS_PROJINHERIT_FL);
  153 #endif
  154 #if defined(FS_SECRM_FL)
  155         stress_inode_flags_ioctl(args, fdfile, FS_SECRM_FL);
  156 #endif
  157 #if defined(FS_SYNC_FL)
  158         stress_inode_flags_ioctl(args, fdfile, FS_SYNC_FL);
  159 #endif
  160 #if defined(FS_UNRM_FL)
  161         stress_inode_flags_ioctl(args, fdfile, FS_UNRM_FL);
  162 #endif
  163         ret = shim_pthread_spin_lock(&spinlock);
  164         if (!ret) {
  165             inc_counter(args);
  166             ret = shim_pthread_spin_unlock(&spinlock);
  167             (void)ret;
  168         }
  169         stress_inode_flags_ioctl_sane(fdfile);
  170     }
  171     stress_inode_flags_ioctl_sane(fdfile);
  172     (void)close(fdfile);
  173     (void)close(fddir);
  174 }
  175 
  176 /*
  177  *  stress_inode_flags()
  178  *  exercise inode flags on a file
  179  */
  180 static void *stress_inode_flags_thread(void *arg)
  181 {
  182     static void *nowt = NULL;
  183     uint8_t stack[SIGSTKSZ + STACK_ALIGNMENT];
  184     pthread_args_t *pa = (pthread_args_t *)arg;
  185 
  186     /*
  187      *  Block all signals, let controlling thread
  188      *  handle these
  189      */
  190     (void)sigprocmask(SIG_BLOCK, &set, NULL);
  191 
  192     /*
  193      *  According to POSIX.1 a thread should have
  194      *  a distinct alternative signal stack.
  195      *  However, we block signals in this thread
  196      *  so this is probably just totally unncessary.
  197      */
  198     (void)memset(stack, 0, sizeof(stack));
  199     if (stress_sigaltstack(stack, SIGSTKSZ) < 0)
  200         return &nowt;
  201 
  202     stress_inode_flags_stressor(pa->args, (char *)pa->data);
  203 
  204     return &nowt;
  205 }
  206 
  207 
  208 /*
  209  *  stress_inode_flags
  210  *  stress reading all of /dev
  211  */
  212 static int stress_inode_flags(const args_t *args)
  213 {
  214     char filename[PATH_MAX];
  215     size_t i;
  216     pthread_t pthreads[MAX_INODE_FLAG_THREADS];
  217     int rc, ret[MAX_INODE_FLAG_THREADS];
  218     pthread_args_t pa;
  219 
  220     rc = shim_pthread_spin_init(&spinlock, SHIM_PTHREAD_PROCESS_SHARED);
  221         if (rc) {
  222                 pr_fail_errno("pthread_spin_init", rc);
  223                 return EXIT_FAILURE;
  224         }
  225 
  226     rc = stress_temp_dir_mk_args(args);
  227     if (rc < 0)
  228         return exit_status(-rc);
  229     (void)stress_temp_filename_args(args,
  230         filename, sizeof(filename), mwc32());
  231 
  232     pa.args = args;
  233     pa.data = (void *)filename;
  234 
  235     (void)memset(ret, 0, sizeof(ret));
  236     keep_running = true;
  237 
  238     for (i = 0; i < MAX_INODE_FLAG_THREADS; i++) {
  239         ret[i] = pthread_create(&pthreads[i], NULL,
  240                 stress_inode_flags_thread, &pa);
  241     }
  242 
  243     do {
  244         stress_inode_flags_stressor(args, filename);
  245     } while (keep_stressing());
  246 
  247     keep_running = false;
  248 
  249     for (i = 0; i < MAX_INODE_FLAG_THREADS; i++) {
  250         if (ret[i] == 0)
  251             pthread_join(pthreads[i], NULL);
  252     }
  253 
  254     (void)shim_pthread_spin_destroy(&spinlock);
  255     (void)unlink(filename);
  256     stress_temp_dir_rm_args(args);
  257 
  258     return EXIT_SUCCESS;
  259 }
  260 
  261 stressor_info_t stress_inode_flags_info = {
  262     .stressor = stress_inode_flags,
  263     .class = CLASS_OS | CLASS_FILESYSTEM
  264 };
  265 #else
  266 stressor_info_t stress_inode_flags_info = {
  267     .stressor = stress_not_implemented ,
  268     .class = CLASS_OS | CLASS_FILESYSTEM
  269 };
  270 #endif