Index: user/pho/stress2/misc/namecache.sh =================================================================== --- user/pho/stress2/misc/namecache.sh (revision 357722) +++ user/pho/stress2/misc/namecache.sh (revision 357723) @@ -1,219 +1,219 @@ #!/bin/sh # # Copyright (c) 2009 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Test case for vfs.lookup_shared=1 that shows possible name cache # inconsistency: # $ ls -l /tmp/file.05015? # ls: /tmp/file.050150: No such file or directory # $ fsdb -r /dev/ad4s1e # ** /dev/ad4s1e (NO WRITE) # Examining file system `/dev/ad4s1e' # Last Mounted on /tmp # current inode: directory # I=2 MODE=41777 SIZE=5120 # BTIME=May 7 05:54:47 2006 [0 nsec] # MTIME=Apr 2 11:27:36 2009 [0 nsec] # CTIME=Apr 2 11:27:36 2009 [0 nsec] # ATIME=Apr 2 12:00:30 2009 [0 nsec] # OWNER=root GRP=wheel LINKCNT=35 FLAGS=0 BLKCNT=c GEN=65f71df4 # fsdb (inum: 2)> lookup file.050150 # component `file.050150': current inode: regular file # I=198 MODE=100600 SIZE=0 # BTIME=Apr 2 11:24:33 2009 [0 nsec] # MTIME=Apr 2 11:24:33 2009 [0 nsec] # CTIME=Apr 2 11:24:33 2009 [0 nsec] # ATIME=Apr 2 11:24:33 2009 [0 nsec] # OWNER=pho GRP=wheel LINKCNT=1 FLAGS=0 BLKCNT=0 GEN=1deaab3a # fsdb (inum: 198)> quit # $ # Consistency is restored by a umount + mount of the FS # Observations: # No problems seen with vfs.lookup_shared=0. # Does not fail in a "private" subdirectory . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > namecache.c mycc -o namecache -Wall namecache.c rm -f namecache.c #dir=/tmp/namecache.dir # No problems seen dir=/tmp [ -d $dir ] || mkdir -p $dir cd $dir start=`date '+%s'` for i in `jot 30`; do for j in `jot 10`; do /tmp/namecache & done for j in `jot 10`; do wait done - [ $((`date '+%s'` - start)) -gt 1800 ] && break + [ $((`date '+%s'` - start)) -gt 1200 ] && break done if ls -l $dir/file.0* 2>&1 | egrep "file.0[0-9]" | grep -q "No such file"; then echo FAIL echo "ls -l $dir/file.0*" ls -l $dir/file.0* fi rm -f /tmp/namecache # /$dir/file.0* exit EOF /* Test scenario for possible name cache problem */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include static char path[MAXPATHLEN+1]; static char buf[64 * 1024]; void pm(void) { int fd, n; int space = sizeof(buf); struct stat statb; - long base; + off_t base; struct dirent *dp; char *bp = buf; if ((fd = open(".", O_RDONLY)) == -1) err(1, "open(%s)", "."); do { if ((n = getdirentries(fd, bp, space, &base)) == -1) err(1, "getdirentries"); space = space - n; bp = bp + n; } while (n != 0); close(fd); bp = buf; dp = (struct dirent *)bp; for (;;) { if (strcmp(path, dp->d_name) == 0) { if (stat(dp->d_name, &statb) == -1) { warn("stat(%s)", dp->d_name); printf("name: %-10s, inode %7ju, " "type %2d, namelen %d, d_reclen %d\n", dp->d_name, (uintmax_t)dp->d_fileno, dp->d_type, dp->d_namlen, dp->d_reclen); fflush(stdout); } else { printf("stat(%s) succeeded!\n", path); fflush(stdout); } } bp = bp + dp->d_reclen; dp = (struct dirent *)bp; if (dp->d_reclen <= 0) break; } } static void reader(void) { int fd; if ((fd = open(path, O_RDWR, 0600)) < 0) { warn("open(%s). %s:%d", path, __FILE__, __LINE__); pm(); exit(1); } close(fd); return; } static void writer(void) { int fd; if ((fd = open(path, O_RDWR, 0600)) < 0) { warn("open(%s). %s:%d", path, __FILE__, __LINE__); pm(); exit(1); } close(fd); return; } int main(int argc, char **argv) { pid_t pid; int fd, i, status; for (i = 0; i < 10000; i++) { if (sprintf(path, "file.0%d", getpid()) < 0) err(1, "sprintf()"); if ((fd = open(path, O_CREAT | O_RDWR, 0600)) == -1) err(1, "open(%s)", path); close(fd); if ((pid = fork()) == 0) { writer(); exit(EXIT_SUCCESS); } else if (pid > 0) { reader(); if (waitpid(pid, &status, 0) == -1) warn("waitpid(%d)", pid); } else err(1, "fork(), %s:%d", __FILE__, __LINE__); if (unlink(path) == -1) err(1, "unlink(%s). %s:%d", path, __FILE__, __LINE__); } return (0); } Index: user/pho/stress2/misc/namecache2.sh =================================================================== --- user/pho/stress2/misc/namecache2.sh (revision 357722) +++ user/pho/stress2/misc/namecache2.sh (revision 357723) @@ -1,194 +1,194 @@ #!/bin/sh # # Copyright (c) 2013 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # UFS cache inconsistancy for rename(2) demonstrated # Fails with: # ls -ali /mnt # ls: tfa1022: No such file or directory # Fixed by r248422 # Test scenario obtained from Rick Miller [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 # This threaded test is designed for MP. [ `sysctl hw.ncpu | sed 's/.* //'` -eq 1 ] && exit 0 . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > namecache2.c rm -f /tmp/namecache2 mycc -o namecache2 -Wall -Wextra -g -O2 namecache2.c -lpthread || exit 1 rm -f namecache2.c cd $odir mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart mdconfig -a -t swap -s 1g -u $mdstart bsdlabel -w md$mdstart auto newfs $newfs_flags md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint (cd $mntpoint; /tmp/namecache2) f=`(cd $mntpoint; echo *)` if [ "$f" != '*' ]; then echo FAIL echo "echo $mntpoint/*" echo $mntpoint/* echo "" echo "ls -ali $mntpoint" ls -ali $mntpoint echo "" echo "fsdb -r /dev/md${mdstart}$part" fsdb -r /dev/md${mdstart}$part <<-EF ls quit EF fi while mount | grep $mntpoint | grep -q /dev/md; do umount $mntpoint || sleep 1 done mdconfig -d -u $mdstart rm -f /tmp/namecache2 exit 0 EOF /* * NOTE: This must be run with the current working directory on a local UFS * disk partition, to demonstrate a FreeBSD namecache bug. I have never seen * this bug happen with an NFS partition. */ #include #include #include #include #include #include #include #include #include #include #include int stopping = false; char *pFilename = 0; static void * statThread(void *arg __unused) { struct stat statData; int rc; for (;;) { while (pFilename == 0) { if (stopping) return 0; } rc = stat(pFilename, &statData); if (rc < 0 && errno != ENOENT) { printf(" statThread stat() on %s failed with errno %d\n", pFilename, errno); return 0; } } return 0; } int main(void) { char filename1 [20], filename2[20], filename3[20]; pthread_t threadId; struct stat statData; int result, fd; unsigned int number; struct timespec period; time_t start; sprintf(filename1, "tfa0"); fd = open(filename1, O_CREAT, S_IRWXU); if (fd < 0) { printf("open(O_CREAT) on %s failed with errno %d\n", filename1, errno); return 0; } if (close(fd) < 0) { printf("close() on %s failed with errno %d\n", filename1, errno); return 0; } result = pthread_create(&threadId, NULL, statThread, NULL); if (result < 0) errc(1, result, "pthread_create()"); start = time(NULL); for (number = 0; number < 0x001FFFFF; number += 2) { sprintf(filename1, "tfa%u", number); sprintf(filename2, "tfa%u", number + 1); sprintf(filename3, "tfa%u", number + 2); if (rename(filename1, filename2) < 0) { printf(" rename1() from %s to %s failed with errno %d\n", filename1, filename2, errno); return 0; } pFilename = filename3; if (rename(filename2, filename3) < 0) { printf(" rename2() from %s to %s failed with errno %d\n", filename2, filename3, errno); return 0; } pFilename = 0; period.tv_sec = 0; period.tv_nsec = 500; nanosleep(&period, 0); if (stat(filename3, &statData) < 0) { printf("stat(%s) failed with errno %d\n", filename3, errno); stopping = true; period.tv_sec = 0; period.tv_nsec = 500; nanosleep(&period, 0); return 0; } - if (time(NULL) - start > 1800) { + if (time(NULL) - start > 1200) { fprintf(stderr, "Test timed out.\n"); break; } } unlink(filename3); return 0; }