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/mmapwrite.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 2007 Sun Microsystems, Inc.  All rights reserved.
   24  * Use is subject to license terms.
   25  */
   26 
   27 #include <unistd.h>
   28 #include <fcntl.h>
   29 #include <stdio.h>
   30 #include <stdlib.h>
   31 #include <string.h>
   32 #include <sys/mman.h>
   33 #include <pthread.h>
   34 #include <errno.h>
   35 #include <err.h>
   36 
   37 /*
   38  * --------------------------------------------------------------------
   39  * Bug Issue Id: #7512
   40  * The bug time sequence:
   41  * 1. context #1, zfs_write assign a txg "n".
   42  * 2. In the same process, context #2, mmap page fault (which means the mm_sem
   43  *    is hold) occurred, zfs_dirty_inode open a txg failed, and wait previous
   44  *    txg "n" completed.
   45  * 3. context #1 call zfs_uiomove to write, however page fault is occurred in
   46  *    zfs_uiomove, which means it needs mm_sem, but mm_sem is hold by
   47  *    context #2, so it stuck and can't complete, then txg "n" will not
   48  *    complete.
   49  *
   50  * So context #1 and context #2 trap into the "dead lock".
   51  * --------------------------------------------------------------------
   52  */
   53 
   54 #define NORMAL_WRITE_TH_NUM     2
   55 #define MAX_WRITE_BYTES 262144000
   56 
   57 static void *
   58 normal_writer(void *filename)
   59 {
   60         char *file_path = filename;
   61         int fd = -1;
   62         ssize_t write_num = 0;
   63         int page_size = getpagesize();
   64 
   65         fd = open(file_path, O_RDWR | O_CREAT, 0777);
   66         if (fd == -1) {
   67                 err(1, "failed to open %s", file_path);
   68         }
   69 
   70         char buf = 'z';
   71         off_t bytes_written = 0;
   72 
   73         while (bytes_written < MAX_WRITE_BYTES) {
   74                 write_num = write(fd, &buf, 1);
   75                 if (write_num == 0) {
   76                         err(1, "write failed!");
   77                         break;
   78                 }
   79                 if ((bytes_written = lseek(fd, page_size, SEEK_CUR)) == -1) {
   80                         err(1, "lseek failed on %s: %s", file_path,
   81                             strerror(errno));
   82                         break;
   83                 }
   84         }
   85 
   86         if (close(fd) != 0)
   87                 err(1, "failed to close file");
   88 
   89         return (NULL);
   90 }
   91 
   92 static void *
   93 map_writer(void *filename)
   94 {
   95         int fd = -1;
   96         int ret = 0;
   97         char *buf = NULL;
   98         int page_size = getpagesize();
   99         char *file_path = filename;
  100 
  101         while (1) {
  102                 fd = open(file_path, O_RDWR);
  103                 if (fd == -1) {
  104                         if (errno == ENOENT) {
  105                                 fd = open(file_path, O_RDWR | O_CREAT, 0777);
  106                                 if (fd == -1) {
  107                                         err(1, "open file failed");
  108                                 }
  109                                 ret = ftruncate(fd, page_size);
  110                                 if (ret == -1) {
  111                                         err(1, "truncate file failed");
  112                                 }
  113                         } else {
  114                                 err(1, "open file failed");
  115                         }
  116                 }
  117 
  118                 if ((buf = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
  119                     MAP_SHARED, fd, 0)) == MAP_FAILED) {
  120                         err(1, "map file failed");
  121                 }
  122 
  123                 if (fd != -1)
  124                         close(fd);
  125 
  126                 char s[10] = {0, };
  127                 memcpy(buf, s, 10);
  128                 ret = munmap(buf, page_size);
  129                 if (ret != 0) {
  130                         err(1, "unmap file failed");
  131                 }
  132         }
  133 }
  134 
  135 int
  136 main(int argc, char **argv)
  137 {
  138         pthread_t map_write_tid;
  139         pthread_t normal_write_tid[NORMAL_WRITE_TH_NUM];
  140         int i = 0;
  141 
  142         if (argc != 3) {
  143                 (void) printf("usage: %s <normal write file name> "
  144                     "<map write file name>\n", argv[0]);
  145                 exit(1);
  146         }
  147 
  148         for (i = 0; i < NORMAL_WRITE_TH_NUM; i++) {
  149                 if (pthread_create(&normal_write_tid[i], NULL, normal_writer,
  150                     argv[1])) {
  151                         err(1, "pthread_create normal_writer failed.");
  152                 }
  153         }
  154 
  155         if (pthread_create(&map_write_tid, NULL, map_writer, argv[2])) {
  156                 err(1, "pthread_create map_writer failed.");
  157         }
  158 
  159         pthread_join(map_write_tid, NULL);
  160         return (0);
  161 }

Cache object: c5d1fe0c018bdcde5814e8a825868de5


[ 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.