Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/dir_rd_update.c
48529 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* 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.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/2122/*23* Copyright 2007 Sun Microsystems, Inc. All rights reserved.24* Use is subject to license terms.25*/2627/*28* Assertion:29*30* A read operation and directory update operation performed31* concurrently on the same directory can lead to deadlock32* on a UFS logging file system, but not on a ZFS file system.33*/3435#include <sys/types.h>36#include <sys/stat.h>37#include <errno.h>38#include <fcntl.h>39#include <string.h>40#include <stdio.h>41#include <stdlib.h>42#include <unistd.h>43#define TMP_DIR /tmp4445static char dirpath[256];4647int48main(int argc, char **argv)49{50const char *cp1 = "";51int i = 0;52int ret = 0;53int testdd = 0;54pid_t pid;55static const int op_num = 5;5657if (argc == 1) {58(void) printf("Usage: %s <mount point>\n", argv[0]);59exit(-1);60}61for (i = 0; i < 256; i++) {62dirpath[i] = 0;63}6465cp1 = argv[1];66if (strlen(cp1) >= (sizeof (dirpath) - strlen("/TMP_DIR"))) {67(void) printf("The string length of mount point is "68"too large\n");69exit(-1);70}71(void) snprintf(dirpath, sizeof (dirpath), "%s/TMP_DIR", cp1);7273ret = mkdir(dirpath, 0777);74if (ret != 0) {75if (errno != EEXIST) {76(void) printf("%s: mkdir(<%s>, 0777) failed: errno "77"(decimal)=%d\n", argv[0], dirpath, errno);78exit(-1);79}80}81testdd = open(dirpath, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC);82if (testdd < 0) {83(void) printf("%s: open(<%s>, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC)"84" failed: errno (decimal)=%d\n", argv[0], dirpath, errno);85exit(-1);86} else {87(void) close(testdd);88}89pid = fork();90if (pid > 0) {91int fd = open(dirpath, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC);92char buf[16];93int rdret;94int j = 0;9596if (fd < 0) {97(void) printf("%s: open <%s> again failed:"98" errno = %d\n", argv[0], dirpath, errno);99exit(-1);100}101102while (j < op_num) {103(void) sleep(1);104rdret = read(fd, buf, 16);105if (rdret == -1) {106(void) printf("readdir failed");107}108j++;109}110(void) close(fd);111} else if (pid == 0) {112int fd = open(dirpath, O_RDONLY);113int chownret;114int k = 0;115116if (fd < 0) {117(void) printf("%s: open(<%s>, O_RDONLY) again failed:"118" errno (decimal)=%d\n", argv[0], dirpath, errno);119exit(-1);120}121122while (k < op_num) {123(void) sleep(1);124chownret = fchown(fd, 0, 0);125if (chownret == -1) {126(void) printf("chown failed");127}128129k++;130}131(void) close(fd);132}133134return (0);135}136137138