The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/tests/zfs-tests/cmd/file/file_append.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or https://opensource.org/licenses/CDDL-1.0.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 
   22 /*
   23  * Copyright (c) 2022 by Triad National Security, LLC
   24  */
   25 
   26 #include "file_common.h"
   27 #include <unistd.h>
   28 #include <sys/sysmacros.h>
   29 
   30 static char *filename = NULL;
   31 static int expected_offset = -1;
   32 static int blocksize = 131072; /* 128KiB */
   33 static int numblocks = 8;
   34 static const char *execname = "file_append";
   35 static int use_odirect = 0;
   36 
   37 static void
   38 usage(void)
   39 {
   40         (void) fprintf(stderr,
   41             "usage %s -f filename -e expected_offset [-b blocksize] \n"
   42             "         [-n numblocks] [-d use_odirect] [-h help]\n"
   43             "\n"
   44             "Opens a file using O_APPEND and writes numblocks blocksize\n"
   45             "blocks to filename.\n"
   46             "Checks if expected_offst == lseek(fd, 0, SEEK_CUR)).\n"
   47             "\n"
   48             "    filename:         File to open with O_APPEND and write to.\n"
   49             "    expected_offset:  Expected file offset after writing\n"
   50             "                      blocksize numblocks to filename\n"
   51             "    blocksize:        Size of each block to writei (must be at\n"
   52             "                      least >= 512). If using use_odirect (-d)\n"
   53             "                      must be a mutltiple of _SC_PAGE_SIZE\n"
   54             "    numblocks:        Total number of blocksized blocks to\n"
   55             "                      write.\n"
   56             "    use_odirect:      Open file using O_DIRECT.\n"
   57             "    help:             Print usage information and exit.\n"
   58             "\n"
   59             "    Required parameters:\n"
   60             "    filename\n"
   61             "    expected_offset\n"
   62             "\n"
   63             "    Default values:\n"
   64             "    blocksize   -> 131072 (128 KiB)\n"
   65             "    numblocks   -> 8\n"
   66             "    use_odirect -> False\n",
   67             execname);
   68         (void) exit(1);
   69 }
   70 
   71 static void
   72 parse_options(int argc, char *argv[])
   73 {
   74         int c;
   75         int errflag = 0;
   76         extern char *optarg;
   77         extern int optind, optopt;
   78 
   79         while ((c = getopt(argc, argv, "b:de:f:hn:")) != -1) {
   80                 switch (c) {
   81                         case 'b':
   82                                 blocksize = atoi(optarg);
   83                                 break;
   84                         case 'd':
   85                                 use_odirect = 1;
   86                                 break;
   87                         case 'e':
   88                                 expected_offset = atoi(optarg);
   89                                 break;
   90                         case 'f':
   91                                 filename = optarg;
   92                                 break;
   93                         case 'h':
   94                                 (void) usage();
   95                                 break;
   96                         case 'n':
   97                                 numblocks = atoi(optarg);
   98                                 break;
   99                         case ':':
  100                                 (void) fprintf(stderr,
  101                                     "Option -%c requires an operand\n",
  102                                     optopt);
  103                                 errflag++;
  104                                 break;
  105                         case '?':
  106                         default:
  107                                 (void) fprintf(stderr,
  108                                     "Unrecognized option: -%c\n", optopt);
  109                                 errflag++;
  110                                 break;
  111                 }
  112         }
  113 
  114         if (errflag)
  115                 (void) usage();
  116 
  117         if (use_odirect && ((blocksize % sysconf(_SC_PAGE_SIZE)) != 0)) {
  118                 (void) fprintf(stderr,
  119                     "blocksize parameter invalid when using O_DIRECT.\n");
  120                 (void) usage();
  121         }
  122 
  123         if (blocksize < 512 || expected_offset < 0 || filename == NULL ||
  124             numblocks <= 0) {
  125                 (void) fprintf(stderr,
  126                     "Required parameters(s) missing or invalid value for "
  127                     "parameter.\n");
  128                 (void) usage();
  129         }
  130 }
  131 
  132 int
  133 main(int argc, char *argv[])
  134 {
  135         int             err;
  136         const char      *datapattern = "0xf00ba3";
  137         int             fd = -1;
  138         int             fd_flags = O_WRONLY | O_CREAT | O_APPEND;
  139         int             buf_offset = 0;
  140         char            *buf;
  141 
  142         parse_options(argc, argv);
  143 
  144         if (use_odirect)
  145                 fd_flags |= O_DIRECT;
  146 
  147         fd = open(filename, fd_flags, 0666);
  148         if (fd == -1) {
  149                 (void) fprintf(stderr, "%s: %s: ", execname, filename);
  150                 perror("open");
  151                 (void) exit(2);
  152         }
  153 
  154         err = posix_memalign((void **)&buf, sysconf(_SC_PAGE_SIZE),
  155             blocksize);
  156 
  157         if (err != 0) {
  158                 (void) fprintf(stderr,
  159                     "%s: %s\n", execname, strerror(err));
  160                 (void) exit(2);
  161         }
  162 
  163         /* Putting known data pattern in buffer */
  164         int left = blocksize;
  165         while (left) {
  166                 size_t amt = MIN(strlen(datapattern), left);
  167                 memcpy(&buf[buf_offset], datapattern, amt);
  168                 buf_offset += amt;
  169                 left -= amt;
  170         }
  171 
  172         for (int i = 0; i < numblocks; i++) {
  173                 int wrote = write(fd, buf, blocksize);
  174 
  175                 if (wrote != blocksize) {
  176                         if (wrote < 0) {
  177                                 perror("write");
  178                         } else {
  179                                 (void) fprintf(stderr,
  180                                     "%s: unexpected short write, wrote %d "
  181                                     "byte, expected %d\n", execname, wrote,
  182                                     blocksize);
  183                         }
  184                         (void) exit(2);
  185                 }
  186         }
  187 
  188         /* Getting current file offset */
  189         off_t off = lseek(fd, 0, SEEK_CUR);
  190 
  191         if (off == -1) {
  192                 perror("output seek");
  193                 (void) exit(2);
  194         } else if (off != expected_offset) {
  195                 (void) fprintf(stderr,
  196                     "%s: expected offset %d but current offset in %s is set "
  197                     "to %ld\n", execname, expected_offset, filename,
  198                     (long int)off);
  199                 (void) exit(2);
  200         }
  201 
  202         (void) close(fd);
  203         free(buf);
  204 
  205         return (0);
  206 }

Cache object: 6761456d35b1f9783b0fed849510a711


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.