1#!/bin/sh 2 3# 4# Copyright (c) 2008 Peter Holm <pho@FreeBSD.org> 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# Regression test for statfs problems with deleting a large number of files 30 31# $ ./statfs.sh 32# Filesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on 33# /dev/ad0s1e 1982798 1782134 42042 98% 4965 254105 2% /tmp 34# Free inodes on /tmp: 254105 35# Creating 100000 files... 36# Deleting 100000 files... 37# Filesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on 38# /dev/ad0s1e 1982798 -284096 2108272 -16% 4965 254105 2% /tmp 39# $ umount -f /tmp; mount /tmp 40# $ df -i /tmp 41# Filesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on 42# /dev/ad0s1e 1982798 1784528 39648 98% 4965 254105 2% /tmp 43 44. ../default.cfg 45 46odir=`pwd` 47dir=/tmp 48 49cd $dir 50sed '1,/^EOF/d' < $odir/$0 > $dir/statfs.c 51mycc -o statfs -Wall statfs.c 52rm -f statfs.c 53 54df -i /tmp 55./statfs 56df -i /tmp 57 58exit 59EOF 60#include <sys/types.h> 61#include <sys/sysctl.h> 62#include <unistd.h> 63#include <stdio.h> 64#include <fcntl.h> 65#include <stdlib.h> 66#include <sys/stat.h> 67#include <sys/param.h> 68#include <sys/mount.h> 69#include <errno.h> 70#include <err.h> 71 72int64_t 73inodes(void) 74{ 75 char path[MAXPATHLEN+1]; 76 struct statfs buf; 77 78 sync(); 79 if (getcwd(path, sizeof(path)) == NULL) 80 err(1, "getcwd()"); 81 82 if (statfs(path, &buf) < 0) 83 err(1, "statfs(%s)", path); 84 printf("Free inodes on %s: %jd\n", path, buf.f_ffree); 85 return (buf.f_ffree); 86} 87 88int 89main() 90{ 91 int fd, i, j; 92 int64_t size; 93 pid_t pid; 94 char file[128]; 95 96 size = inodes() - 1000; 97 98 if (size > 100000) 99 size = 100000; 100 101 printf("Creating %jd files...", size); fflush(stdout); 102 pid = getpid(); 103 for (j = 0; j < size; j++) { 104 sprintf(file,"p%06d.%05d", pid, j); 105 if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0666)) == -1) { 106 if (errno != EINTR) { 107 warn("creat(%s)", file); 108 printf("break out at %d, errno %d\n", j, errno); 109 break; 110 } 111 } 112 if (fd != -1 && close(fd) == -1) 113 err(2, "close(%d)", j); 114 115 } 116 117 printf("\nDeleting %jd files...", size); fflush(stdout); 118 for (i = --j; i >= 0; i--) { 119 sprintf(file,"p%06d.%05d", pid, i); 120 if (unlink(file) == -1) 121 err(3, "unlink(%s)", file); 122 123 } 124 printf("\n"); 125 return (0); 126} 127