Path: blob/main/tests/sys/cddl/zfs/bin/rm_lnkcnt_zero_file.c
39536 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License (the "License").5* You may not use this file except in compliance with the License.6*7* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE8* or http://www.opensolaris.org/os/licensing.9* See the License for the specific language governing permissions10* and limitations under the License.11*12* When distributing Covered Code, include this CDDL HEADER in each13* file and include the License file at usr/src/OPENSOLARIS.LICENSE.14* If applicable, add the following below this CDDL HEADER, with the15* fields enclosed by brackets "[]" replaced with your own identifying16* information: Portions Copyright [yyyy] [name of copyright owner]17*18* CDDL HEADER END19*/2021/*22* Copyright 2007 Sun Microsystems, Inc. All rights reserved.23* Use is subject to license terms.24*/252627/*28* --------------------------------------------------------------------29* The purpose of this test is to see if the bug reported (#4723351) for30* UFS exists when using a ZFS file system.31* --------------------------------------------------------------------32*33*/34#define _REENTRANT 135#include <stdio.h>36#include <fcntl.h>37#include <pthread.h>38#include <errno.h>39#include <sys/types.h>40#include <sys/stat.h>41#include <stdlib.h>42#include <unistd.h>4344static const int TRUE = 1;45static char *filebase;4647static int48pickidx()49{50return (random() % 1000);51}5253/* ARGSUSED */54static void *55mover(void *a)56{57char buf[256];58int idx, ret;5960while (TRUE) {61idx = pickidx();62(void) sprintf(buf, "%s.%03d", filebase, idx);63ret = rename(filebase, buf);64if (ret < 0 && errno != ENOENT)65(void) perror("renaming file");66}6768return (NULL);69}7071/* ARGSUSED */72static void *73cleaner(void *a)74{75char buf[256];76int idx, ret;7778while (TRUE) {79idx = pickidx();80(void) sprintf(buf, "%s.%03d", filebase, idx);81ret = remove(buf);82if (ret < 0 && errno != ENOENT)83(void) perror("removing file");84}8586return (NULL);87}8889static void *90writer(void *a)91{92int *fd = (int *)a;9394while (TRUE) {95(void) close (*fd);96*fd = open(filebase, O_APPEND | O_RDWR | O_CREAT, 0644);97if (*fd < 0)98perror("refreshing file");99(void) write(*fd, "test\n", 5);100}101102return (NULL);103}104105int106main(int argc, char **argv)107{108int fd;109pthread_t tid;110111if (argc == 1) {112(void) printf("Usage: %s <filebase>\n", argv[0]);113exit(-1);114}115116filebase = argv[1];117fd = open(filebase, O_APPEND | O_RDWR | O_CREAT, 0644);118if (fd < 0) {119perror("creating test file");120exit(-1);121}122123if (pthread_setconcurrency(4)) { /* 3 threads + main */124fprintf(stderr, "failed to set concurrency\n");125exit(-1);126}127(void) pthread_create(&tid, NULL, mover, NULL);128(void) pthread_create(&tid, NULL, cleaner, NULL);129(void) pthread_create(&tid, NULL, writer, (void *) &fd);130131while (TRUE) {132int ret;133struct stat st;134135ret = stat(filebase, &st);136if (ret == 0 && (st.st_nlink > 2 || st.st_nlink < 1)) {137(void) printf("st.st_nlink = %d, exiting\n", \138(int)st.st_nlink);139exit(0);140}141(void) sleep(1);142}143144return (0);145}146147148