summaryrefslogtreecommitdiff
path: root/regress/sys
diff options
context:
space:
mode:
authorPedro Martelletto <pedro@cvs.openbsd.org>2007-03-30 19:02:53 +0000
committerPedro Martelletto <pedro@cvs.openbsd.org>2007-03-30 19:02:53 +0000
commita43ee3c02d87b24b5d42a21bea8c53251ff63ba1 (patch)
treebd8ac259df6b2244d1a16cb5cb1b652eeaff32d6 /regress/sys
parent01d780afe96118f9a23cd8132c1965c12c6ddb17 (diff)
Add regression test suite for FFS, from FreeBSD, okay art@ deraadt@
Diffstat (limited to 'regress/sys')
-rw-r--r--regress/sys/ffs/LICENSE28
-rw-r--r--regress/sys/ffs/Makefile71
-rw-r--r--regress/sys/ffs/README4
-rw-r--r--regress/sys/ffs/fstest.c700
-rw-r--r--regress/sys/ffs/run60
-rw-r--r--regress/sys/ffs/tests/chflags/00.t171
-rw-r--r--regress/sys/ffs/tests/chflags/01.t13
-rw-r--r--regress/sys/ffs/tests/chflags/02.t11
-rw-r--r--regress/sys/ffs/tests/chflags/03.t18
-rw-r--r--regress/sys/ffs/tests/chflags/04.t7
-rw-r--r--regress/sys/ffs/tests/chflags/05.t28
-rw-r--r--regress/sys/ffs/tests/chflags/06.t14
-rw-r--r--regress/sys/ffs/tests/chflags/07.t47
-rw-r--r--regress/sys/ffs/tests/chflags/08.t63
-rw-r--r--regress/sys/ffs/tests/chflags/09.t51
-rw-r--r--regress/sys/ffs/tests/chflags/10.t55
-rw-r--r--regress/sys/ffs/tests/chflags/11.t63
-rw-r--r--regress/sys/ffs/tests/chflags/12.t31
-rw-r--r--regress/sys/ffs/tests/chflags/13.t7
-rw-r--r--regress/sys/ffs/tests/chmod/00.t119
-rw-r--r--regress/sys/ffs/tests/chmod/01.t13
-rw-r--r--regress/sys/ffs/tests/chmod/02.t10
-rw-r--r--regress/sys/ffs/tests/chmod/03.t17
-rw-r--r--regress/sys/ffs/tests/chmod/04.t12
-rw-r--r--regress/sys/ffs/tests/chmod/05.t26
-rw-r--r--regress/sys/ffs/tests/chmod/06.t14
-rw-r--r--regress/sys/ffs/tests/chmod/07.t26
-rw-r--r--regress/sys/ffs/tests/chmod/08.t52
-rw-r--r--regress/sys/ffs/tests/chmod/09.t27
-rw-r--r--regress/sys/ffs/tests/chmod/10.t7
-rw-r--r--regress/sys/ffs/tests/chmod/11.t36
-rw-r--r--regress/sys/ffs/tests/chown/00.t277
-rw-r--r--regress/sys/ffs/tests/chown/01.t13
-rw-r--r--regress/sys/ffs/tests/chown/02.t9
-rw-r--r--regress/sys/ffs/tests/chown/03.t17
-rw-r--r--regress/sys/ffs/tests/chown/04.t12
-rw-r--r--regress/sys/ffs/tests/chown/05.t27
-rw-r--r--regress/sys/ffs/tests/chown/06.t14
-rw-r--r--regress/sys/ffs/tests/chown/07.t23
-rw-r--r--regress/sys/ffs/tests/chown/08.t46
-rw-r--r--regress/sys/ffs/tests/chown/09.t27
-rw-r--r--regress/sys/ffs/tests/chown/10.t7
-rw-r--r--regress/sys/ffs/tests/link/00.t146
-rw-r--r--regress/sys/ffs/tests/link/01.t17
-rw-r--r--regress/sys/ffs/tests/link/02.t18
-rw-r--r--regress/sys/ffs/tests/link/03.t23
-rw-r--r--regress/sys/ffs/tests/link/04.t15
-rw-r--r--regress/sys/ffs/tests/link/05.t31
-rw-r--r--regress/sys/ffs/tests/link/06.t38
-rw-r--r--regress/sys/ffs/tests/link/07.t36
-rw-r--r--regress/sys/ffs/tests/link/08.t19
-rw-r--r--regress/sys/ffs/tests/link/09.t13
-rw-r--r--regress/sys/ffs/tests/link/10.t27
-rw-r--r--regress/sys/ffs/tests/link/11.t24
-rw-r--r--regress/sys/ffs/tests/link/12.t48
-rw-r--r--regress/sys/ffs/tests/link/13.t49
-rw-r--r--regress/sys/ffs/tests/link/14.t24
-rw-r--r--regress/sys/ffs/tests/link/15.t28
-rw-r--r--regress/sys/ffs/tests/link/16.t29
-rw-r--r--regress/sys/ffs/tests/link/17.t15
-rw-r--r--regress/sys/ffs/tests/mkdir/00.t68
-rw-r--r--regress/sys/ffs/tests/mkdir/01.t13
-rw-r--r--regress/sys/ffs/tests/mkdir/02.t8
-rw-r--r--regress/sys/ffs/tests/mkdir/03.t16
-rw-r--r--regress/sys/ffs/tests/mkdir/04.t11
-rw-r--r--regress/sys/ffs/tests/mkdir/05.t24
-rw-r--r--regress/sys/ffs/tests/mkdir/06.t24
-rw-r--r--regress/sys/ffs/tests/mkdir/07.t14
-rw-r--r--regress/sys/ffs/tests/mkdir/08.t46
-rw-r--r--regress/sys/ffs/tests/mkdir/09.t24
-rw-r--r--regress/sys/ffs/tests/mkdir/10.t22
-rw-r--r--regress/sys/ffs/tests/mkdir/11.t26
-rw-r--r--regress/sys/ffs/tests/mkdir/12.t7
-rw-r--r--regress/sys/ffs/tests/mkfifo/00.t68
-rw-r--r--regress/sys/ffs/tests/mkfifo/01.t13
-rw-r--r--regress/sys/ffs/tests/mkfifo/02.t8
-rw-r--r--regress/sys/ffs/tests/mkfifo/03.t16
-rw-r--r--regress/sys/ffs/tests/mkfifo/04.t11
-rw-r--r--regress/sys/ffs/tests/mkfifo/05.t24
-rw-r--r--regress/sys/ffs/tests/mkfifo/06.t24
-rw-r--r--regress/sys/ffs/tests/mkfifo/07.t14
-rw-r--r--regress/sys/ffs/tests/mkfifo/08.t24
-rw-r--r--regress/sys/ffs/tests/mkfifo/09.t22
-rw-r--r--regress/sys/ffs/tests/mkfifo/10.t46
-rw-r--r--regress/sys/ffs/tests/mkfifo/11.t26
-rw-r--r--regress/sys/ffs/tests/mkfifo/12.t7
-rw-r--r--regress/sys/ffs/tests/open/00.t94
-rw-r--r--regress/sys/ffs/tests/open/01.t13
-rw-r--r--regress/sys/ffs/tests/open/02.t9
-rw-r--r--regress/sys/ffs/tests/open/03.t17
-rw-r--r--regress/sys/ffs/tests/open/04.t12
-rw-r--r--regress/sys/ffs/tests/open/05.t24
-rw-r--r--regress/sys/ffs/tests/open/06.t84
-rw-r--r--regress/sys/ffs/tests/open/07.t40
-rw-r--r--regress/sys/ffs/tests/open/08.t14
-rw-r--r--regress/sys/ffs/tests/open/09.t46
-rw-r--r--regress/sys/ffs/tests/open/10.t38
-rw-r--r--regress/sys/ffs/tests/open/11.t32
-rw-r--r--regress/sys/ffs/tests/open/12.t14
-rw-r--r--regress/sys/ffs/tests/open/13.t17
-rw-r--r--regress/sys/ffs/tests/open/14.t27
-rw-r--r--regress/sys/ffs/tests/open/15.t22
-rw-r--r--regress/sys/ffs/tests/open/16.t14
-rw-r--r--regress/sys/ffs/tests/open/17.t10
-rw-r--r--regress/sys/ffs/tests/open/18.t13
-rw-r--r--regress/sys/ffs/tests/open/19.t26
-rw-r--r--regress/sys/ffs/tests/open/20.t13
-rw-r--r--regress/sys/ffs/tests/open/21.t7
-rw-r--r--regress/sys/ffs/tests/open/22.t22
-rw-r--r--regress/sys/ffs/tests/open/23.t11
-rw-r--r--regress/sys/ffs/tests/rename/00.t136
-rw-r--r--regress/sys/ffs/tests/rename/01.t16
-rw-r--r--regress/sys/ffs/tests/rename/02.t21
-rw-r--r--regress/sys/ffs/tests/rename/03.t15
-rw-r--r--regress/sys/ffs/tests/rename/04.t38
-rw-r--r--regress/sys/ffs/tests/rename/05.t36
-rw-r--r--regress/sys/ffs/tests/rename/06.t43
-rw-r--r--regress/sys/ffs/tests/rename/07.t88
-rw-r--r--regress/sys/ffs/tests/rename/08.t88
-rw-r--r--regress/sys/ffs/tests/rename/09.t89
-rw-r--r--regress/sys/ffs/tests/rename/10.t238
-rw-r--r--regress/sys/ffs/tests/rename/11.t19
-rw-r--r--regress/sys/ffs/tests/rename/12.t17
-rw-r--r--regress/sys/ffs/tests/rename/13.t29
-rw-r--r--regress/sys/ffs/tests/rename/14.t29
-rw-r--r--regress/sys/ffs/tests/rename/15.t35
-rw-r--r--regress/sys/ffs/tests/rename/16.t27
-rw-r--r--regress/sys/ffs/tests/rename/17.t15
-rw-r--r--regress/sys/ffs/tests/rename/18.t17
-rw-r--r--regress/sys/ffs/tests/rename/19.t17
-rw-r--r--regress/sys/ffs/tests/rename/20.t30
-rw-r--r--regress/sys/ffs/tests/rmdir/00.t23
-rw-r--r--regress/sys/ffs/tests/rmdir/01.t25
-rw-r--r--regress/sys/ffs/tests/rmdir/02.t9
-rw-r--r--regress/sys/ffs/tests/rmdir/03.t17
-rw-r--r--regress/sys/ffs/tests/rmdir/04.t12
-rw-r--r--regress/sys/ffs/tests/rmdir/05.t14
-rw-r--r--regress/sys/ffs/tests/rmdir/06.t31
-rw-r--r--regress/sys/ffs/tests/rmdir/07.t22
-rw-r--r--regress/sys/ffs/tests/rmdir/08.t22
-rw-r--r--regress/sys/ffs/tests/rmdir/09.t42
-rw-r--r--regress/sys/ffs/tests/rmdir/10.t45
-rw-r--r--regress/sys/ffs/tests/rmdir/11.t35
-rw-r--r--regress/sys/ffs/tests/rmdir/12.t14
-rw-r--r--regress/sys/ffs/tests/rmdir/13.t17
-rw-r--r--regress/sys/ffs/tests/rmdir/14.t22
-rw-r--r--regress/sys/ffs/tests/rmdir/15.t7
-rw-r--r--regress/sys/ffs/tests/symlink/00.t27
-rw-r--r--regress/sys/ffs/tests/symlink/01.t13
-rw-r--r--regress/sys/ffs/tests/symlink/02.t15
-rw-r--r--regress/sys/ffs/tests/symlink/03.t21
-rw-r--r--regress/sys/ffs/tests/symlink/04.t11
-rw-r--r--regress/sys/ffs/tests/symlink/05.t29
-rw-r--r--regress/sys/ffs/tests/symlink/06.t29
-rw-r--r--regress/sys/ffs/tests/symlink/07.t14
-rw-r--r--regress/sys/ffs/tests/symlink/08.t18
-rw-r--r--regress/sys/ffs/tests/symlink/09.t46
-rw-r--r--regress/sys/ffs/tests/symlink/10.t27
-rw-r--r--regress/sys/ffs/tests/symlink/11.t27
-rw-r--r--regress/sys/ffs/tests/symlink/12.t13
-rw-r--r--regress/sys/ffs/tests/truncate/00.t46
-rw-r--r--regress/sys/ffs/tests/truncate/01.t13
-rw-r--r--regress/sys/ffs/tests/truncate/02.t10
-rw-r--r--regress/sys/ffs/tests/truncate/03.t17
-rw-r--r--regress/sys/ffs/tests/truncate/04.t12
-rw-r--r--regress/sys/ffs/tests/truncate/05.t27
-rw-r--r--regress/sys/ffs/tests/truncate/06.t19
-rw-r--r--regress/sys/ffs/tests/truncate/07.t14
-rw-r--r--regress/sys/ffs/tests/truncate/08.t52
-rw-r--r--regress/sys/ffs/tests/truncate/09.t10
-rw-r--r--regress/sys/ffs/tests/truncate/10.t27
-rw-r--r--regress/sys/ffs/tests/truncate/11.t11
-rw-r--r--regress/sys/ffs/tests/truncate/12.t22
-rw-r--r--regress/sys/ffs/tests/truncate/13.t11
-rw-r--r--regress/sys/ffs/tests/truncate/14.t7
-rw-r--r--regress/sys/ffs/tests/unlink/00.t110
-rw-r--r--regress/sys/ffs/tests/unlink/01.t13
-rw-r--r--regress/sys/ffs/tests/unlink/02.t9
-rw-r--r--regress/sys/ffs/tests/unlink/03.t17
-rw-r--r--regress/sys/ffs/tests/unlink/04.t12
-rw-r--r--regress/sys/ffs/tests/unlink/05.t22
-rw-r--r--regress/sys/ffs/tests/unlink/06.t22
-rw-r--r--regress/sys/ffs/tests/unlink/07.t14
-rw-r--r--regress/sys/ffs/tests/unlink/08.t10
-rw-r--r--regress/sys/ffs/tests/unlink/09.t42
-rw-r--r--regress/sys/ffs/tests/unlink/10.t45
-rw-r--r--regress/sys/ffs/tests/unlink/11.t63
-rw-r--r--regress/sys/ffs/tests/unlink/12.t22
-rw-r--r--regress/sys/ffs/tests/unlink/13.t7
189 files changed, 6494 insertions, 0 deletions
diff --git a/regress/sys/ffs/LICENSE b/regress/sys/ffs/LICENSE
new file mode 100644
index 00000000000..0cbd1fb4919
--- /dev/null
+++ b/regress/sys/ffs/LICENSE
@@ -0,0 +1,28 @@
+$OpenBSD: LICENSE,v 1.1 2007/03/30 19:02:51 pedro Exp $
+$FreeBSD: src/tools/regression/fstest/LICENSE,v 1.1 2007/01/17 01:42:07 pjd Exp $
+
+The license for all regression tests available in this directory is as follows:
+
+Copyright (c) 2006-2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+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 AUTHORS 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 AUTHORS 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.
diff --git a/regress/sys/ffs/Makefile b/regress/sys/ffs/Makefile
new file mode 100644
index 00000000000..4098d18702f
--- /dev/null
+++ b/regress/sys/ffs/Makefile
@@ -0,0 +1,71 @@
+# $OpenBSD: Makefile,v 1.1 2007/03/30 19:02:51 pedro Exp $
+
+PROG= fstest
+
+mount:
+ dd if=/dev/zero of=${.CURDIR}/fakeobj bs=512 count=4k
+ vnconfig svnd0 ${.CURDIR}/fakeobj
+ newfs /dev/rsvnd0c
+ mount /dev/svnd0c /mnt
+
+clean:
+ -umount -f /mnt
+ -vnconfig -u svnd0
+ -vnconfig -u svnd1
+ -rm -f ${.CURDIR}/fakeobj
+ -rm -f ${.OBJDIR}/fstest
+ -rm -f ${.OBJDIR}/fstest.o
+
+chflags: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/chflags/*.t
+
+chmod: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/chmod/*.t
+
+chown: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/chown/*.t
+
+link: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/link/*.t
+
+mkdir: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/mkdir/*.t
+
+mkfifo: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/mkfifo/*.t
+
+open: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/open/*.t
+
+rename: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/rename/*.t
+
+rmdir: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/rmdir/*.t
+
+symlink: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/symlink/*.t
+
+truncate: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/truncate/*.t
+
+unlink: ${PROG} mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/unlink/*.t
+
+run-regress-fstest: mount
+ cd /mnt && env FSTEST=${.OBJDIR}/fstest ${.CURDIR}/run\
+ ${.CURDIR}/tests/*/*.t
+
+.include <bsd.regress.mk>
diff --git a/regress/sys/ffs/README b/regress/sys/ffs/README
new file mode 100644
index 00000000000..3a13e2e57ce
--- /dev/null
+++ b/regress/sys/ffs/README
@@ -0,0 +1,4 @@
+$OpenBSD: README,v 1.1 2007/03/30 19:02:51 pedro Exp $
+
+These tests must be run as root, on a system with free svnd0 and svnd1 slots.
+It is also advised that /mnt be unmounted, and clean.
diff --git a/regress/sys/ffs/fstest.c b/regress/sys/ffs/fstest.c
new file mode 100644
index 00000000000..af7047882ab
--- /dev/null
+++ b/regress/sys/ffs/fstest.c
@@ -0,0 +1,700 @@
+/* $OpenBSD: fstest.c,v 1.1 2007/03/30 19:02:51 pedro Exp $ */
+
+/*
+ * Copyright (c) 2006-2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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 AUTHORS 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 AUTHORS 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: src/tools/regression/fstest/fstest.c,v 1.1 2007/01/17 01:42:07 pjd Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <assert.h>
+
+enum action {
+ ACTION_OPEN,
+ ACTION_CREATE,
+ ACTION_UNLINK,
+ ACTION_MKDIR,
+ ACTION_RMDIR,
+ ACTION_LINK,
+ ACTION_SYMLINK,
+ ACTION_RENAME,
+ ACTION_MKFIFO,
+ ACTION_CHMOD,
+ ACTION_CHOWN,
+ ACTION_LCHOWN,
+ ACTION_CHFLAGS,
+ ACTION_TRUNCATE,
+ ACTION_STAT,
+ ACTION_LSTAT,
+};
+
+#define TYPE_NONE 0x0000
+#define TYPE_STRING 0x0001
+#define TYPE_NUMBER 0x0002
+#define TYPE_OPTIONAL 0x0100
+#define MAX_ARGS 8
+
+struct syscall_desc {
+ char *sd_name;
+ enum action sd_action;
+ int sd_args[MAX_ARGS];
+};
+
+static struct syscall_desc syscalls[] = {
+ { "open", ACTION_OPEN, { TYPE_STRING, TYPE_STRING,
+ TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } },
+ { "create", ACTION_CREATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
+ { "unlink", ACTION_UNLINK, { TYPE_STRING, TYPE_NONE } },
+ { "mkdir", ACTION_MKDIR, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
+ { "rmdir", ACTION_RMDIR, { TYPE_STRING, TYPE_NONE } },
+ { "link", ACTION_LINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { "symlink", ACTION_SYMLINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { "rename", ACTION_RENAME, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { "mkfifo", ACTION_MKFIFO, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
+ { "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
+ { "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER,
+ TYPE_NUMBER, TYPE_NONE } },
+ { "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER,
+ TYPE_NUMBER, TYPE_NONE } },
+ { "chflags", ACTION_CHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { "truncate", ACTION_TRUNCATE, { TYPE_STRING, TYPE_NUMBER,
+ TYPE_NONE } },
+ { "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { NULL, -1, { TYPE_NONE } }
+};
+
+struct flag {
+ long long f_flag;
+ char *f_str;
+};
+
+static struct flag open_flags[] = {
+ { O_RDONLY, "O_RDONLY" },
+ { O_WRONLY, "O_WRONLY" },
+ { O_RDWR, "O_RDWR" },
+ { O_NONBLOCK, "O_NONBLOCK" },
+ { O_APPEND, "O_APPEND" },
+ { O_CREAT, "O_CREAT" },
+ { O_TRUNC, "O_TRUNC" },
+ { O_EXCL, "O_EXCL" },
+ { O_SHLOCK, "O_SHLOCK" },
+ { O_EXLOCK, "O_EXLOCK" },
+ { O_FSYNC, "O_FSYNC" },
+ { O_SYNC, "O_SYNC" },
+ { O_NOFOLLOW, "O_NOFOLLOW" },
+ { O_NOCTTY, "O_NOCTTY" },
+ { 0, NULL }
+};
+
+static struct flag chflags_flags[] = {
+ { UF_NODUMP, "UF_NODUMP" },
+ { UF_IMMUTABLE, "UF_IMMUTABLE" },
+ { UF_APPEND, "UF_APPEND" },
+ { UF_OPAQUE, "UF_OPAQUE" },
+ { SF_ARCHIVED, "SF_ARCHIVED" },
+ { SF_IMMUTABLE, "SF_IMMUTABLE" },
+ { SF_APPEND, "SF_APPEND" },
+ { 0, NULL }
+};
+
+static const char *err2str(int error);
+
+__dead static void
+usage(void)
+{
+ fprintf(stderr, "usage: fstest [-u uid] [-g gid1[,gid2[...]]] syscall "
+ "args ...\n");
+ exit(1);
+}
+
+static long long
+str2flags(struct flag *tflags, char *sflags)
+{
+ long long flags = 0;
+ unsigned int i;
+ char *f;
+
+ for (f = strtok(sflags, ","); f != NULL; f = strtok(NULL, ",")) {
+ /* Support magic 'none' flag which just reset all flags. */
+ if (strcmp(f, "none") == 0)
+ return (0);
+ for (i = 0; tflags[i].f_str != NULL; i++) {
+ if (strcmp(tflags[i].f_str, f) == 0)
+ break;
+ }
+ if (tflags[i].f_str == NULL) {
+ fprintf(stderr, "unknown flag '%s'\n", f);
+ exit(1);
+ }
+ flags |= tflags[i].f_flag;
+ }
+ return (flags);
+}
+
+static char *
+flags2str(struct flag *tflags, long long flags)
+{
+ static char sflags[1024];
+ unsigned int i;
+
+ sflags[0] = '\0';
+ for (i = 0; tflags[i].f_str != NULL; i++) {
+ if (flags & tflags[i].f_flag) {
+ if (sflags[0] != '\0')
+ strlcat(sflags, ",", sizeof(sflags));
+ strlcat(sflags, tflags[i].f_str, sizeof(sflags));
+ }
+ }
+ if (sflags[0] == '\0')
+ strlcpy(sflags, "none", sizeof(sflags));
+ return (sflags);
+}
+
+static struct syscall_desc *
+find_syscall(const char *name)
+{
+ int i;
+
+ for (i = 0; syscalls[i].sd_name != NULL; i++) {
+ if (strcmp(syscalls[i].sd_name, name) == 0)
+ return (&syscalls[i]);
+ }
+ return (NULL);
+}
+
+static void
+show_stat(struct stat *sp, const char *what)
+{
+
+ if (strcmp(what, "mode") == 0)
+ printf("0%o", (unsigned int)(sp->st_mode & ALLPERMS));
+ else if (strcmp(what, "inode") == 0)
+ printf("%lld", (long long)sp->st_ino);
+ else if (strcmp(what, "nlink") == 0)
+ printf("%lld", (long long)sp->st_nlink);
+ else if (strcmp(what, "uid") == 0)
+ printf("%d", (int)sp->st_uid);
+ else if (strcmp(what, "gid") == 0)
+ printf("%d", (int)sp->st_gid);
+ else if (strcmp(what, "size") == 0)
+ printf("%lld", (long long)sp->st_size);
+ else if (strcmp(what, "blocks") == 0)
+ printf("%lld", (long long)sp->st_blocks);
+ else if (strcmp(what, "atime") == 0)
+ printf("%lld", (long long)sp->st_atime);
+ else if (strcmp(what, "mtime") == 0)
+ printf("%lld", (long long)sp->st_mtime);
+ else if (strcmp(what, "ctime") == 0)
+ printf("%lld", (long long)sp->st_ctime);
+ else if (strcmp(what, "flags") == 0)
+ printf("%s", flags2str(chflags_flags, sp->st_flags));
+ else if (strcmp(what, "type") == 0) {
+ switch (sp->st_mode & S_IFMT) {
+ case S_IFIFO:
+ printf("fifo");
+ break;
+ case S_IFCHR:
+ printf("char");
+ break;
+ case S_IFDIR:
+ printf("dir");
+ break;
+ case S_IFBLK:
+ printf("block");
+ break;
+ case S_IFREG:
+ printf("regular");
+ break;
+ case S_IFLNK:
+ printf("symlink");
+ break;
+ case S_IFSOCK:
+ printf("socket");
+ break;
+ default:
+ printf("unknown");
+ break;
+ }
+ } else {
+ printf("unknown");
+ }
+}
+
+static void
+show_stats(struct stat *sp, char *what)
+{
+ const char *s = "";
+ char *w;
+
+ for (w = strtok(what, ","); w != NULL; w = strtok(NULL, ",")) {
+ printf("%s", s);
+ show_stat(sp, w);
+ s = ",";
+ }
+ printf("\n");
+}
+
+static unsigned int
+call_syscall(struct syscall_desc *scall, char *argv[])
+{
+ struct stat sb;
+ long long flags;
+ unsigned int i;
+ char *endp;
+ int rval;
+ union {
+ char *str;
+ long long num;
+ } args[MAX_ARGS];
+
+ /*
+ * Verify correctness of the arguments.
+ */
+ for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) {
+ if (scall->sd_args[i] == TYPE_NONE) {
+ if (argv[i] == NULL || strcmp(argv[i], ":") == 0)
+ break;
+ fprintf(stderr, "too many arguments [%s]\n", argv[i]);
+ exit(1);
+ } else {
+ if (argv[i] == NULL || strcmp(argv[i], ":") == 0) {
+ if (scall->sd_args[i] & TYPE_OPTIONAL)
+ break;
+ fprintf(stderr, "too few arguments\n");
+ exit(1);
+ }
+ if (scall->sd_args[i] & TYPE_STRING) {
+ if (strcmp(argv[i], "NULL") == 0)
+ args[i].str = NULL;
+ else if (strcmp(argv[i], "DEADCODE") == 0)
+ args[i].str = (void *)0xdeadc0de;
+ else
+ args[i].str = argv[i];
+ } else if (scall->sd_args[i] & TYPE_NUMBER) {
+ args[i].num = strtoll(argv[i], &endp, 0);
+ if (*endp != '\0' &&
+ !isspace((unsigned char)*endp)) {
+ fprintf(stderr, "invalid argument %u, "
+ "number expected [%s]\n", i, endp);
+ exit(1);
+ }
+ }
+ }
+ }
+ /*
+ * Call the given syscall.
+ */
+#define NUM(n) (args[(n)].num)
+#define STR(n) (args[(n)].str)
+ switch (scall->sd_action) {
+ case ACTION_OPEN:
+ flags = str2flags(open_flags, STR(1));
+ if (flags & O_CREAT) {
+ if (i == 2) {
+ fprintf(stderr, "too few arguments\n");
+ exit(1);
+ }
+ rval = open(STR(0), flags, (mode_t)NUM(2));
+ } else {
+ if (i == 3) {
+ fprintf(stderr, "too many arguments\n");
+ exit(1);
+ }
+ rval = open(STR(0), flags);
+ }
+ break;
+ case ACTION_CREATE:
+ rval = open(STR(0), O_CREAT | O_EXCL, NUM(1));
+ if (rval >= 0)
+ close(rval);
+ break;
+ case ACTION_UNLINK:
+ rval = unlink(STR(0));
+ break;
+ case ACTION_MKDIR:
+ rval = mkdir(STR(0), NUM(1));
+ break;
+ case ACTION_RMDIR:
+ rval = rmdir(STR(0));
+ break;
+ case ACTION_LINK:
+ rval = link(STR(0), STR(1));
+ break;
+ case ACTION_SYMLINK:
+ rval = symlink(STR(0), STR(1));
+ break;
+ case ACTION_RENAME:
+ rval = rename(STR(0), STR(1));
+ break;
+ case ACTION_MKFIFO:
+ rval = mkfifo(STR(0), NUM(1));
+ break;
+ case ACTION_CHMOD:
+ rval = chmod(STR(0), NUM(1));
+ break;
+ case ACTION_CHOWN:
+ rval = chown(STR(0), NUM(1), NUM(2));
+ break;
+ case ACTION_LCHOWN:
+ rval = lchown(STR(0), NUM(1), NUM(2));
+ break;
+ case ACTION_CHFLAGS:
+ rval = chflags(STR(0), str2flags(chflags_flags, STR(1)));
+ break;
+ case ACTION_TRUNCATE:
+ rval = truncate(STR(0), NUM(1));
+ break;
+ case ACTION_STAT:
+ rval = stat(STR(0), &sb);
+ if (rval == 0) {
+ show_stats(&sb, STR(1));
+ return (i);
+ }
+ break;
+ case ACTION_LSTAT:
+ rval = lstat(STR(0), &sb);
+ if (rval == 0) {
+ show_stats(&sb, STR(1));
+ return (i);
+ }
+ break;
+ default:
+ fprintf(stderr, "unsupported syscall\n");
+ exit(1);
+ }
+#undef STR
+#undef NUM
+ if (rval < 0) {
+ const char *serrno;
+
+ serrno = err2str(errno);
+ fprintf(stderr, "%s returned %d\n", scall->sd_name, rval);
+ printf("%s\n", serrno);
+ exit(1);
+ }
+ printf("0\n");
+ return (i);
+}
+
+static void
+set_gids(char *gids)
+{
+ gid_t *gidset;
+ long ngroups;
+ char *g, *endp;
+ unsigned i;
+
+ ngroups = sysconf(_SC_NGROUPS_MAX);
+ assert(ngroups > 0);
+ gidset = malloc(sizeof(*gidset) * ngroups);
+ assert(gidset != NULL);
+ for (i = 0, g = strtok(gids, ","); g != NULL;
+ g = strtok(NULL, ","), i++) {
+ if (i >= ngroups) {
+ fprintf(stderr, "too many gids\n");
+ exit(1);
+ }
+ gidset[i] = strtol(g, &endp, 0);
+ if (*endp != '\0' && !isspace((unsigned char)*endp)) {
+ fprintf(stderr, "invalid gid '%s' - number expected\n",
+ g);
+ exit(1);
+ }
+ }
+ if (setgroups(i, gidset) < 0) {
+ fprintf(stderr, "cannot change groups: %s\n", strerror(errno));
+ exit(1);
+ }
+ free(gidset);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct syscall_desc *scall;
+ unsigned int n;
+ char *gids, *endp;
+ int uid, umsk, ch;
+
+ uid = -1;
+ gids = NULL;
+ umsk = 0;
+
+ while ((ch = getopt(argc, argv, "g:u:U:")) != -1) {
+ switch(ch) {
+ case 'g':
+ gids = optarg;
+ break;
+ case 'u':
+ uid = (int)strtol(optarg, &endp, 0);
+ if (*endp != '\0' && !isspace((unsigned char)*endp)) {
+ fprintf(stderr, "invalid uid '%s' - number "
+ "expected\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'U':
+ umsk = (int)strtol(optarg, &endp, 0);
+ if (*endp != '\0' && !isspace((unsigned char)*endp)) {
+ fprintf(stderr, "invalid umask '%s' - number "
+ "expected\n", optarg);
+ exit(1);
+ }
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ fprintf(stderr, "too few arguments\n");
+ usage();
+ }
+
+ if (gids != NULL) {
+ fprintf(stderr, "changing groups to %s\n", gids);
+ set_gids(gids);
+ }
+ if (uid != -1) {
+ fprintf(stderr, "changing uid to %d\n", uid);
+ if (setuid(uid) < 0) {
+ fprintf(stderr, "cannot change uid: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ }
+
+ /* Change umask to requested value or to 0, if not requested. */
+ umask(umsk);
+
+ for (;;) {
+ scall = find_syscall(argv[0]);
+ if (scall == NULL) {
+ fprintf(stderr, "syscall '%s' not supported\n", argv[0]);
+ exit(1);
+ }
+ argc++;
+ argv++;
+ n = call_syscall(scall, argv);
+ argc += n;
+ argv += n;
+ if (argv[0] == NULL)
+ break;
+ argc++;
+ argv++;
+ }
+
+ exit(0);
+}
+
+static const char *
+err2str(int error)
+{
+ static char errnum[8];
+
+ switch (error) {
+ case EPERM:
+ return ("EPERM");
+ case ENOENT:
+ return ("ENOENT");
+ case ESRCH:
+ return ("ESRCH");
+ case EINTR:
+ return ("EINTR");
+ case EIO:
+ return ("EIO");
+ case ENXIO:
+ return ("ENXIO");
+ case E2BIG:
+ return ("E2BIG");
+ case ENOEXEC:
+ return ("ENOEXEC");
+ case EBADF:
+ return ("EBADF");
+ case ECHILD:
+ return ("ECHILD");
+ case EDEADLK:
+ return ("EDEADLK");
+ case ENOMEM:
+ return ("ENOMEM");
+ case EACCES:
+ return ("EACCES");
+ case EFAULT:
+ return ("EFAULT");
+ case ENOTBLK:
+ return ("ENOTBLK");
+ case EBUSY:
+ return ("EBUSY");
+ case EEXIST:
+ return ("EEXIST");
+ case EXDEV:
+ return ("EXDEV");
+ case ENODEV:
+ return ("ENODEV");
+ case ENOTDIR:
+ return ("ENOTDIR");
+ case EISDIR:
+ return ("EISDIR");
+ case EINVAL:
+ return ("EINVAL");
+ case ENFILE:
+ return ("ENFILE");
+ case EMFILE:
+ return ("EMFILE");
+ case ENOTTY:
+ return ("ENOTTY");
+ case ETXTBSY:
+ return ("ETXTBSY");
+ case EFBIG:
+ return ("EFBIG");
+ case ENOSPC:
+ return ("ENOSPC");
+ case ESPIPE:
+ return ("ESPIPE");
+ case EROFS:
+ return ("EROFS");
+ case EMLINK:
+ return ("EMLINK");
+ case EPIPE:
+ return ("EPIPE");
+ case EDOM:
+ return ("EDOM");
+ case ERANGE:
+ return ("ERANGE");
+ case EAGAIN:
+ return ("EAGAIN");
+ case EINPROGRESS:
+ return ("EINPROGRESS");
+ case EALREADY:
+ return ("EALREADY");
+ case ENOTSOCK:
+ return ("ENOTSOCK");
+ case EDESTADDRREQ:
+ return ("EDESTADDRREQ");
+ case EMSGSIZE:
+ return ("EMSGSIZE");
+ case EPROTOTYPE:
+ return ("EPROTOTYPE");
+ case ENOPROTOOPT:
+ return ("ENOPROTOOPT");
+ case EPROTONOSUPPORT:
+ return ("EPROTONOSUPPORT");
+ case ESOCKTNOSUPPORT:
+ return ("ESOCKTNOSUPPORT");
+ case EOPNOTSUPP:
+ return ("EOPNOTSUPP");
+ case EPFNOSUPPORT:
+ return ("EPFNOSUPPORT");
+ case EAFNOSUPPORT:
+ return ("EAFNOSUPPORT");
+ case EADDRINUSE:
+ return ("EADDRINUSE");
+ case EADDRNOTAVAIL:
+ return ("EADDRNOTAVAIL");
+ case ENETDOWN:
+ return ("ENETDOWN");
+ case ENETUNREACH:
+ return ("ENETUNREACH");
+ case ENETRESET:
+ return ("ENETRESET");
+ case ECONNABORTED:
+ return ("ECONNABORTED");
+ case ECONNRESET:
+ return ("ECONNRESET");
+ case ENOBUFS:
+ return ("ENOBUFS");
+ case EISCONN:
+ return ("EISCONN");
+ case ENOTCONN:
+ return ("ENOTCONN");
+ case ESHUTDOWN:
+ return ("ESHUTDOWN");
+ case ETOOMANYREFS:
+ return ("ETOOMANYREFS");
+ case ETIMEDOUT:
+ return ("ETIMEDOUT");
+ case ECONNREFUSED:
+ return ("ECONNREFUSED");
+ case ELOOP:
+ return ("ELOOP");
+ case ENAMETOOLONG:
+ return ("ENAMETOOLONG");
+ case EHOSTDOWN:
+ return ("EHOSTDOWN");
+ case EHOSTUNREACH:
+ return ("EHOSTUNREACH");
+ case ENOTEMPTY:
+ return ("ENOTEMPTY");
+ case EPROCLIM:
+ return ("EPROCLIM");
+ case EUSERS:
+ return ("EUSERS");
+ case EDQUOT:
+ return ("EDQUOT");
+ case ESTALE:
+ return ("ESTALE");
+ case EREMOTE:
+ return ("EREMOTE");
+ case EBADRPC:
+ return ("EBADRPC");
+ case ERPCMISMATCH:
+ return ("ERPCMISMATCH");
+ case EPROGUNAVAIL:
+ return ("EPROGUNAVAIL");
+ case EPROGMISMATCH:
+ return ("EPROGMISMATCH");
+ case EPROCUNAVAIL:
+ return ("EPROCUNAVAIL");
+ case ENOLCK:
+ return ("ENOLCK");
+ case ENOSYS:
+ return ("ENOSYS");
+ case EFTYPE:
+ return ("EFTYPE");
+ case EAUTH:
+ return ("EAUTH");
+ case ENEEDAUTH:
+ return ("ENEEDAUTH");
+ case EILSEQ:
+ return ("EILSEQ");
+ case ENOATTR:
+ return ("ENOATTR");
+ default:
+ snprintf(errnum, sizeof(errnum), "%d", error);
+ return (errnum);
+ }
+}
diff --git a/regress/sys/ffs/run b/regress/sys/ffs/run
new file mode 100644
index 00000000000..a1a967a5306
--- /dev/null
+++ b/regress/sys/ffs/run
@@ -0,0 +1,60 @@
+#!/bin/sh
+# $OpenBSD: run,v 1.1 2007/03/30 19:02:51 pedro Exp $
+# Heavily inspired on FreeBSD's misc.sh.
+
+totntest=0
+totnfail=0
+
+name253="_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12"
+name255="${name253}34"
+name256="${name255}5"
+path1021="${name255}/${name255}/${name255}/${name253}"
+path1023="${path1021}/x"
+path1024="${path1023}x"
+
+# Run a single test, calling fstest to do the job.
+expect()
+{
+ e="${1}"
+ shift
+ echo -n "Running test #${ntest}... "
+# echo ${FSTEST} $*
+ r=`${FSTEST} $* 2>/dev/null | tail -1`
+ echo "${r}" | egrep '^'${e}'$' >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ echo "okay."
+ else
+ nfail=`expr $nfail + 1`
+ echo "failed."
+ fi
+ ntest=`expr $ntest + 1`
+}
+
+test_check()
+{
+ echo -n "Running test #${ntest}... "
+ if [ $* ]; then
+ echo "okay."
+ else
+ nfail=`expr $nfail + 1`
+ echo "failed."
+ fi
+ ntest=`expr $ntest + 1`
+}
+
+# Generate a random file/directory name.
+namegen()
+{
+ echo "fstest_`dd if=/dev/urandom bs=1k count=1 2>/dev/null | openssl md5`"
+}
+
+for arg in $*; do
+ ntest=0
+ nfail=0
+ echo $arg:
+ . $arg
+ totntest=`expr $totntest + $ntest`
+ totnfail=`expr $totnfail + $nfail`
+done
+
+echo "${totntest} tests completed, ${totnfail} failed."
diff --git a/regress/sys/ffs/tests/chflags/00.t b/regress/sys/ffs/tests/chflags/00.t
new file mode 100644
index 00000000000..56110ebaa43
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/00.t
@@ -0,0 +1,171 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/00.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags changes flags"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n2} 0755
+cdir=`pwd`
+cd ${n2}
+
+expect 0 create ${n0} 0644
+expect none stat ${n0} flags
+expect 0 chflags ${n0} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n0} flags
+expect 0 chflags ${n0} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE stat ${n0} flags
+expect 0 chflags ${n0} SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n0} flags
+expect 0 chflags ${n0} none
+expect none stat ${n0} flags
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0644
+expect none stat ${n0} flags
+expect 0 chflags ${n0} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n0} flags
+expect 0 chflags ${n0} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE stat ${n0} flags
+expect 0 chflags ${n0} SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n0} flags
+expect 0 chflags ${n0} none
+expect none stat ${n0} flags
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect none stat ${n0} flags
+expect 0 chflags ${n0} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n0} flags
+expect 0 chflags ${n0} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE stat ${n0} flags
+expect 0 chflags ${n0} SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n0} flags
+expect 0 chflags ${n0} none
+expect none stat ${n0} flags
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 symlink ${n0} ${n1}
+expect none stat ${n1} flags
+expect none lstat ${n1} flags
+expect 0 chflags ${n1} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n1} flags
+expect none lstat ${n1} flags
+expect 0 chflags ${n1} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE stat ${n1} flags
+expect none lstat ${n1} flags
+expect 0 chflags ${n1} SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK stat ${n1} flags
+expect none lstat ${n1} flags
+expect 0 chflags ${n1} none
+expect none stat ${n1} flags
+expect none lstat ${n1} flags
+expect 0 unlink ${n1}
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 symlink ${n0} ${n1}
+expect none stat ${n1} flags
+expect none lstat ${n1} flags
+expect 0 lchflags ${n1} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE,SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK lstat ${n1} flags
+expect none stat ${n1} flags
+expect 0 lchflags ${n1} UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE
+expect UF_NODUMP,UF_IMMUTABLE,UF_APPEND,UF_NOUNLINK,UF_OPAQUE lstat ${n1} flags
+expect none stat ${n1} flags
+expect 0 lchflags ${n1} SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK
+expect SF_ARCHIVED,SF_IMMUTABLE,SF_APPEND,SF_NOUNLINK lstat ${n1} flags
+expect none stat ${n1} flags
+expect 0 lchflags ${n1} none
+expect none lstat ${n1} flags
+expect none stat ${n1} flags
+expect 0 unlink ${n1}
+expect 0 unlink ${n0}
+
+# successful chflags(2) updates ctime.
+expect 0 create ${n0} 0644
+for flag in UF_NODUMP UF_IMMUTABLE UF_APPEND UF_NOUNLINK UF_OPAQUE SF_ARCHIVED SF_IMMUTABLE SF_APPEND SF_NOUNLINK none; do
+ ctime1=`${FSTEST} stat ${n0} ctime`
+ sleep 1
+ expect 0 chflags ${n0} ${flag}
+ ctime2=`${FSTEST} stat ${n0} ctime`
+ test_check $ctime1 -lt $ctime2
+done
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+for flag in UF_NODUMP UF_IMMUTABLE UF_APPEND UF_NOUNLINK UF_OPAQUE SF_ARCHIVED SF_IMMUTABLE SF_APPEND SF_NOUNLINK none; do
+ ctime1=`${FSTEST} stat ${n0} ctime`
+ sleep 1
+ expect 0 chflags ${n0} ${flag}
+ ctime2=`${FSTEST} stat ${n0} ctime`
+ test_check $ctime1 -lt $ctime2
+done
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+for flag in UF_NODUMP UF_IMMUTABLE UF_APPEND UF_NOUNLINK UF_OPAQUE SF_ARCHIVED SF_IMMUTABLE SF_APPEND SF_NOUNLINK none; do
+ ctime1=`${FSTEST} stat ${n0} ctime`
+ sleep 1
+ expect 0 chflags ${n0} ${flag}
+ ctime2=`${FSTEST} stat ${n0} ctime`
+ test_check $ctime1 -lt $ctime2
+done
+expect 0 unlink ${n0}
+
+expect 0 symlink ${n1} ${n0}
+for flag in UF_NODUMP UF_IMMUTABLE UF_APPEND UF_NOUNLINK UF_OPAQUE SF_ARCHIVED SF_IMMUTABLE SF_APPEND SF_NOUNLINK none; do
+ ctime1=`${FSTEST} lstat ${n0} ctime`
+ sleep 1
+ expect 0 lchflags ${n0} ${flag}
+ ctime2=`${FSTEST} lstat ${n0} ctime`
+ test_check $ctime1 -lt $ctime2
+done
+expect 0 unlink ${n0}
+
+# unsuccessful chflags(2) does not update ctime.
+expect 0 create ${n0} 0644
+for flag in UF_IMMUTABLE SF_IMMUTABLE none; do
+ ctime1=`${FSTEST} stat ${n0} ctime`
+ sleep 1
+ expect EPERM -u 65534 chflags ${n0} ${flag}
+ ctime2=`${FSTEST} stat ${n0} ctime`
+ test_check $ctime1 -eq $ctime2
+done
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+for flag in UF_IMMUTABLE SF_IMMUTABLE none; do
+ ctime1=`${FSTEST} stat ${n0} ctime`
+ sleep 1
+ expect EPERM -u 65534 chflags ${n0} ${flag}
+ ctime2=`${FSTEST} stat ${n0} ctime`
+ test_check $ctime1 -eq $ctime2
+done
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+for flag in UF_IMMUTABLE SF_IMMUTABLE none; do
+ ctime1=`${FSTEST} stat ${n0} ctime`
+ sleep 1
+ expect EPERM -u 65534 chflags ${n0} ${flag}
+ ctime2=`${FSTEST} stat ${n0} ctime`
+ test_check $ctime1 -eq $ctime2
+done
+expect 0 unlink ${n0}
+
+expect 0 symlink ${n1} ${n0}
+for flag in UF_IMMUTABLE SF_IMMUTABLE none; do
+ ctime1=`${FSTEST} lstat ${n0} ctime`
+ sleep 1
+ expect EPERM -u 65534 lchflags ${n0} ${flag}
+ ctime2=`${FSTEST} lstat ${n0} ctime`
+ test_check $ctime1 -eq $ctime2
+done
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n2}
diff --git a/regress/sys/ffs/tests/chflags/01.t b/regress/sys/ffs/tests/chflags/01.t
new file mode 100644
index 00000000000..70cc6e6e748
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/01.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR chflags ${n0}/${n1}/test UF_IMMUTABLE
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/02.t b/regress/sys/ffs/tests/chflags/02.t
new file mode 100644
index 00000000000..5b569756ad8
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/02.t
@@ -0,0 +1,11 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/02.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 create ${name255} 0644
+expect 0 chflags ${name255} UF_IMMUTABLE
+expect UF_IMMUTABLE stat ${name255} flags
+expect 0 chflags ${name255} none
+expect 0 unlink ${name255}
+expect ENAMETOOLONG chflags ${name256} UF_IMMUTABLE
diff --git a/regress/sys/ffs/tests/chflags/03.t b/regress/sys/ffs/tests/chflags/03.t
new file mode 100644
index 00000000000..7fcbd698651
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/03.t
@@ -0,0 +1,18 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/03.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 create ${path1023} 0644
+expect 0 chflags ${path1023} UF_IMMUTABLE
+expect 0 chflags ${path1023} none
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG chflags ${path1024} UF_IMMUTABLE
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/chflags/04.t b/regress/sys/ffs/tests/chflags/04.t
new file mode 100644
index 00000000000..6a980157372
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/04.t
@@ -0,0 +1,7 @@
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT chflags ${n0}/${n1}/test UF_IMMUTABLE
+expect ENOENT chflags ${n0}/${n1} UF_IMMUTABLE
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/05.t b/regress/sys/ffs/tests/chflags/05.t
new file mode 100644
index 00000000000..96f7c9c81f7
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/05.t
@@ -0,0 +1,28 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/05.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 chflags ${n1}/${n2} UF_IMMUTABLE
+expect UF_IMMUTABLE -u 65534 -g 65534 stat ${n1}/${n2} flags
+expect 0 -u 65534 -g 65534 chflags ${n1}/${n2} none
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 chflags ${n1}/${n2} UF_IMMUTABLE
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 chflags ${n1}/${n2} UF_IMMUTABLE
+expect UF_IMMUTABLE -u 65534 -g 65534 stat ${n1}/${n2} flags
+expect 0 -u 65534 -g 65534 chflags ${n1}/${n2} none
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/06.t b/regress/sys/ffs/tests/chflags/06.t
new file mode 100644
index 00000000000..7b6ad814881
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/06.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/06.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP chflags ${n0}/test UF_IMMUTABLE
+expect ELOOP chflags ${n1}/test UF_IMMUTABLE
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/chflags/07.t b/regress/sys/ffs/tests/chflags/07.t
new file mode 100644
index 00000000000..a86eea32c1b
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/07.t
@@ -0,0 +1,47 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/07.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EPERM when the effective user ID does not match the owner of the file and the effective user ID is not the super-user"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 create ${n1} 0644
+expect EPERM -u 65534 -g 65534 chflags ${n1} UF_IMMUTABLE
+expect none stat ${n1} flags
+expect 0 chown ${n1} 65534 65534
+expect EPERM -u 65533 -g 65533 chflags ${n1} UF_IMMUTABLE
+expect none stat ${n1} flags
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+expect EPERM -u 65534 -g 65534 chflags ${n1} UF_IMMUTABLE
+expect none stat ${n1} flags
+expect 0 chown ${n1} 65534 65534
+expect EPERM -u 65533 -g 65533 chflags ${n1} UF_IMMUTABLE
+expect none stat ${n1} flags
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect EPERM -u 65534 -g 65534 chflags ${n1} UF_IMMUTABLE
+expect none stat ${n1} flags
+expect 0 chown ${n1} 65534 65534
+expect EPERM -u 65533 -g 65533 chflags ${n1} UF_IMMUTABLE
+expect none stat ${n1} flags
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n1}
+expect EPERM -u 65534 -g 65534 lchflags ${n1} UF_IMMUTABLE
+expect none lstat ${n1} flags
+expect 0 lchown ${n1} 65534 65534
+expect EPERM -u 65533 -g 65533 lchflags ${n1} UF_IMMUTABLE
+expect none lstat ${n1} flags
+expect 0 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/08.t b/regress/sys/ffs/tests/chflags/08.t
new file mode 100644
index 00000000000..d135dc621fb
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/08.t
@@ -0,0 +1,63 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/08.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EPERM when one of SF_IMMUTABLE, SF_APPEND, or SF_NOUNLINK is set and the user is not the super-user"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 create ${n1} 0644
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 chflags ${n1} ${flag}
+ expect EPERM -u 65533 -g 65533 chflags ${n1} UF_IMMUTABLE
+ expect ${flag} stat ${n1} flags
+ expect EPERM -u 65534 -g 65534 chflags ${n1} UF_IMMUTABLE
+ expect ${flag} stat ${n1} flags
+done
+expect 0 chflags ${n1} none
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 chflags ${n1} ${flag}
+ expect EPERM -u 65533 -g 65533 chflags ${n1} UF_IMMUTABLE
+ expect ${flag} stat ${n1} flags
+ expect EPERM -u 65534 -g 65534 chflags ${n1} UF_IMMUTABLE
+ expect ${flag} stat ${n1} flags
+done
+expect 0 chflags ${n1} none
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 chflags ${n1} ${flag}
+ expect EPERM -u 65533 -g 65533 chflags ${n1} UF_IMMUTABLE
+ expect ${flag} stat ${n1} flags
+ expect EPERM -u 65534 -g 65534 chflags ${n1} UF_IMMUTABLE
+ expect ${flag} stat ${n1} flags
+done
+expect 0 chflags ${n1} none
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n1}
+expect 0 lchown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 lchflags ${n1} ${flag}
+ expect EPERM -u 65533 -g 65533 lchflags ${n1} UF_IMMUTABLE
+ expect ${flag} lstat ${n1} flags
+ expect EPERM -u 65534 -g 65534 lchflags ${n1} UF_IMMUTABLE
+ expect ${flag} lstat ${n1} flags
+done
+expect 0 lchflags ${n1} none
+expect 0 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/09.t b/regress/sys/ffs/tests/chflags/09.t
new file mode 100644
index 00000000000..57560e7ebce
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/09.t
@@ -0,0 +1,51 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/09.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EPERM when one of SF_IMMUTABLE, SF_APPEND, or SF_NOUNLINK is set and securelevel is greater than 0"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 create ${n1} 0644
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 chflags ${n1} ${flag}
+ expect ${flag} stat ${n1} flags
+done
+expect 0 chflags ${n1} none
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 chflags ${n1} ${flag}
+ expect ${flag} stat ${n1} flags
+done
+expect 0 chflags ${n1} none
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 chflags ${n1} ${flag}
+ expect ${flag} stat ${n1} flags
+done
+expect 0 chflags ${n1} none
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n1}
+expect 0 lchown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect 0 lchflags ${n1} ${flag}
+ expect ${flag} lstat ${n1} flags
+done
+expect 0 lchflags ${n1} none
+expect 0 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/10.t b/regress/sys/ffs/tests/chflags/10.t
new file mode 100644
index 00000000000..6094ead7c47
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/10.t
@@ -0,0 +1,55 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/10.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EPERM if non-super-user tries to set one of SF_IMMUTABLE, SF_APPEND, or SF_NOUNLINK"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 create ${n1} 0644
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect EPERM -u 65533 -g 65533 chflags ${n1} ${flag}
+ expect none stat ${n1} flags
+ expect EPERM -u 65534 -g 65534 chflags ${n1} ${flag}
+ expect none stat ${n1} flags
+done
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect EPERM -u 65533 -g 65533 chflags ${n1} ${flag}
+ expect none stat ${n1} flags
+ expect EPERM -u 65534 -g 65534 chflags ${n1} ${flag}
+ expect none stat ${n1} flags
+done
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect 0 chown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect EPERM -u 65533 -g 65533 chflags ${n1} ${flag}
+ expect none stat ${n1} flags
+ expect EPERM -u 65534 -g 65534 chflags ${n1} ${flag}
+ expect none stat ${n1} flags
+done
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n1}
+expect 0 lchown ${n1} 65534 65534
+for flag in SF_IMMUTABLE SF_APPEND SF_NOUNLINK; do
+ expect EPERM -u 65533 -g 65533 lchflags ${n1} ${flag}
+ expect none lstat ${n1} flags
+ expect EPERM -u 65534 -g 65534 lchflags ${n1} ${flag}
+ expect none lstat ${n1} flags
+done
+expect 0 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/11.t b/regress/sys/ffs/tests/chflags/11.t
new file mode 100644
index 00000000000..10b38f0ff9e
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/11.t
@@ -0,0 +1,63 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/11.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EPERM if a user tries to set or remove the SF_SNAPSHOT flag"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 create ${n1} 0644
+expect EPERM -u 65534 -g 65534 chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect EPERM chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect 0 chown ${n1} 65534 65534
+expect EPERM -u 65534 -g 65534 chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect EPERM chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0644
+expect EPERM -u 65534 -g 65534 chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect EPERM chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect 0 chown ${n1} 65534 65534
+expect EPERM -u 65534 -g 65534 chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect EPERM chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect EPERM -u 65534 -g 65534 chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect EPERM chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect 0 chown ${n1} 65534 65534
+expect EPERM -u 65534 -g 65534 chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect EPERM chflags ${n1} SF_SNAPSHOT
+expect none stat ${n1} flags
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n1}
+expect EPERM -u 65534 -g 65534 lchflags ${n1} SF_SNAPSHOT
+expect none lstat ${n1} flags
+expect EPERM lchflags ${n1} SF_SNAPSHOT
+expect none lstat ${n1} flags
+expect 0 lchown ${n1} 65534 65534
+expect EPERM -u 65534 -g 65534 lchflags ${n1} SF_SNAPSHOT
+expect none lstat ${n1} flags
+expect EPERM lchflags ${n1} SF_SNAPSHOT
+expect none lstat ${n1} flags
+expect 0 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/12.t b/regress/sys/ffs/tests/chflags/12.t
new file mode 100644
index 00000000000..2316514aa5b
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/12.t
@@ -0,0 +1,31 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/12.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+expect 0 chflags ${n0}/${n1} UF_IMMUTABLE
+expect UF_IMMUTABLE stat ${n0}/${n1} flags
+expect 0 chflags ${n0}/${n1} none
+expect none stat ${n0}/${n1} flags
+mount -ur /dev/svnd1c
+expect EROFS chflags ${n0}/${n1} UF_IMMUTABLE
+expect none stat ${n0}/${n1} flags
+mount -uw /dev/svnd1c
+expect 0 chflags ${n0}/${n1} UF_IMMUTABLE
+expect UF_IMMUTABLE stat ${n0}/${n1} flags
+expect 0 chflags ${n0}/${n1} none
+expect none stat ${n0}/${n1} flags
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chflags/13.t b/regress/sys/ffs/tests/chflags/13.t
new file mode 100644
index 00000000000..f476b3249c9
--- /dev/null
+++ b/regress/sys/ffs/tests/chflags/13.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chflags/13.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chflags returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT chflags NULL UF_IMMUTABLE
+expect EFAULT chflags DEADCODE UF_IMMUTABLE
diff --git a/regress/sys/ffs/tests/chmod/00.t b/regress/sys/ffs/tests/chmod/00.t
new file mode 100644
index 00000000000..43b24f5d995
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/00.t
@@ -0,0 +1,119 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/00.t,v 1.2 2007/01/25 20:48:14 pjd Exp $
+
+desc="chmod changes permission"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n2} 0755
+cdir=`pwd`
+cd ${n2}
+
+expect 0 create ${n0} 0644
+expect 0644 stat ${n0} mode
+expect 0 chmod ${n0} 0111
+expect 0111 stat ${n0} mode
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0755 stat ${n0} mode
+expect 0 chmod ${n0} 0753
+expect 0753 stat ${n0} mode
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect 0644 stat ${n0} mode
+expect 0 chmod ${n0} 0310
+expect 0310 stat ${n0} mode
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 symlink ${n0} ${n1}
+expect 0644 stat ${n1} mode
+expect 0 chmod ${n1} 0321
+expect 0321 stat ${n1} mode
+expect 0321 lstat ${n0} mode
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
+
+# successful chmod(2) updates ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chmod ${n0} 0111
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chmod ${n0} 0753
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chmod ${n0} 0310
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+
+# unsuccessful chmod(2) does not update ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EPERM -u 65534 chmod ${n0} 0111
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EPERM -u 65534 chmod ${n0} 0753
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EPERM -u 65534 chmod ${n0} 0310
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+# POSIX: If the calling process does not have appropriate privileges, and if
+# the group ID of the file does not match the effective group ID or one of the
+# supplementary group IDs and if the file is a regular file, bit S_ISGID
+# (set-group-ID on execution) in the file's mode shall be cleared upon
+# successful return from chmod().
+
+expect 0 create ${n0} 0755
+expect 0 chown ${n0} 65535 65535
+expect 0 -u 65535 -g 65535 chmod ${n0} 02755
+expect 02755 stat ${n0} mode
+expect 0 -u 65535 -g 65535 chmod ${n0} 0755
+expect 0755 stat ${n0} mode
+
+# XXX
+# Unfortunately FreeBSD doesn't clear set-gid bit, but returns EPERM instead.
+#case "${os}" in
+#FreeBSD)
+ expect EPERM -u 65535 -g 65534 chmod ${n0} 02755
+ expect 0755 stat ${n0} mode
+# ;;
+#*)
+# expect 0 -u 65535 -g 65534 chmod ${n0} 02755
+# expect 0755 stat ${n0} mode
+# ;;
+#esac
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n2}
diff --git a/regress/sys/ffs/tests/chmod/01.t b/regress/sys/ffs/tests/chmod/01.t
new file mode 100644
index 00000000000..623f2300546
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/01.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR chmod ${n0}/${n1}/test 0644
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chmod/02.t b/regress/sys/ffs/tests/chmod/02.t
new file mode 100644
index 00000000000..52848e0ab77
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/02.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/02.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 create ${name255} 0644
+expect 0 chmod ${name255} 0620
+expect 0620 stat ${name255} mode
+expect 0 unlink ${name255}
+expect ENAMETOOLONG chmod ${name256} 0620
diff --git a/regress/sys/ffs/tests/chmod/03.t b/regress/sys/ffs/tests/chmod/03.t
new file mode 100644
index 00000000000..5460195078c
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/03.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/03.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 create ${path1023} 0644
+expect 0 chmod ${path1023} 0642
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG chmod ${path1024} 0642
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/chmod/04.t b/regress/sys/ffs/tests/chmod/04.t
new file mode 100644
index 00000000000..e38365c7426
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/04.t
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/04.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns ENOENT if the named file does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT chmod ${n0}/${n1}/test 0644
+expect ENOENT chmod ${n0}/${n1} 0644
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chmod/05.t b/regress/sys/ffs/tests/chmod/05.t
new file mode 100644
index 00000000000..fbe16b937cd
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/05.t
@@ -0,0 +1,26 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/05.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 chmod ${n1}/${n2} 0642
+expect 0642 -u 65534 -g 65534 stat ${n1}/${n2} mode
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 chmod ${n1}/${n2} 0620
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 chmod ${n1}/${n2} 0420
+expect 0420 -u 65534 -g 65534 stat ${n1}/${n2} mode
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chmod/06.t b/regress/sys/ffs/tests/chmod/06.t
new file mode 100644
index 00000000000..d60475c5b74
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/06.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/06.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP chmod ${n0}/test 0644
+expect ELOOP chmod ${n1}/test 0644
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/chmod/07.t b/regress/sys/ffs/tests/chmod/07.t
new file mode 100644
index 00000000000..e16257d0b09
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/07.t
@@ -0,0 +1,26 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/07.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns EPERM if the operation would change the ownership, but the effective user ID is not the super-user"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 chmod ${n1}/${n2} 0642
+expect 0642 stat ${n1}/${n2} mode
+expect EPERM -u 65533 -g 65533 chmod ${n1}/${n2} 0641
+expect 0642 stat ${n1}/${n2} mode
+expect 0 chown ${n1}/${n2} 0 0
+expect EPERM -u 65534 -g 65534 chmod ${n1}/${n2} 0641
+expect 0642 stat ${n1}/${n2} mode
+expect 0 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chmod/08.t b/regress/sys/ffs/tests/chmod/08.t
new file mode 100644
index 00000000000..3008b79efa8
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/08.t
@@ -0,0 +1,52 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/08.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns EPERM if the named file has its immutable or append-only flag set"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM chmod ${n0} 0600
+expect 0644 stat ${n0} mode
+expect 0 chflags ${n0} none
+expect 0 chmod ${n0} 0600
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM chmod ${n0} 0600
+expect 0644 stat ${n0} mode
+expect 0 chflags ${n0} none
+expect 0 chmod ${n0} 0600
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM chmod ${n0} 0600
+expect 0644 stat ${n0} mode
+expect 0 chflags ${n0} none
+expect 0 chmod ${n0} 0600
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM chmod ${n0} 0600
+expect 0644 stat ${n0} mode
+expect 0 chflags ${n0} none
+expect 0 chmod ${n0} 0600
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 chmod ${n0} 0600
+expect 0600 stat ${n0} mode
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 chmod ${n0} 0600
+expect 0600 stat ${n0} mode
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/chmod/09.t b/regress/sys/ffs/tests/chmod/09.t
new file mode 100644
index 00000000000..326e105771a
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/09.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/09.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+expect 0 chmod ${n0}/${n1} 0640
+expect 0640 stat ${n0}/${n1} mode
+mount -ur /dev/svnd1c
+expect EROFS chmod ${n0}/${n1} 0600
+expect 0640 stat ${n0}/${n1} mode
+mount -uw /dev/svnd1c
+expect 0 chmod ${n0}/${n1} 0600
+expect 0600 stat ${n0}/${n1} mode
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chmod/10.t b/regress/sys/ffs/tests/chmod/10.t
new file mode 100644
index 00000000000..b7d3d19a708
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/10.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/10.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT chmod NULL 0644
+expect EFAULT chmod DEADCODE 0644
diff --git a/regress/sys/ffs/tests/chmod/11.t b/regress/sys/ffs/tests/chmod/11.t
new file mode 100644
index 00000000000..f90f357f2b2
--- /dev/null
+++ b/regress/sys/ffs/tests/chmod/11.t
@@ -0,0 +1,36 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chmod/11.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chmod returns EFTYPE if the effective user ID is not the super-user, the mode includes the sticky bit (S_ISVTX), and path does not refer to a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chmod ${n1} 01755
+expect 01755 stat ${n1} mode
+expect 0 rmdir ${n1}
+
+expect 0 create ${n1} 0644
+expect 0 chmod ${n1} 01644
+expect 01644 stat ${n1} mode
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 chmod ${n1} 01755
+expect 01755 stat ${n1} mode
+expect 0 rmdir ${n1}
+
+expect 0 create ${n1} 0644
+expect 0 chown ${n1} 65534 65534
+expect EFTYPE -u 65534 -g 65534 chmod ${n1} 01644
+expect 0644 stat ${n1} mode
+expect 0 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chown/00.t b/regress/sys/ffs/tests/chown/00.t
new file mode 100644
index 00000000000..ed0874d3fe6
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/00.t
@@ -0,0 +1,277 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/00.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown changes ownership"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n2} 0755
+cdir=`pwd`
+cd ${n2}
+
+# super-user can always modify ownership
+# 2
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 123 456
+expect 123,456 lstat ${n0} uid,gid
+expect 0 chown ${n0} 0 0
+expect 0,0 lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+# 8
+expect 0 mkfifo ${n0} 0644
+expect 0 chown ${n0} 123 456
+expect 123,456 lstat ${n0} uid,gid
+expect 0 chown ${n0} 0 0
+expect 0,0 lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+# 14
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 123 456
+expect 123,456 lstat ${n0} uid,gid
+expect 0 chown ${n0} 0 0
+expect 0,0 lstat ${n0} uid,gid
+expect 0 rmdir ${n0}
+# 20
+expect 0 create ${n0} 0644
+expect 0 symlink ${n0} ${n1}
+expect 0 chown ${n1} 123 456
+expect 123,456 stat ${n1} uid,gid
+expect 123,456 stat ${n0} uid,gid
+expect 0 lchown ${n1} 135 579
+expect 135,579 lstat ${n1} uid,gid
+expect 123,456 stat ${n1} uid,gid
+expect 123,456 stat ${n0} uid,gid
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
+
+# non-super-user can modify file group if he is owner of a file and
+# gid he is setting is in his groups list.
+# 31
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 65534 65533
+expect 65534,65533 lstat ${n0} uid,gid
+expect 0 -u 65534 -g 65532,65531 chown ${n0} -1 65532
+expect 65534,65532 lstat ${n0} uid,gid
+expect 0 -u 65534 -g 65532,65531 chown ${n0} 65534 65531
+expect 65534,65531 lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+
+# chown(2) return 0 if user is not owner of a file, but chown(2) is called
+# with both uid and gid equal to -1.
+# 39
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 65534 65533
+expect 0 -u 65532 -g 65531 chown ${n0} -1 -1
+expect 0 unlink ${n0}
+
+# when super-user calls chown(2), set-uid and set-gid bits are not removed.
+# 43
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 65534 65533
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 chown ${n0} 65532 65531
+expect 06555 lstat ${n0} mode
+expect 0 unlink ${n0}
+# 50
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 0 0
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 chown ${n0} 65534 65533
+expect 06555 lstat ${n0} mode
+expect 0 unlink ${n0}
+# 57
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 65534 65533
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 chown ${n0} 0 0
+expect 06555 lstat ${n0} mode
+expect 0 unlink ${n0}
+
+# when non-super-user calls chown(2) successfully, set-uid and set-gid bits are
+# removed, except when both uid and gid are equal to -1.
+# 64
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 65534 65533
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 -u 65534 -g 65533,65532 chown ${n0} 65534 65532
+expect 0555,65534,65532 lstat ${n0} mode,uid,gid
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 65533
+expect 0555,65534,65533 lstat ${n0} mode,uid,gid
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 -1
+expect 06555,65534,65533 lstat ${n0} mode,uid,gid
+expect 0 unlink ${n0}
+# 79
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65533
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 -u 65534 -g 65533,65532 chown ${n0} 65534 65532
+expect 0555,65534,65532 lstat ${n0} mode,uid,gid
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 65533
+expect 0555,65534,65533 lstat ${n0} mode,uid,gid
+expect 0 chmod ${n0} 06555
+expect 06555 lstat ${n0} mode
+expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 -1
+expect 06555,65534,65533 lstat ${n0} mode,uid,gid
+expect 0 rmdir ${n0}
+
+# successfull chown(2) call (except uid and gid equal to -1) updates ctime.
+# 109
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chown ${n0} 65534 65533
+expect 65534,65533 lstat ${n0} uid,gid
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+# 114
+expect 0 mkdir ${n0} 0755
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chown ${n0} 65534 65533
+expect 65534,65533 lstat ${n0} uid,gid
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 rmdir ${n0}
+# 119
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chown ${n0} 65534 65533
+expect 65534,65533 lstat ${n0} uid,gid
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+# 124
+expect 0 symlink ${n1} ${n0}
+ctime1=`${FSTEST} lstat ${n0} ctime`
+sleep 1
+expect 0 lchown ${n0} 65534 65533
+expect 65534,65533 lstat ${n0} uid,gid
+ctime2=`${FSTEST} lstat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+# 129
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 65534 65533
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 -u 65534 -g 65532 chown ${n0} 65534 65532
+expect 65534,65532 lstat ${n0} uid,gid
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+# 135
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65533
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 -u 65534 -g 65532 chown ${n0} 65534 65532
+expect 65534,65532 lstat ${n0} uid,gid
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 rmdir ${n0}
+# 141
+expect 0 mkfifo ${n0} 0644
+expect 0 chown ${n0} 65534 65533
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chown ${n0} 65534 65533
+expect 0 -u 65534 -g 65532 chown ${n0} 65534 65532
+expect 65534,65532 lstat ${n0} uid,gid
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+# 148
+expect 0 symlink ${n1} ${n0}
+expect 0 lchown ${n0} 65534 65533
+ctime1=`${FSTEST} lstat ${n0} ctime`
+sleep 1
+expect 0 -u 65534 -g 65532 lchown ${n0} 65534 65532
+expect 65534,65532 lstat ${n0} uid,gid
+ctime2=`${FSTEST} lstat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+# 154
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chown ${n0} -1 -1
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+# 158
+expect 0 mkdir ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chown ${n0} -1 -1
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 rmdir ${n0}
+# 162
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 chown ${n0} -1 -1
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+# 166
+expect 0 symlink ${n1} ${n0}
+ctime1=`${FSTEST} lstat ${n0} ctime`
+sleep 1
+expect 0 lchown ${n0} -1 -1
+ctime2=`${FSTEST} lstat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+# unsuccessful chown(2) does not update ctime.
+# 170
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EPERM -u 65534 chown ${n0} 65534 -1
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+# 174
+expect 0 mkdir ${n0} 0755
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EPERM -u 65534 -g 65534 chown ${n0} -1 65534
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 rmdir ${n0}
+# 178
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EPERM -u 65534 -g 65534 chown ${n0} 65534 65534
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+# 182
+expect 0 symlink ${n1} ${n0}
+ctime1=`${FSTEST} lstat ${n0} ctime`
+sleep 1
+expect EPERM -u 65534 -g 65534 lchown ${n0} 65534 65534
+ctime2=`${FSTEST} lstat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+# 186
+cd ${cdir}
+expect 0 rmdir ${n2}
diff --git a/regress/sys/ffs/tests/chown/01.t b/regress/sys/ffs/tests/chown/01.t
new file mode 100644
index 00000000000..8bb1c5aec67
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/01.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR chown ${n0}/${n1}/test 65534 65534
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chown/02.t b/regress/sys/ffs/tests/chown/02.t
new file mode 100644
index 00000000000..34ea2068882
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/02.t
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/02.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+expect 0 create ${name255} 0644
+expect 0 chown ${name255} 65534 65534
+expect 65534,65534 stat ${name255} uid,gid
+expect 0 unlink ${name255}
+expect ENAMETOOLONG chown ${name256} 65533 65533
diff --git a/regress/sys/ffs/tests/chown/03.t b/regress/sys/ffs/tests/chown/03.t
new file mode 100644
index 00000000000..61ce2336f38
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/03.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/03.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 create ${path1023} 0644
+expect 0 chown ${path1023} 65534 65534
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG chown ${path1024} 65533 65533
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/chown/04.t b/regress/sys/ffs/tests/chown/04.t
new file mode 100644
index 00000000000..5cdf3798629
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/04.t
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/04.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns ENOENT if the named file does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT chown ${n0}/${n1}/test 65534 65534
+expect ENOENT chown ${n0}/${n1} 65534 65534
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chown/05.t b/regress/sys/ffs/tests/chown/05.t
new file mode 100644
index 00000000000..d469f45b1a8
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/05.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/05.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65533,65534 chown ${n1}/${n2} -1 65533
+expect 65534,65533 -u 65534 -g 65534 stat ${n1}/${n2} uid,gid
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65533,65534 chown ${n1}/${n2} -1 65534
+expect 0 chmod ${n1} 0755
+expect 65534,65533 -u 65534 -g 65534 stat ${n1}/${n2} uid,gid
+expect 0 -u 65534 -g 65533,65534 chown ${n1}/${n2} -1 65534
+expect 65534,65534 -u 65534 -g 65534 stat ${n1}/${n2} uid,gid
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chown/06.t b/regress/sys/ffs/tests/chown/06.t
new file mode 100644
index 00000000000..88999d8f040
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/06.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/06.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP chown ${n0}/test 65534 65534
+expect ELOOP chown ${n1}/test 65534 65534
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/chown/07.t b/regress/sys/ffs/tests/chown/07.t
new file mode 100644
index 00000000000..0aed7c2ed23
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/07.t
@@ -0,0 +1,23 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/07.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns EPERM if the operation would change the ownership, but the effective user ID is not the super-user and the process is not an owner of the file"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect EPERM -u 65534 -g 65534 chown ${n1}/${n2} 65533 65533
+expect EPERM -u 65533 -g 65533 chown ${n1}/${n2} 65534 65534
+expect EPERM -u 65533 -g 65533 chown ${n1}/${n2} 65533 65533
+expect EPERM -u 65534 -g 65534 chown ${n1}/${n2} -1 65533
+expect 0 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chown/08.t b/regress/sys/ffs/tests/chown/08.t
new file mode 100644
index 00000000000..da83e6ac58c
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/08.t
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/08.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns EPERM if the named file has its immutable or append-only flag set"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM chown ${n0} 65534 65534
+expect 0 chflags ${n0} none
+expect 0 chown ${n0} 65534 65534
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM chown ${n0} 65534 65534
+expect 0 chflags ${n0} none
+expect 0 chown ${n0} 65534 65534
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM chown ${n0} 65534 65534
+expect 0 chflags ${n0} none
+expect 0 chown ${n0} 65534 65534
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM chown ${n0} 65534 65534
+expect 0 chflags ${n0} none
+expect 0 chown ${n0} 65534 65534
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 chown ${n0} 65534 65534
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 chown ${n0} 65534 65534
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/chown/09.t b/regress/sys/ffs/tests/chown/09.t
new file mode 100644
index 00000000000..90f5350dfaa
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/09.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/09.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+expect 0 chown ${n0}/${n1} 65534 65534
+expect 65534,65534 stat ${n0}/${n1} uid,gid
+mount -ur /dev/svnd1c
+expect EROFS chown ${n0}/${n1} 65533 65533
+expect 65534,65534 stat ${n0}/${n1} uid,gid
+mount -uw /dev/svnd1c
+expect 0 chown ${n0}/${n1} 65533 65533
+expect 65533,65533 stat ${n0}/${n1} uid,gid
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/chown/10.t b/regress/sys/ffs/tests/chown/10.t
new file mode 100644
index 00000000000..bc429f222ab
--- /dev/null
+++ b/regress/sys/ffs/tests/chown/10.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/chown/10.t,v 1.1 2007/01/17 01:42:08 pjd Exp $
+
+desc="chown returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT chown NULL 65534 65534
+expect EFAULT chown DEADCODE 65534 65534
diff --git a/regress/sys/ffs/tests/link/00.t b/regress/sys/ffs/tests/link/00.t
new file mode 100644
index 00000000000..85c572f5548
--- /dev/null
+++ b/regress/sys/ffs/tests/link/00.t
@@ -0,0 +1,146 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/00.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link creates hardlinks"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+
+expect 0 mkdir ${n3} 0755
+cdir=`pwd`
+cd ${n3}
+
+expect 0 create ${n0} 0644
+expect regular,0644,1 lstat ${n0} type,mode,nlink
+
+expect 0 link ${n0} ${n1}
+expect regular,0644,2 lstat ${n0} type,mode,nlink
+expect regular,0644,2 lstat ${n1} type,mode,nlink
+
+expect 0 link ${n1} ${n2}
+expect regular,0644,3 lstat ${n0} type,mode,nlink
+expect regular,0644,3 lstat ${n1} type,mode,nlink
+expect regular,0644,3 lstat ${n2} type,mode,nlink
+
+expect 0 chmod ${n1} 0201
+expect 0 chown ${n1} 65534 65533
+
+expect regular,0201,3,65534,65533 lstat ${n0} type,mode,nlink,uid,gid
+expect regular,0201,3,65534,65533 lstat ${n1} type,mode,nlink,uid,gid
+expect regular,0201,3,65534,65533 lstat ${n2} type,mode,nlink,uid,gid
+
+expect 0 unlink ${n0}
+expect ENOENT lstat ${n0} type,mode,nlink,uid,gid
+expect regular,0201,2,65534,65533 lstat ${n1} type,mode,nlink,uid,gid
+expect regular,0201,2,65534,65533 lstat ${n2} type,mode,nlink,uid,gid
+
+expect 0 unlink ${n2}
+expect ENOENT lstat ${n0} type,mode,nlink,uid,gid
+expect regular,0201,1,65534,65533 lstat ${n1} type,mode,nlink,uid,gid
+expect ENOENT lstat ${n2} type,mode,nlink,uid,gid
+
+expect 0 unlink ${n1}
+expect ENOENT lstat ${n0} type,mode,nlink,uid,gid
+expect ENOENT lstat ${n1} type,mode,nlink,uid,gid
+expect ENOENT lstat ${n2} type,mode,nlink,uid,gid
+
+expect 0 mkfifo ${n0} 0644
+expect fifo,0644,1 lstat ${n0} type,mode,nlink
+
+expect 0 link ${n0} ${n1}
+expect fifo,0644,2 lstat ${n0} type,mode,nlink
+expect fifo,0644,2 lstat ${n1} type,mode,nlink
+
+expect 0 link ${n1} ${n2}
+expect fifo,0644,3 lstat ${n0} type,mode,nlink
+expect fifo,0644,3 lstat ${n1} type,mode,nlink
+expect fifo,0644,3 lstat ${n2} type,mode,nlink
+
+expect 0 chmod ${n1} 0201
+expect 0 chown ${n1} 65534 65533
+
+expect fifo,0201,3,65534,65533 lstat ${n0} type,mode,nlink,uid,gid
+expect fifo,0201,3,65534,65533 lstat ${n1} type,mode,nlink,uid,gid
+expect fifo,0201,3,65534,65533 lstat ${n2} type,mode,nlink,uid,gid
+
+expect 0 unlink ${n0}
+expect ENOENT lstat ${n0} type,mode,nlink,uid,gid
+expect fifo,0201,2,65534,65533 lstat ${n1} type,mode,nlink,uid,gid
+expect fifo,0201,2,65534,65533 lstat ${n2} type,mode,nlink,uid,gid
+
+expect 0 unlink ${n2}
+expect ENOENT lstat ${n0} type,mode,nlink,uid,gid
+expect fifo,0201,1,65534,65533 lstat ${n1} type,mode,nlink,uid,gid
+expect ENOENT lstat ${n2} type,mode,nlink,uid,gid
+
+expect 0 unlink ${n1}
+expect ENOENT lstat ${n0} type,mode,nlink,uid,gid
+expect ENOENT lstat ${n1} type,mode,nlink,uid,gid
+expect ENOENT lstat ${n2} type,mode,nlink,uid,gid
+
+# successful link(2) updates ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+dctime1=`${FSTEST} stat . ctime`
+dmtime1=`${FSTEST} stat . mtime`
+sleep 1
+expect 0 link ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+dctime2=`${FSTEST} stat . ctime`
+test_check $dctime1 -lt $dctime2
+dmtime2=`${FSTEST} stat . mtime`
+test_check $dctime1 -lt $dmtime2
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
+
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+dctime1=`${FSTEST} stat . ctime`
+dmtime1=`${FSTEST} stat . mtime`
+sleep 1
+expect 0 link ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+dctime2=`${FSTEST} stat . ctime`
+test_check $dctime1 -lt $dctime2
+dmtime2=`${FSTEST} stat . mtime`
+test_check $dctime1 -lt $dmtime2
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
+
+# unsuccessful link(2) does not update ctime.
+expect 0 create ${n0} 0644
+expect 0 chown ${n0} 65534 -1
+ctime1=`${FSTEST} stat ${n0} ctime`
+dctime1=`${FSTEST} stat . ctime`
+dmtime1=`${FSTEST} stat . mtime`
+sleep 1
+expect EACCES -u 65534 link ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+dctime2=`${FSTEST} stat . ctime`
+test_check $dctime1 -eq $dctime2
+dmtime2=`${FSTEST} stat . mtime`
+test_check $dctime1 -eq $dmtime2
+expect 0 unlink ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect 0 chown ${n0} 65534 -1
+ctime1=`${FSTEST} stat ${n0} ctime`
+dctime1=`${FSTEST} stat . ctime`
+dmtime1=`${FSTEST} stat . mtime`
+sleep 1
+expect EACCES -u 65534 link ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+dctime2=`${FSTEST} stat . ctime`
+test_check $dctime1 -eq $dctime2
+dmtime2=`${FSTEST} stat . mtime`
+test_check $dctime1 -eq $dmtime2
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n3}
diff --git a/regress/sys/ffs/tests/link/01.t b/regress/sys/ffs/tests/link/01.t
new file mode 100644
index 00000000000..766fa2409a6
--- /dev/null
+++ b/regress/sys/ffs/tests/link/01.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/01.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns ENOTDIR if a component of either path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR link ${n0}/${n1}/test ${n0}/${n2}
+expect 0 create ${n0}/${n2} 0644
+expect ENOTDIR link ${n0}/${n2} ${n0}/${n1}/test
+expect 0 unlink ${n0}/${n1}
+expect 0 unlink ${n0}/${n2}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/02.t b/regress/sys/ffs/tests/link/02.t
new file mode 100644
index 00000000000..807a5a4c5a9
--- /dev/null
+++ b/regress/sys/ffs/tests/link/02.t
@@ -0,0 +1,18 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/02.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns ENAMETOOLONG if a component of either pathname exceeded 255 characters"
+
+n0=`namegen`
+
+expect 0 create ${name255} 0644
+expect 0 link ${name255} ${n0}
+expect 0 unlink ${name255}
+expect 0 link ${n0} ${name255}
+expect 0 unlink ${n0}
+expect 0 unlink ${name255}
+
+expect 0 create ${n0} 0644
+expect ENAMETOOLONG link ${n0} ${name256}
+expect 0 unlink ${n0}
+expect ENAMETOOLONG link ${name256} ${n0}
diff --git a/regress/sys/ffs/tests/link/03.t b/regress/sys/ffs/tests/link/03.t
new file mode 100644
index 00000000000..0ea265a2f4a
--- /dev/null
+++ b/regress/sys/ffs/tests/link/03.t
@@ -0,0 +1,23 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/03.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns ENAMETOOLONG if an entire length of either path name exceeded 1023 characters"
+
+n0=`namegen`
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 create ${path1023} 0644
+expect 0 link ${path1023} ${n0}
+expect 0 unlink ${path1023}
+expect 0 link ${n0} ${path1023}
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG link ${n0} ${path1024}
+expect 0 unlink ${n0}
+expect ENAMETOOLONG link ${path1024} ${n0}
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/link/04.t b/regress/sys/ffs/tests/link/04.t
new file mode 100644
index 00000000000..4da80462c2d
--- /dev/null
+++ b/regress/sys/ffs/tests/link/04.t
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/04.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns ENOENT if a component of either path prefix does not exist"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT link ${n0}/${n1}/test ${n2}
+expect 0 create ${n2} 0644
+expect ENOENT link ${n2} ${n0}/${n1}/test
+expect 0 unlink ${n2}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/05.t b/regress/sys/ffs/tests/link/05.t
new file mode 100644
index 00000000000..63b68b4a604
--- /dev/null
+++ b/regress/sys/ffs/tests/link/05.t
@@ -0,0 +1,31 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/05.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EMLINK if the link count of the file named by name1 would exceed 32767"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs -i 1 /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+i=1
+while :; do
+ link ${n0}/${n1} ${n0}/${i} >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ break
+ fi
+ i=`expr $i + 1`
+done
+test_check $i -eq 32767
+
+expect EMLINK link ${n0}/${n1} ${n0}/${n2}
+
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/06.t b/regress/sys/ffs/tests/link/06.t
new file mode 100644
index 00000000000..643c008a49f
--- /dev/null
+++ b/regress/sys/ffs/tests/link/06.t
@@ -0,0 +1,38 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/06.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EACCES when a component of either path prefix denies search permission"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+n4=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 mkdir ${n2} 0755
+expect 0 chown ${n2} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n3} 0644
+
+expect 0 -u 65534 -g 65534 link ${n1}/${n3} ${n2}/${n4}
+expect 0 -u 65534 -g 65534 unlink ${n2}/${n4}
+
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 link ${n1}/${n3} ${n1}/${n4}
+expect EACCES -u 65534 -g 65534 link ${n1}/${n3} ${n2}/${n4}
+
+expect 0 chmod ${n1} 0755
+expect 0 chmod ${n2} 0644
+expect EACCES -u 65534 -g 65534 link ${n1}/${n3} ${n2}/${n4}
+
+expect 0 unlink ${n1}/${n3}
+expect 0 rmdir ${n1}
+expect 0 rmdir ${n2}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/07.t b/regress/sys/ffs/tests/link/07.t
new file mode 100644
index 00000000000..0c1367c9299
--- /dev/null
+++ b/regress/sys/ffs/tests/link/07.t
@@ -0,0 +1,36 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/07.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EACCES when the requested link requires writing in a directory with a mode that denies write permission"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+n4=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 mkdir ${n2} 0755
+expect 0 chown ${n2} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n3} 0644
+
+expect 0 -u 65534 -g 65534 link ${n1}/${n3} ${n2}/${n4}
+expect 0 -u 65534 -g 65534 unlink ${n2}/${n4}
+
+expect 0 chmod ${n2} 0555
+expect EACCES -u 65534 -g 65534 link ${n1}/${n3} ${n2}/${n4}
+expect 0 chmod ${n1} 0555
+expect EACCES -u 65534 -g 65534 link ${n1}/${n3} ${n1}/${n4}
+expect 0 chmod ${n1} 0755
+
+expect 0 unlink ${n1}/${n3}
+expect 0 rmdir ${n1}
+expect 0 rmdir ${n2}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/08.t b/regress/sys/ffs/tests/link/08.t
new file mode 100644
index 00000000000..8fdea089521
--- /dev/null
+++ b/regress/sys/ffs/tests/link/08.t
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/08.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns ELOOP if too many symbolic links were encountered in translating one of the pathnames"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP link ${n0}/test ${n2}
+expect ELOOP link ${n1}/test ${n2}
+expect 0 create ${n2} 0644
+expect ELOOP link ${n2} ${n0}/test
+expect ELOOP link ${n2} ${n1}/test
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
+expect 0 unlink ${n2}
diff --git a/regress/sys/ffs/tests/link/09.t b/regress/sys/ffs/tests/link/09.t
new file mode 100644
index 00000000000..679276f2e11
--- /dev/null
+++ b/regress/sys/ffs/tests/link/09.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/09.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns ENOENT if the source file does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 link ${n0} ${n1}
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
+expect ENOENT link ${n0} ${n1}
diff --git a/regress/sys/ffs/tests/link/10.t b/regress/sys/ffs/tests/link/10.t
new file mode 100644
index 00000000000..98fbeababa8
--- /dev/null
+++ b/regress/sys/ffs/tests/link/10.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/10.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EEXIST if the destination file does exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 create ${n0} 0644
+
+expect 0 create ${n1} 0644
+expect EEXIST link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+expect EEXIST link ${n0} ${n1}
+expect 0 rmdir ${n1}
+
+expect 0 symlink test ${n1}
+expect EEXIST link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect EEXIST link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/link/11.t b/regress/sys/ffs/tests/link/11.t
new file mode 100644
index 00000000000..a839b65cebf
--- /dev/null
+++ b/regress/sys/ffs/tests/link/11.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/11.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EPERM if the source file is a directory"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect EPERM link ${n0} ${n1}
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65534
+cdir=`pwd`
+cd ${n0}
+
+expect 0 -u 65534 -g 65534 mkdir ${n1} 0755
+expect EPERM -u 65534 -g 65534 link ${n1} ${n2}
+expect 0 -u 65534 -g 65534 rmdir ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/12.t b/regress/sys/ffs/tests/link/12.t
new file mode 100644
index 00000000000..ee8049509c9
--- /dev/null
+++ b/regress/sys/ffs/tests/link/12.t
@@ -0,0 +1,48 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/12.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EPERM if the source file has its immutable or append-only flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 create ${n0} 0644
+
+expect 0 link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM link ${n0} ${n1}
+expect 0 chflags ${n0} none
+expect 0 link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM link ${n0} ${n1}
+expect 0 chflags ${n0} none
+expect 0 link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM link ${n0} ${n1}
+expect 0 chflags ${n0} none
+expect 0 link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM link ${n0} ${n1}
+expect 0 chflags ${n0} none
+expect 0 link ${n0} ${n1}
+expect 0 unlink ${n1}
+
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 link ${n0} ${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n1}
+
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 link ${n0} ${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n1}
+
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/link/13.t b/regress/sys/ffs/tests/link/13.t
new file mode 100644
index 00000000000..fca74a4237f
--- /dev/null
+++ b/regress/sys/ffs/tests/link/13.t
@@ -0,0 +1,49 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/13.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EPERM if the parent directory of the destination file has its immutable flag set"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 create ${n0}/${n1} 0644
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 unlink ${n0}/${n2}
+
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM link ${n0}/${n1} ${n0}/${n2}
+expect 0 chflags ${n0} none
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 unlink ${n0}/${n2}
+
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM link ${n0}/${n1} ${n0}/${n2}
+expect 0 chflags ${n0} none
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 unlink ${n0}/${n2}
+
+expect 0 chflags ${n0} SF_APPEND
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n2}
+
+expect 0 chflags ${n0} UF_APPEND
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n2}
+
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n2}
+
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n2}
+
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/14.t b/regress/sys/ffs/tests/link/14.t
new file mode 100644
index 00000000000..95372da657f
--- /dev/null
+++ b/regress/sys/ffs/tests/link/14.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/14.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EXDEV if the source and the destination files are on different file systems"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+expect EXDEV link ${n0}/${n1} ${n2}
+expect 0 unlink ${n0}/${n1}
+expect 0 create ${n1} 0644
+expect EXDEV link ${n1} ${n0}/${n2}
+expect 0 unlink ${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/15.t b/regress/sys/ffs/tests/link/15.t
new file mode 100644
index 00000000000..cbe19522dee
--- /dev/null
+++ b/regress/sys/ffs/tests/link/15.t
@@ -0,0 +1,28 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/15.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns ENOSPC if the directory in which the entry for the new link is being placed cannot be extended because there is no space left on the file system containing the directory"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=256 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+i=0
+while :; do
+ link ${n0}/${n1} ${n0}/${i} >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ break
+ fi
+ i=`expr $i + 1`
+done
+expect ENOSPC link ${n0}/${n1} ${n0}/${n2}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/16.t b/regress/sys/ffs/tests/link/16.t
new file mode 100644
index 00000000000..6cfe6de7360
--- /dev/null
+++ b/regress/sys/ffs/tests/link/16.t
@@ -0,0 +1,29 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/16.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EROFS if the requested link requires writing in a directory on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 unlink ${n0}/${n2}
+mount -ur /dev/svnd1c
+expect EROFS link ${n0}/${n1} ${n0}/${n2}
+mount -uw /dev/svnd1c
+expect 0 link ${n0}/${n1} ${n0}/${n2}
+expect 0 unlink ${n0}/${n2}
+
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/link/17.t b/regress/sys/ffs/tests/link/17.t
new file mode 100644
index 00000000000..cb472ba4a32
--- /dev/null
+++ b/regress/sys/ffs/tests/link/17.t
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/link/17.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="link returns EFAULT if one of the pathnames specified is outside the process's allocated address space"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect EFAULT link ${n0} NULL
+expect EFAULT link ${n0} DEADCODE
+expect 0 unlink ${n0}
+expect EFAULT link NULL ${n0}
+expect EFAULT link DEADCODE ${n0}
+expect EFAULT link NULL DEADCODE
+expect EFAULT link DEADCODE NULL
diff --git a/regress/sys/ffs/tests/mkdir/00.t b/regress/sys/ffs/tests/mkdir/00.t
new file mode 100644
index 00000000000..991d825a314
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/00.t
@@ -0,0 +1,68 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/00.t,v 1.2 2007/01/25 20:50:02 pjd Exp $
+
+desc="mkdir creates directories"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n1} 0755
+cdir=`pwd`
+cd ${n1}
+
+# POSIX: The file permission bits of the new directory shall be initialized from
+# mode. These file permission bits of the mode argument shall be modified by the
+# process' file creation mask.
+expect 0 mkdir ${n0} 0755
+expect dir,0755 lstat ${n0} type,mode
+expect 0 rmdir ${n0}
+expect 0 mkdir ${n0} 0151
+expect dir,0151 lstat ${n0} type,mode
+expect 0 rmdir ${n0}
+expect 0 -U 077 mkdir ${n0} 0151
+expect dir,0100 lstat ${n0} type,mode
+expect 0 rmdir ${n0}
+expect 0 -U 070 mkdir ${n0} 0345
+expect dir,0305 lstat ${n0} type,mode
+expect 0 rmdir ${n0}
+expect 0 -U 0501 mkdir ${n0} 0345
+expect dir,0244 lstat ${n0} type,mode
+expect 0 rmdir ${n0}
+
+# POSIX: The directory's user ID shall be set to the process' effective user ID.
+# The directory's group ID shall be set to the group ID of the parent directory
+# or to the effective group ID of the process.
+expect 0 chown . 65535 65535
+expect 0 -u 65535 -g 65535 mkdir ${n0} 0755
+expect 65535,65535 lstat ${n0} uid,gid
+expect 0 rmdir ${n0}
+expect 0 -u 65535 -g 65534 mkdir ${n0} 0755
+expect "65535,6553[45]" lstat ${n0} uid,gid
+expect 0 rmdir ${n0}
+expect 0 chmod . 0777
+expect 0 -u 65534 -g 65533 mkdir ${n0} 0755
+expect "65534,6553[35]" lstat ${n0} uid,gid
+expect 0 rmdir ${n0}
+
+# POSIX: Upon successful completion, mkdir() shall mark for update the st_atime,
+# st_ctime, and st_mtime fields of the directory. Also, the st_ctime and
+# st_mtime fields of the directory that contains the new entry shall be marked
+# for update.
+expect 0 chown . 0 0
+time=`${FSTEST} stat . ctime`
+sleep 1
+expect 0 mkdir ${n0} 0755
+atime=`${FSTEST} stat ${n0} atime`
+test_check $time -lt $atime
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+mtime=`${FSTEST} stat . mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat . ctime`
+test_check $time -lt $ctime
+expect 0 rmdir ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n1}
diff --git a/regress/sys/ffs/tests/mkdir/01.t b/regress/sys/ffs/tests/mkdir/01.t
new file mode 100644
index 00000000000..fb20427c8f2
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/01.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR mkdir ${n0}/${n1}/test 0755
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/02.t b/regress/sys/ffs/tests/mkdir/02.t
new file mode 100644
index 00000000000..8235b6ca829
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/02.t
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/02.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 rmdir ${name255}
+expect ENAMETOOLONG mkdir ${name256} 0755
diff --git a/regress/sys/ffs/tests/mkdir/03.t b/regress/sys/ffs/tests/mkdir/03.t
new file mode 100644
index 00000000000..e7cb8ee3815
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/03.t
@@ -0,0 +1,16 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/03.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 mkdir ${path1023} 0755
+expect 0 rmdir ${path1023}
+expect ENAMETOOLONG mkdir ${path1024} 0755
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/mkdir/04.t b/regress/sys/ffs/tests/mkdir/04.t
new file mode 100644
index 00000000000..8e8ca46a678
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/04.t
@@ -0,0 +1,11 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/04.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns ENOENT if a component of the path prefix does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT mkdir ${n0}/${n1}/test 0755
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/05.t b/regress/sys/ffs/tests/mkdir/05.t
new file mode 100644
index 00000000000..aeb982edc63
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/05.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/05.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/06.t b/regress/sys/ffs/tests/mkdir/06.t
new file mode 100644
index 00000000000..35479539ab6
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/06.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/06.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns EACCES when write permission is denied on the parent directory of the directory to be created"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 chmod ${n1} 0555
+expect EACCES -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/07.t b/regress/sys/ffs/tests/mkdir/07.t
new file mode 100644
index 00000000000..340b867c730
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/07.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/07.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP mkdir ${n0}/test 0755
+expect ELOOP mkdir ${n1}/test 0755
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/mkdir/08.t b/regress/sys/ffs/tests/mkdir/08.t
new file mode 100644
index 00000000000..39bf7bc804e
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/08.t
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/08.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns EPERM if the parent directory of the directory to be created has its immutable flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} none
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} none
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_APPEND
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_APPEND
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/09.t b/regress/sys/ffs/tests/mkdir/09.t
new file mode 100644
index 00000000000..43c13d18532
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/09.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/09.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 rmdir ${n0}/${n1}
+mount -ur /dev/svnd1c
+expect EROFS mkdir ${n0}/${n1} 0755
+mount -uw /dev/svnd1c
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 rmdir ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/10.t b/regress/sys/ffs/tests/mkdir/10.t
new file mode 100644
index 00000000000..93d00f26bc3
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/10.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/10.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns EEXIST if the named file exists"
+
+n0=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect EEXIST mkdir ${n0} 0755
+expect 0 rmdir ${n0}
+
+expect 0 create ${n0} 0644
+expect EEXIST mkdir ${n0} 0755
+expect 0 unlink ${n0}
+
+expect 0 symlink test ${n0}
+expect EEXIST mkdir ${n0} 0755
+expect 0 unlink ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect EEXIST mkdir ${n0} 0755
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/11.t b/regress/sys/ffs/tests/mkdir/11.t
new file mode 100644
index 00000000000..0eeac313d0b
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/11.t
@@ -0,0 +1,26 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/11.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns ENOSPC if there are no free inodes on the file system on which the directory is being created"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=256 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+i=0
+while :; do
+ mkdir ${n0}/${i} >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ break
+ fi
+ i=`expr $i + 1`
+done
+expect ENOSPC mkdir ${n0}/${n1} 0755
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkdir/12.t b/regress/sys/ffs/tests/mkdir/12.t
new file mode 100644
index 00000000000..a526a69d927
--- /dev/null
+++ b/regress/sys/ffs/tests/mkdir/12.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkdir/12.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkdir returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT mkdir NULL 0755
+expect EFAULT mkdir DEADCODE 0755
diff --git a/regress/sys/ffs/tests/mkfifo/00.t b/regress/sys/ffs/tests/mkfifo/00.t
new file mode 100644
index 00000000000..be417091bf7
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/00.t
@@ -0,0 +1,68 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/00.t,v 1.2 2007/01/25 20:50:02 pjd Exp $
+
+desc="mkfifo creates fifo files"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n1} 0755
+cdir=`pwd`
+cd ${n1}
+
+# POSIX: The file permission bits of the new FIFO shall be initialized from
+# mode. The file permission bits of the mode argument shall be modified by the
+# process' file creation mask.
+expect 0 mkfifo ${n0} 0755
+expect fifo,0755 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 mkfifo ${n0} 0151
+expect fifo,0151 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 -U 077 mkfifo ${n0} 0151
+expect fifo,0100 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 -U 070 mkfifo ${n0} 0345
+expect fifo,0305 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 -U 0501 mkfifo ${n0} 0345
+expect fifo,0244 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+
+# POSIX: The FIFO's user ID shall be set to the process' effective user ID.
+# The FIFO's group ID shall be set to the group ID of the parent directory or to
+# the effective group ID of the process.
+expect 0 chown . 65535 65535
+expect 0 -u 65535 -g 65535 mkfifo ${n0} 0755
+expect 65535,65535 lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+expect 0 -u 65535 -g 65534 mkfifo ${n0} 0755
+expect "65535,6553[45]" lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+expect 0 chmod . 0777
+expect 0 -u 65534 -g 65533 mkfifo ${n0} 0755
+expect "65534,6553[35]" lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+
+# POSIX: Upon successful completion, mkfifo() shall mark for update the
+# st_atime, st_ctime, and st_mtime fields of the file. Also, the st_ctime and
+# st_mtime fields of the directory that contains the new entry shall be marked
+# for update.
+expect 0 chown . 0 0
+time=`${FSTEST} stat . ctime`
+sleep 1
+expect 0 mkfifo ${n0} 0755
+atime=`${FSTEST} stat ${n0} atime`
+test_check $time -lt $atime
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+mtime=`${FSTEST} stat . mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat . ctime`
+test_check $time -lt $ctime
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n1}
diff --git a/regress/sys/ffs/tests/mkfifo/01.t b/regress/sys/ffs/tests/mkfifo/01.t
new file mode 100644
index 00000000000..c9ba0fb04b7
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/01.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR mkfifo ${n0}/${n1}/test 0644
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/02.t b/regress/sys/ffs/tests/mkfifo/02.t
new file mode 100644
index 00000000000..95580667ec5
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/02.t
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/02.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 mkfifo ${name255} 0644
+expect 0 unlink ${name255}
+expect ENAMETOOLONG mkfifo ${name256} 0644
diff --git a/regress/sys/ffs/tests/mkfifo/03.t b/regress/sys/ffs/tests/mkfifo/03.t
new file mode 100644
index 00000000000..74c3637cbbc
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/03.t
@@ -0,0 +1,16 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/03.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 mkfifo ${path1023} 0644
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG mkfifo ${path1024} 0644
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/mkfifo/04.t b/regress/sys/ffs/tests/mkfifo/04.t
new file mode 100644
index 00000000000..a24ed1b4a02
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/04.t
@@ -0,0 +1,11 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/04.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns ENOENT if a component of the path prefix does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT mkfifo ${n0}/${n1}/test 0644
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/05.t b/regress/sys/ffs/tests/mkfifo/05.t
new file mode 100644
index 00000000000..bf4b78d4807
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/05.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/05.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 mkfifo ${n1}/${n2} 0644
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/06.t b/regress/sys/ffs/tests/mkfifo/06.t
new file mode 100644
index 00000000000..f8478cd6752
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/06.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/06.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns EACCES when write permission is denied on the parent directory of the file to be created"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 chmod ${n1} 0555
+expect EACCES -u 65534 -g 65534 mkfifo ${n1}/${n2} 0644
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/07.t b/regress/sys/ffs/tests/mkfifo/07.t
new file mode 100644
index 00000000000..e4dc57cb762
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/07.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/07.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP mkfifo ${n0}/test 0644
+expect ELOOP mkfifo ${n1}/test 0644
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/mkfifo/08.t b/regress/sys/ffs/tests/mkfifo/08.t
new file mode 100644
index 00000000000..4364fb03153
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/08.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/08.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 unlink ${n0}/${n1}
+mount -ur /dev/svnd1c
+expect EROFS mkfifo ${n0}/${n1} 0644
+#mount -uw /dev/svnd1c
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/09.t b/regress/sys/ffs/tests/mkfifo/09.t
new file mode 100644
index 00000000000..7a1d67ce12d
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/09.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/09.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns EEXIST if the named file exists"
+
+n0=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect EEXIST mkfifo ${n0} 0644
+expect 0 rmdir ${n0}
+
+expect 0 create ${n0} 0644
+expect EEXIST mkfifo ${n0} 0644
+expect 0 unlink ${n0}
+
+expect 0 symlink test ${n0}
+expect EEXIST mkfifo ${n0} 0644
+expect 0 unlink ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect EEXIST mkfifo ${n0} 0644
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/10.t b/regress/sys/ffs/tests/mkfifo/10.t
new file mode 100644
index 00000000000..26bdb526361
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/10.t
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/10.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns EPERM if the parent directory of the file to be created has its immutable flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM mkfifo ${n0}/${n1} 0644
+expect 0 chflags ${n0} none
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM mkfifo ${n0}/${n1} 0644
+expect 0 chflags ${n0} none
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_APPEND
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_APPEND
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 mkfifo ${n0}/${n1} 0644
+expect 0 unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/11.t b/regress/sys/ffs/tests/mkfifo/11.t
new file mode 100644
index 00000000000..383ee681439
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/11.t
@@ -0,0 +1,26 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/11.t,v 1.1 2007/01/17 01:42:09 pjd Exp $
+
+desc="mkfifo returns ENOSPC if there are no free inodes on the file system on which the file is being created"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=256 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+i=0
+while :; do
+ mkfifo ${n0}/${i} >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ break
+ fi
+ i=`expr $i + 1`
+done
+expect ENOSPC mkfifo ${n0}/${n1} 0644
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/mkfifo/12.t b/regress/sys/ffs/tests/mkfifo/12.t
new file mode 100644
index 00000000000..1807903933c
--- /dev/null
+++ b/regress/sys/ffs/tests/mkfifo/12.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/mkfifo/12.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="mkfifo returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT mkfifo NULL 0644
+expect EFAULT mkfifo DEADCODE 0644
diff --git a/regress/sys/ffs/tests/open/00.t b/regress/sys/ffs/tests/open/00.t
new file mode 100644
index 00000000000..1a60afbc139
--- /dev/null
+++ b/regress/sys/ffs/tests/open/00.t
@@ -0,0 +1,94 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/00.t,v 1.2 2007/01/25 20:50:02 pjd Exp $
+
+desc="open opens (and eventually creates) a file"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n1} 0755
+cdir=`pwd`
+cd ${n1}
+
+# POSIX: (If O_CREAT is specified and the file doesn't exist) [...] the access
+# permission bits of the file mode shall be set to the value of the third
+# argument taken as type mode_t modified as follows: a bitwise AND is performed
+# on the file-mode bits and the corresponding bits in the complement of the
+# process' file mode creation mask. Thus, all bits in the file mode whose
+# corresponding bit in the file mode creation mask is set are cleared.
+expect 0 open ${n0} O_CREAT,O_WRONLY 0755
+expect regular,0755 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 open ${n0} O_CREAT,O_WRONLY 0151
+expect regular,0151 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 -U 077 open ${n0} O_CREAT,O_WRONLY 0151
+expect regular,0100 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 -U 070 open ${n0} O_CREAT,O_WRONLY 0345
+expect regular,0305 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+expect 0 -U 0501 open ${n0} O_CREAT,O_WRONLY 0345
+expect regular,0244 lstat ${n0} type,mode
+expect 0 unlink ${n0}
+
+# POSIX: (If O_CREAT is specified and the file doesn't exist) [...] the user ID
+# of the file shall be set to the effective user ID of the process; the group ID
+# of the file shall be set to the group ID of the file's parent directory or to
+# the effective group ID of the process [...]
+expect 0 chown . 65535 65535
+expect 0 -u 65535 -g 65535 open ${n0} O_CREAT,O_WRONLY 0644
+expect 65535,65535 lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+expect 0 -u 65535 -g 65534 open ${n0} O_CREAT,O_WRONLY 0644
+expect "65535,6553[45]" lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+expect 0 chmod . 0777
+expect 0 -u 65534 -g 65533 open ${n0} O_CREAT,O_WRONLY 0644
+expect "65534,6553[35]" lstat ${n0} uid,gid
+expect 0 unlink ${n0}
+
+# Update parent directory ctime/mtime if file didn't exist.
+expect 0 chown . 0 0
+time=`${FSTEST} stat . ctime`
+sleep 1
+expect 0 open ${n0} O_CREAT,O_WRONLY 0644
+atime=`${FSTEST} stat ${n0} atime`
+test_check $time -lt $atime
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+mtime=`${FSTEST} stat . mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat . ctime`
+test_check $time -lt $ctime
+expect 0 unlink ${n0}
+
+# Don't update parent directory ctime/mtime if file existed.
+expect 0 create ${n0} 0644
+dmtime=`${FSTEST} stat . mtime`
+dctime=`${FSTEST} stat . ctime`
+sleep 1
+expect 0 open ${n0} O_CREAT,O_RDONLY 0644
+mtime=`${FSTEST} stat . mtime`
+test_check $dmtime -eq $mtime
+ctime=`${FSTEST} stat . ctime`
+test_check $dctime -eq $ctime
+expect 0 unlink ${n0}
+
+echo test > ${n0}
+expect 5 stat ${n0} size
+mtime1=`${FSTEST} stat ${n0} mtime`
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 open ${n0} O_WRONLY,O_TRUNC
+mtime2=`${FSTEST} stat ${n0} mtime`
+test_check $mtime1 -lt $mtime2
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 stat ${n0} size
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n1}
diff --git a/regress/sys/ffs/tests/open/01.t b/regress/sys/ffs/tests/open/01.t
new file mode 100644
index 00000000000..16d4c8577d1
--- /dev/null
+++ b/regress/sys/ffs/tests/open/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/01.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR open ${n0}/${n1}/test O_CREAT 0644
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/02.t b/regress/sys/ffs/tests/open/02.t
new file mode 100644
index 00000000000..caaf0cfabae
--- /dev/null
+++ b/regress/sys/ffs/tests/open/02.t
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/02.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 open ${name255} O_CREAT 0620
+expect 0620 stat ${name255} mode
+expect 0 unlink ${name255}
+expect ENAMETOOLONG open ${name256} O_CREAT 0620
diff --git a/regress/sys/ffs/tests/open/03.t b/regress/sys/ffs/tests/open/03.t
new file mode 100644
index 00000000000..9b184fff702
--- /dev/null
+++ b/regress/sys/ffs/tests/open/03.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/03.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 open ${path1023} O_CREAT 0642
+expect 0642 stat ${path1023} mode
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG open ${path1024} O_CREAT 0642
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/open/04.t b/regress/sys/ffs/tests/open/04.t
new file mode 100644
index 00000000000..c59bf4de48e
--- /dev/null
+++ b/regress/sys/ffs/tests/open/04.t
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/04.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ENOENT if a component of the path name that must exist does not exist or O_CREAT is not set and the named file does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT open ${n0}/${n1}/test O_CREAT 0644
+expect ENOENT open ${n0}/${n1} O_RDONLY
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/05.t b/regress/sys/ffs/tests/open/05.t
new file mode 100644
index 00000000000..a849b31480e
--- /dev/null
+++ b/regress/sys/ffs/tests/open/05.t
@@ -0,0 +1,24 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/05.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 open ${n1}/${n2} O_RDONLY
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 open ${n1}/${n2} O_RDONLY
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 open ${n1}/${n2} O_RDONLY
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/06.t b/regress/sys/ffs/tests/open/06.t
new file mode 100644
index 00000000000..8de3d1d3218
--- /dev/null
+++ b/regress/sys/ffs/tests/open/06.t
@@ -0,0 +1,84 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/06.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EACCES when the required permissions (for reading and/or writing) are denied for the given flags"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65534
+cdir=`pwd`
+cd ${n0}
+
+expect 0 -u 65534 -g 65534 create ${n1} 0644
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0600
+expect 0 -u 65534 -g 65534 open ${n1} O_RDONLY
+expect 0 -u 65534 -g 65534 open ${n1} O_WRONLY
+expect 0 -u 65534 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0060
+expect 0 -u 65533 -g 65534 open ${n1} O_RDONLY
+expect 0 -u 65533 -g 65534 open ${n1} O_WRONLY
+expect 0 -u 65533 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0006
+expect 0 -u 65533 -g 65533 open ${n1} O_RDONLY
+expect 0 -u 65533 -g 65533 open ${n1} O_WRONLY
+expect 0 -u 65533 -g 65533 open ${n1} O_RDWR
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0477
+expect 0 -u 65534 -g 65534 open ${n1} O_RDONLY
+expect EACCES -u 65534 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0747
+expect 0 -u 65533 -g 65534 open ${n1} O_RDONLY
+expect EACCES -u 65533 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0774
+expect 0 -u 65533 -g 65533 open ${n1} O_RDONLY
+expect EACCES -u 65533 -g 65533 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDWR
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0277
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDONLY
+expect 0 -u 65534 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0727
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDONLY
+expect 0 -u 65533 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0772
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDONLY
+expect 0 -u 65533 -g 65533 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDWR
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0177
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDONLY
+expect EACCES -u 65534 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0717
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDONLY
+expect EACCES -u 65533 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0771
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDONLY
+expect EACCES -u 65533 -g 65533 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDWR
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0077
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDONLY
+expect EACCES -u 65534 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0707
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDONLY
+expect EACCES -u 65533 -g 65534 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDWR
+expect 0 -u 65534 -g 65534 chmod ${n1} 0770
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDONLY
+expect EACCES -u 65533 -g 65533 open ${n1} O_WRONLY
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDWR
+
+expect 0 -u 65534 -g 65534 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/07.t b/regress/sys/ffs/tests/open/07.t
new file mode 100644
index 00000000000..22e2f5733f7
--- /dev/null
+++ b/regress/sys/ffs/tests/open/07.t
@@ -0,0 +1,40 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/07.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EACCES when O_TRUNC is specified and write permission is denied"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65534
+cdir=`pwd`
+cd ${n0}
+
+expect 0 -u 65534 -g 65534 create ${n1} 0644
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0477
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDONLY,O_TRUNC
+expect 0 -u 65534 -g 65534 chmod ${n1} 0747
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDONLY,O_TRUNC
+expect 0 -u 65534 -g 65534 chmod ${n1} 0774
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDONLY,O_TRUNC
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0177
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDONLY,O_TRUNC
+expect 0 -u 65534 -g 65534 chmod ${n1} 0717
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDONLY,O_TRUNC
+expect 0 -u 65534 -g 65534 chmod ${n1} 0771
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDONLY,O_TRUNC
+
+expect 0 -u 65534 -g 65534 chmod ${n1} 0077
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDONLY,O_TRUNC
+expect 0 -u 65534 -g 65534 chmod ${n1} 0707
+expect EACCES -u 65533 -g 65534 open ${n1} O_RDONLY,O_TRUNC
+expect 0 -u 65534 -g 65534 chmod ${n1} 0770
+expect EACCES -u 65533 -g 65533 open ${n1} O_RDONLY,O_TRUNC
+
+expect 0 -u 65534 -g 65534 unlink ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/08.t b/regress/sys/ffs/tests/open/08.t
new file mode 100644
index 00000000000..200f8322a2e
--- /dev/null
+++ b/regress/sys/ffs/tests/open/08.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/08.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EACCES when O_CREAT is specified, the file does not exist, and the directory in which it is to be created does not permit writing"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect EACCES -u 65534 -g 65534 open ${n1} O_RDONLY,O_CREAT 0644
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/09.t b/regress/sys/ffs/tests/open/09.t
new file mode 100644
index 00000000000..71532485efc
--- /dev/null
+++ b/regress/sys/ffs/tests/open/09.t
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/09.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="O_CREAT is specified, the file does not exist, and the directory in which it is to be created has its immutable flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 chflags ${n0} none
+expect 0 open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 chflags ${n0} none
+expect 0 open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_APPEND
+expect 0 open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_APPEND
+expect 0 open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 symlink test ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/10.t b/regress/sys/ffs/tests/open/10.t
new file mode 100644
index 00000000000..0a207743e4c
--- /dev/null
+++ b/regress/sys/ffs/tests/open/10.t
@@ -0,0 +1,38 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/10.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EPERM when the named file has its immutable flag set and the file is to be modified"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM open ${n0} O_WRONLY
+expect EPERM open ${n0} O_RDWR
+expect EPERM open ${n0} O_RDONLY,O_TRUNC
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM open ${n0} O_WRONLY
+expect EPERM open ${n0} O_RDWR
+expect EPERM open ${n0} O_RDONLY,O_TRUNC
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 open ${n0} O_WRONLY
+expect 0 open ${n0} O_RDWR
+expect 0 open ${n0} O_RDONLY,O_TRUNC
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 open ${n0} O_WRONLY
+expect 0 open ${n0} O_RDWR
+expect 0 open ${n0} O_RDONLY,O_TRUNC
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/open/11.t b/regress/sys/ffs/tests/open/11.t
new file mode 100644
index 00000000000..764cb02d937
--- /dev/null
+++ b/regress/sys/ffs/tests/open/11.t
@@ -0,0 +1,32 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/11.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EPERM when the named file has its append-only flag set, the file is to be modified, and O_TRUNC is specified or O_APPEND is not specified"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_APPEND
+expect 0 open ${n0} O_WRONLY,O_APPEND
+expect 0 open ${n0} O_RDWR,O_APPEND
+expect EPERM open ${n0} O_WRONLY
+expect EPERM open ${n0} O_RDWR
+expect EPERM open ${n0} O_RDONLY,O_TRUNC
+expect EPERM open ${n0} O_RDONLY,O_APPEND,O_TRUNC
+expect EPERM open ${n0} O_WRONLY,O_APPEND,O_TRUNC
+expect EPERM open ${n0} O_RDWR,O_APPEND,O_TRUNC
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_APPEND
+expect 0 open ${n0} O_WRONLY,O_APPEND
+expect 0 open ${n0} O_RDWR,O_APPEND
+expect EPERM open ${n0} O_WRONLY
+expect EPERM open ${n0} O_RDWR
+expect EPERM open ${n0} O_RDONLY,O_TRUNC
+expect EPERM open ${n0} O_RDONLY,O_APPEND,O_TRUNC
+expect EPERM open ${n0} O_WRONLY,O_APPEND,O_TRUNC
+expect EPERM open ${n0} O_RDWR,O_APPEND,O_TRUNC
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/open/12.t b/regress/sys/ffs/tests/open/12.t
new file mode 100644
index 00000000000..3e2884790d2
--- /dev/null
+++ b/regress/sys/ffs/tests/open/12.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/12.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP open ${n0}/test O_RDONLY
+expect ELOOP open ${n1}/test O_RDONLY
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/open/13.t b/regress/sys/ffs/tests/open/13.t
new file mode 100644
index 00000000000..715f0819881
--- /dev/null
+++ b/regress/sys/ffs/tests/open/13.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/13.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EISDIR when he named file is a directory, and the arguments specify it is to be modified"
+
+n0=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 open ${n0} O_RDONLY
+expect EISDIR open ${n0} O_WRONLY
+expect EISDIR open ${n0} O_RDWR
+expect EISDIR open ${n0} O_RDONLY,O_TRUNC
+expect EISDIR open ${n0} O_WRONLY,O_TRUNC
+expect EISDIR open ${n0} O_RDWR,O_TRUNC
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/14.t b/regress/sys/ffs/tests/open/14.t
new file mode 100644
index 00000000000..577d37f6634
--- /dev/null
+++ b/regress/sys/ffs/tests/open/14.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/14.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EROFS if the named file resides on a read-only file system, and the file is to be modified"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+expect 0 open ${n0}/${n1} O_WRONLY
+expect 0 open ${n0}/${n1} O_RDWR
+expect 0 open ${n0}/${n1} O_RDONLY,O_TRUNC
+mount -ur /dev/svnd1c
+expect EROFS open ${n0}/${n1} O_WRONLY
+expect EROFS open ${n0}/${n1} O_RDWR
+expect EROFS open ${n0}/${n1} O_RDONLY,O_TRUNC
+mount -uw /dev/svnd1c
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/15.t b/regress/sys/ffs/tests/open/15.t
new file mode 100644
index 00000000000..4eae05cb935
--- /dev/null
+++ b/regress/sys/ffs/tests/open/15.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/15.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EROFS when O_CREAT is specified and the named file would reside on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+expect 0 unlink ${n0}/${n1}
+mount -ur /dev/svnd1c
+expect EROFS open ${n0}/${n1} O_RDONLY,O_CREAT 0644
+mount -uw /dev/svnd1c
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/16.t b/regress/sys/ffs/tests/open/16.t
new file mode 100644
index 00000000000..d22381b48e4
--- /dev/null
+++ b/regress/sys/ffs/tests/open/16.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/16.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EMLINK when O_NOFOLLOW was specified and the target is a symbolic link"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect EMLINK open ${n1} O_RDONLY,O_CREAT,O_NOFOLLOW 0644
+expect EMLINK open ${n1} O_RDONLY,O_NOFOLLOW
+expect EMLINK open ${n1} O_WRONLY,O_NOFOLLOW
+expect EMLINK open ${n1} O_RDWR,O_NOFOLLOW
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/open/17.t b/regress/sys/ffs/tests/open/17.t
new file mode 100644
index 00000000000..49d569eaa72
--- /dev/null
+++ b/regress/sys/ffs/tests/open/17.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/17.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ENXIO when O_NONBLOCK is set, the named file is a fifo, O_WRONLY is set, and no process has the file open for reading"
+
+n0=`namegen`
+
+expect 0 mkfifo ${n0} 0644
+expect ENXIO open ${n0} O_WRONLY,O_NONBLOCK
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/open/18.t b/regress/sys/ffs/tests/open/18.t
new file mode 100644
index 00000000000..d15190fc7eb
--- /dev/null
+++ b/regress/sys/ffs/tests/open/18.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/18.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EWOULDBLOCK when O_NONBLOCK and one of O_SHLOCK or O_EXLOCK is specified and the file is locked"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 open ${n0} O_RDONLY,O_SHLOCK : open ${n0} O_RDONLY,O_SHLOCK,O_NONBLOCK
+expect "EWOULDBLOCK|EAGAIN" open ${n0} O_RDONLY,O_EXLOCK : open ${n0} O_RDONLY,O_EXLOCK,O_NONBLOCK
+expect "EWOULDBLOCK|EAGAIN" open ${n0} O_RDONLY,O_SHLOCK : open ${n0} O_RDONLY,O_EXLOCK,O_NONBLOCK
+expect "EWOULDBLOCK|EAGAIN" open ${n0} O_RDONLY,O_EXLOCK : open ${n0} O_RDONLY,O_SHLOCK,O_NONBLOCK
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/open/19.t b/regress/sys/ffs/tests/open/19.t
new file mode 100644
index 00000000000..c25a4f4d78e
--- /dev/null
+++ b/regress/sys/ffs/tests/open/19.t
@@ -0,0 +1,26 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/19.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ENOSPC when O_CREAT is specified, the file does not exist, and there are no free inodes on the file system on which the file is being created"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=256 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+i=0
+while :; do
+ touch ${n0}/${i} >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ break
+ fi
+ i=`expr $i + 1`
+done
+expect ENOSPC open ${n0}/${i} O_RDONLY,O_CREAT 0644
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/open/20.t b/regress/sys/ffs/tests/open/20.t
new file mode 100644
index 00000000000..6313e9cb512
--- /dev/null
+++ b/regress/sys/ffs/tests/open/20.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/20.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns ETXTBSY when the file is a pure procedure (shared text) file that is being executed and the open() system call requests write access"
+
+n0=`namegen`
+
+cp -pf `which sleep` ${n0}
+./${n0} 3 &
+expect ETXTBSY open ${n0} O_WRONLY
+expect ETXTBSY open ${n0} O_RDWR
+expect ETXTBSY open ${n0} O_RDONLY,O_TRUNC
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/open/21.t b/regress/sys/ffs/tests/open/21.t
new file mode 100644
index 00000000000..c7f3b9db8b6
--- /dev/null
+++ b/regress/sys/ffs/tests/open/21.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/21.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT open NULL O_RDONLY
+expect EFAULT open DEADCODE O_RDONLY
diff --git a/regress/sys/ffs/tests/open/22.t b/regress/sys/ffs/tests/open/22.t
new file mode 100644
index 00000000000..80a3763c031
--- /dev/null
+++ b/regress/sys/ffs/tests/open/22.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/22.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EEXIST when O_CREAT and O_EXCL were specified and the file exists"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect EEXIST open ${n0} O_CREAT,O_EXCL 0644
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect EEXIST open ${n0} O_CREAT,O_EXCL 0644
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect EEXIST open ${n0} O_CREAT,O_EXCL 0644
+expect 0 unlink ${n0}
+
+expect 0 symlink test ${n0}
+expect EEXIST open ${n0} O_CREAT,O_EXCL 0644
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/open/23.t b/regress/sys/ffs/tests/open/23.t
new file mode 100644
index 00000000000..7c5c3ab98a8
--- /dev/null
+++ b/regress/sys/ffs/tests/open/23.t
@@ -0,0 +1,11 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/open/23.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="open returns EINVAL when an attempt was made to open a descriptor with an illegal combination of O_RDONLY, O_WRONLY, and O_RDWR"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect EINVAL open ${n0} O_WRONLY,O_RDWR
+expect EINVAL open ${n0} O_RDONLY,O_WRONLY,O_RDWR
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/rename/00.t b/regress/sys/ffs/tests/rename/00.t
new file mode 100644
index 00000000000..e5b342d36f7
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/00.t
@@ -0,0 +1,136 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/00.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename changes file name"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+
+expect 0 mkdir ${n3} 0755
+cdir=`pwd`
+cd ${n3}
+
+expect 0 create ${n0} 0644
+expect regular,0644,1 lstat ${n0} type,mode,nlink
+inode=`${FSTEST} lstat ${n0} inode`
+expect 0 rename ${n0} ${n1}
+expect ENOENT lstat ${n0} type,mode,nlink
+expect regular,${inode},0644,1 lstat ${n1} type,inode,mode,nlink
+expect 0 link ${n1} ${n0}
+expect regular,${inode},0644,2 lstat ${n0} type,inode,mode,nlink
+expect regular,${inode},0644,2 lstat ${n1} type,inode,mode,nlink
+expect 0 rename ${n1} ${n2}
+expect regular,${inode},0644,2 lstat ${n0} type,inode,mode,nlink
+expect ENOENT lstat ${n1} type,mode,nlink
+expect regular,${inode},0644,2 lstat ${n2} type,inode,mode,nlink
+expect 0 unlink ${n0}
+expect 0 unlink ${n2}
+
+expect 0 mkdir ${n0} 0755
+expect dir,0755 lstat ${n0} type,mode
+inode=`${FSTEST} lstat ${n0} inode`
+expect 0 rename ${n0} ${n1}
+expect ENOENT lstat ${n0} type,mode
+expect dir,${inode},0755 lstat ${n1} type,inode,mode
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n0} 0644
+expect fifo,0644,1 lstat ${n0} type,mode,nlink
+inode=`${FSTEST} lstat ${n0} inode`
+expect 0 rename ${n0} ${n1}
+expect ENOENT lstat ${n0} type,mode,nlink
+expect fifo,${inode},0644,1 lstat ${n1} type,inode,mode,nlink
+expect 0 link ${n1} ${n0}
+expect fifo,${inode},0644,2 lstat ${n0} type,inode,mode,nlink
+expect fifo,${inode},0644,2 lstat ${n1} type,inode,mode,nlink
+expect 0 rename ${n1} ${n2}
+expect fifo,${inode},0644,2 lstat ${n0} type,inode,mode,nlink
+expect ENOENT lstat ${n1} type,mode,nlink
+expect fifo,${inode},0644,2 lstat ${n2} type,inode,mode,nlink
+expect 0 unlink ${n0}
+expect 0 unlink ${n2}
+
+expect 0 create ${n0} 0644
+rinode=`${FSTEST} lstat ${n0} inode`
+expect regular,0644 lstat ${n0} type,mode
+expect 0 symlink ${n0} ${n1}
+sinode=`${FSTEST} lstat ${n1} inode`
+expect regular,${rinode},0644 stat ${n1} type,inode,mode
+expect symlink,${sinode} lstat ${n1} type,inode
+expect 0 rename ${n1} ${n2}
+expect regular,${rinode},0644 stat ${n0} type,inode,mode
+expect ENOENT lstat ${n1} type,mode
+expect symlink,${sinode} lstat ${n2} type,inode
+expect 0 unlink ${n0}
+expect 0 unlink ${n2}
+
+# successful rename(2) updates ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 rename ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n1} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n0} 0755
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 rename ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n1} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 rename ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n1} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n0}
+ctime1=`${FSTEST} lstat ${n0} ctime`
+sleep 1
+expect 0 rename ${n0} ${n1}
+ctime2=`${FSTEST} lstat ${n1} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n1}
+
+# unsuccessful link(2) does not update ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EACCES -u 65534 rename ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EACCES -u 65534 rename ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EACCES -u 65534 rename ${n0} ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+expect 0 symlink ${n2} ${n0}
+ctime1=`${FSTEST} lstat ${n0} ctime`
+sleep 1
+expect EACCES -u 65534 rename ${n0} ${n1}
+ctime2=`${FSTEST} lstat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n3}
diff --git a/regress/sys/ffs/tests/rename/01.t b/regress/sys/ffs/tests/rename/01.t
new file mode 100644
index 00000000000..a0abbad5c72
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/01.t
@@ -0,0 +1,16 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/01.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns ENAMETOOLONG if a component of either pathname exceeded 255 characters"
+
+n0=`namegen`
+
+expect 0 create ${name255} 0644
+expect 0 rename ${name255} ${n0}
+expect 0 rename ${n0} ${name255}
+expect 0 unlink ${name255}
+
+expect 0 create ${n0} 0644
+expect ENAMETOOLONG rename ${n0} ${name256}
+expect 0 unlink ${n0}
+expect ENAMETOOLONG rename ${name256} ${n0}
diff --git a/regress/sys/ffs/tests/rename/02.t b/regress/sys/ffs/tests/rename/02.t
new file mode 100644
index 00000000000..5cc8fb48e07
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/02.t
@@ -0,0 +1,21 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/02.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns ENAMETOOLONG if an entire length of either path name exceeded 1023 characters"
+
+n0=`namegen`
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 create ${n0} 0644
+expect 0 rename ${n0} ${path1023}
+expect 0 rename ${path1023} ${n0}
+expect ENAMETOOLONG rename ${n0} ${path1024}
+expect 0 unlink ${n0}
+expect ENAMETOOLONG rename ${path1024} ${n0}
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/rename/03.t b/regress/sys/ffs/tests/rename/03.t
new file mode 100644
index 00000000000..d1abaf50c3f
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/03.t
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/03.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns ENOENT if a component of the 'from' path does not exist, or a path prefix of 'to' does not exist"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT rename ${n0}/${n1}/test ${n2}
+expect 0 create ${n2} 0644
+expect ENOENT rename ${n2} ${n0}/${n1}/test
+expect 0 unlink ${n2}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/04.t b/regress/sys/ffs/tests/rename/04.t
new file mode 100644
index 00000000000..a016e3b8083
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/04.t
@@ -0,0 +1,38 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/04.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EACCES when a component of either path prefix denies search permission"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+n4=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 mkdir ${n2} 0755
+expect 0 chown ${n2} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n3} 0644
+
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n2}/${n4}
+expect 0 -u 65534 -g 65534 rename ${n2}/${n4} ${n1}/${n3}
+
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 rename ${n1}/${n3} ${n1}/${n4}
+expect EACCES -u 65534 -g 65534 rename ${n1}/${n3} ${n2}/${n4}
+
+expect 0 chmod ${n1} 0755
+expect 0 chmod ${n2} 0644
+expect EACCES -u 65534 -g 65534 rename ${n1}/${n3} ${n2}/${n4}
+
+expect 0 unlink ${n1}/${n3}
+expect 0 rmdir ${n1}
+expect 0 rmdir ${n2}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/05.t b/regress/sys/ffs/tests/rename/05.t
new file mode 100644
index 00000000000..79eed15ee50
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/05.t
@@ -0,0 +1,36 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/05.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EACCES when the requested link requires writing in a directory with a mode that denies write permission"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+n4=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 mkdir ${n2} 0755
+expect 0 chown ${n2} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n3} 0644
+
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n2}/${n4}
+expect 0 -u 65534 -g 65534 rename ${n2}/${n4} ${n1}/${n3}
+
+expect 0 chmod ${n2} 0555
+expect EACCES -u 65534 -g 65534 rename ${n1}/${n3} ${n2}/${n4}
+expect 0 chmod ${n1} 0555
+expect EACCES -u 65534 -g 65534 rename ${n1}/${n3} ${n1}/${n4}
+expect 0 chmod ${n1} 0755
+
+expect 0 unlink ${n1}/${n3}
+expect 0 rmdir ${n1}
+expect 0 rmdir ${n2}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/06.t b/regress/sys/ffs/tests/rename/06.t
new file mode 100644
index 00000000000..82524752d1c
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/06.t
@@ -0,0 +1,43 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/06.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EPERM if the file pointed at by the 'from' argument has its immutable, undeletable or append-only flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 create ${n0} 0644
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n0} ${n1}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n0} ${n1}
+done
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}
+
+expect 0 mkfifo ${n0} 0644
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n0} ${n1}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 symlink ${n1} ${n0}
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 lchflags ${n0} ${flag}
+ expect ${flag} lstat ${n0} flags
+ expect EPERM rename ${n0} ${n1}
+done
+expect 0 lchflags ${n0} none
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/rename/07.t b/regress/sys/ffs/tests/rename/07.t
new file mode 100644
index 00000000000..a48fc7b9c7d
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/07.t
@@ -0,0 +1,88 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/07.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EPERM if the parent directory of the file pointed at by the 'from' argument has its immutable or append-only flag set"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 create ${n0}/${n1} 0644
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n0}/${n1} ${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 mkdir ${n0}/${n1} 0755
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n0}/${n1} ${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 mkfifo ${n0}/${n1} 0644
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n0}/${n1} ${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 symlink ${n2} ${n0}/${n1}
+for flag in SF_IMMUTABLE UF_IMMUTABLE SF_APPEND UF_APPEND; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n0}/${n1} ${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 create ${n0}/${n1} 0644
+for flag in SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n0}/${n1} ${n2}
+ expect 0 rename ${n2} ${n0}/${n1}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 mkdir ${n0}/${n1} 0755
+for flag in SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n0}/${n1} ${n2}
+ expect 0 rename ${n2} ${n0}/${n1}
+done
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 mkfifo ${n0}/${n1} 0644
+for flag in SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n0}/${n1} ${n2}
+ expect 0 rename ${n2} ${n0}/${n1}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 symlink ${n2} ${n0}/${n1}
+for flag in SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n0}/${n1} ${n2}
+ expect 0 rename ${n2} ${n0}/${n1}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/08.t b/regress/sys/ffs/tests/rename/08.t
new file mode 100644
index 00000000000..b9d3e29ff04
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/08.t
@@ -0,0 +1,88 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/08.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EPERM if the parent directory of the file pointed at by the 'to' argument has its immutable flag set"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 create ${n1} 0644
+for flag in SF_IMMUTABLE UF_IMMUTABLE; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n1} ${n0}/${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+for flag in SF_IMMUTABLE UF_IMMUTABLE; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n1} ${n0}/${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n1} 0644
+for flag in SF_IMMUTABLE UF_IMMUTABLE; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n1} ${n0}/${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n1}
+for flag in SF_IMMUTABLE UF_IMMUTABLE; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect EPERM rename ${n1} ${n0}/${n2}
+done
+expect 0 chflags ${n0} none
+expect 0 unlink ${n1}
+
+expect 0 create ${n1} 0644
+for flag in SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n1} ${n0}/${n2}
+ expect 0 chflags ${n0} none
+ expect 0 rename ${n0}/${n2} ${n1}
+done
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n1} 0755
+for flag in SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n1} ${n0}/${n2}
+ expect 0 chflags ${n0} none
+ expect 0 rename ${n0}/${n2} ${n1}
+done
+expect 0 rmdir ${n1}
+
+expect 0 mkfifo ${n1} 0644
+for flag in SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n1} ${n0}/${n2}
+ expect 0 chflags ${n0} none
+ expect 0 rename ${n0}/${n2} ${n1}
+done
+expect 0 unlink ${n1}
+
+expect 0 symlink ${n2} ${n1}
+for flag in SF_APPEND UF_APPEND SF_NOUNLINK UF_NOUNLINK; do
+ expect 0 chflags ${n0} ${flag}
+ expect ${flag} stat ${n0} flags
+ expect 0 rename ${n1} ${n0}/${n2}
+ expect 0 chflags ${n0} none
+ expect 0 rename ${n0}/${n2} ${n1}
+done
+expect 0 unlink ${n1}
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/09.t b/regress/sys/ffs/tests/rename/09.t
new file mode 100644
index 00000000000..64437f2482d
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/09.t
@@ -0,0 +1,89 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/09.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EACCES or EPERM if the directory containing 'from' is marked sticky, and neither the containing directory nor 'from' are owned by the effective user ID"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+n4=`namegen`
+
+expect 0 mkdir ${n4} 0755
+cdir=`pwd`
+cd ${n4}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65534
+expect 0 chmod ${n0} 01777
+
+expect 0 mkdir ${n1} 0755
+
+# User owns both: the sticky directory and the file to be renamed.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User owns the file to be renamed, but doesn't own the sticky directory.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65533 -g 65533 create ${n0}/${n2} 0644
+expect 0 -u 65533 -g 65533 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User owns the sticky directory, but doesn't own the file to be renamed.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65533 -g 65533 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User doesn't own the sticky directory nor the file to be renamed.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect "EACCES|EPERM" -u 65533 -g 65533 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n0}/${n2}
+
+# User owns both: the sticky directory and the fifo to be renamed.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User owns the fifo to be renamed, but doesn't own the sticky directory.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65533 -g 65533 mkfifo ${n0}/${n2} 0644
+expect 0 -u 65533 -g 65533 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User owns the sticky directory, but doesn't own the fifo to be renamed.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65533 -g 65533 mkfifo ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User doesn't own the sticky directory nor the fifo to be renamed.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+expect "EACCES|EPERM" -u 65533 -g 65533 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n0}/${n2}
+
+# User owns both: the sticky directory and the symlink to be renamed.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n2}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User owns the symlink to be renamed, but doesn't own the sticky directory.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65533 -g 65533 symlink test ${n0}/${n2}
+expect 0 -u 65533 -g 65533 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User owns the sticky directory, but doesn't own the symlink to be renamed.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65533 -g 65533 symlink test ${n0}/${n2}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n1}/${n3}
+# User doesn't own the sticky directory nor the symlink to be renamed.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n2}
+expect "EACCES|EPERM" -u 65533 -g 65533 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 unlink ${n0}/${n2}
+
+expect 0 rmdir ${n1}
+expect 0 rmdir ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n4}
diff --git a/regress/sys/ffs/tests/rename/10.t b/regress/sys/ffs/tests/rename/10.t
new file mode 100644
index 00000000000..d429381f594
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/10.t
@@ -0,0 +1,238 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/10.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EACCES or EPERM if the file pointed at by the 'to' argument exists, the directory containing 'to' is marked sticky, and neither the containing directory nor 'to' are owned by the effective user ID"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+n3=`namegen`
+n4=`namegen`
+
+expect 0 mkdir ${n4} 0755
+cdir=`pwd`
+cd ${n4}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65534
+
+expect 0 mkdir ${n1} 0755
+expect 0 chmod ${n1} 01777
+
+# User owns both: the sticky directory and the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 create ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User owns the sticky directory, but doesn't own the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 create ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User owns the destination file, but doesn't own the sticky directory.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 create ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User doesn't own the sticky directory nor the destination file.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65533 -g 65533 create ${n1}/${n3} 0644
+inode=`${FSTEST} lstat ${n1}/${n3} inode`
+expect "EACCES|EPERM" -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n0}/${n2}
+expect 0 unlink ${n1}/${n3}
+
+# User owns both: the sticky directory and the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkdir ${n0}/${n2} 0755
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n3} 0755
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect 0 rmdir ${n1}/${n3}
+# User owns the sticky directory, but doesn't own the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkdir ${n0}/${n2} 0755
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n3} 0755
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect 0 rmdir ${n1}/${n3}
+# User owns the destination file, but doesn't own the sticky directory.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 mkdir ${n0}/${n2} 0755
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n3} 0755
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect 0 rmdir ${n1}/${n3}
+# User doesn't own the sticky directory nor the destination file.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 mkdir ${n0}/${n2} 0755
+expect 0 -u 65533 -g 65533 mkdir ${n1}/${n3} 0755
+expect "EACCES|EPERM" -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect 0 rmdir ${n0}/${n2}
+expect 0 rmdir ${n1}/${n3}
+
+# User owns both: the sticky directory and the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User owns the sticky directory, but doesn't own the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User owns the destination file, but doesn't own the sticky directory.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User doesn't own the sticky directory nor the destination file.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n2} 0644
+expect 0 -u 65533 -g 65533 mkfifo ${n1}/${n3} 0644
+inode=`${FSTEST} lstat ${n1}/${n3} inode`
+expect "EACCES|EPERM" -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n0}/${n2}
+expect 0 unlink ${n1}/${n3}
+
+# User owns both: the sticky directory and the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n2}
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User owns the sticky directory, but doesn't own the destination file.
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n2}
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User owns the destination file, but doesn't own the sticky directory.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n2}
+inode=`${FSTEST} lstat ${n0}/${n2} inode`
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n3}
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} type
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 create ${n0}/${n2} 0644
+expect 0 -u 65534 -g 65534 rename ${n1}/${n3} ${n0}/${n2}
+expect ${inode} lstat ${n0}/${n2} inode
+expect ENOENT lstat ${n1}/${n3} inode
+expect 0 -u 65534 -g 65534 mkfifo ${n1}/${n3} 0644
+expect 0 -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ENOENT lstat ${n0}/${n2} inode
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n1}/${n3}
+# User doesn't own the sticky directory nor the destination file.
+expect 0 chown ${n1} 65533 65533
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n2}
+expect 0 -u 65533 -g 65533 symlink test ${n1}/${n3}
+inode=`${FSTEST} lstat ${n1}/${n3} inode`
+expect "EACCES|EPERM" -u 65534 -g 65534 rename ${n0}/${n2} ${n1}/${n3}
+expect ${inode} lstat ${n1}/${n3} inode
+expect 0 unlink ${n0}/${n2}
+expect 0 unlink ${n1}/${n3}
+
+expect 0 rmdir ${n1}
+expect 0 rmdir ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n4}
diff --git a/regress/sys/ffs/tests/rename/11.t b/regress/sys/ffs/tests/rename/11.t
new file mode 100644
index 00000000000..d40f08de68e
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/11.t
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/11.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns ELOOP if too many symbolic links were encountered in translating one of the pathnames"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP rename ${n0}/test ${n2}
+expect ELOOP rename ${n1}/test ${n2}
+expect 0 create ${n2} 0644
+expect ELOOP rename ${n2} ${n0}/test
+expect ELOOP rename ${n2} ${n1}/test
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
+expect 0 unlink ${n2}
diff --git a/regress/sys/ffs/tests/rename/12.t b/regress/sys/ffs/tests/rename/12.t
new file mode 100644
index 00000000000..95d63df17c4
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/12.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/12.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns ENOTDIR if a component of either path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR rename ${n0}/${n1}/test ${n0}/${n2}
+expect 0 create ${n0}/${n2} 0644
+expect ENOTDIR link ${n0}/${n2} ${n0}/${n1}/test
+expect 0 unlink ${n0}/${n1}
+expect 0 unlink ${n0}/${n2}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/13.t b/regress/sys/ffs/tests/rename/13.t
new file mode 100644
index 00000000000..de50c8bdde2
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/13.t
@@ -0,0 +1,29 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/13.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns ENOTDIR when the 'from' argument is a directory, but 'to' is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 create ${n1} 0644
+expect ENOTDIR rename ${n0} ${n1}
+expect dir lstat ${n0} type
+expect regular lstat ${n1} type
+expect 0 unlink ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect ENOTDIR rename ${n0} ${n1}
+expect dir lstat ${n0} type
+expect fifo lstat ${n1} type
+expect 0 unlink ${n1}
+
+expect 0 symlink test ${n1}
+expect ENOTDIR rename ${n0} ${n1}
+expect dir lstat ${n0} type
+expect symlink lstat ${n1} type
+expect 0 unlink ${n1}
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/14.t b/regress/sys/ffs/tests/rename/14.t
new file mode 100644
index 00000000000..d0b3a0d14d1
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/14.t
@@ -0,0 +1,29 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/14.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EISDIR when the 'to' argument is a directory, but 'from' is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 create ${n1} 0644
+expect EISDIR rename ${n1} ${n0}
+expect dir lstat ${n0} type
+expect regular lstat ${n1} type
+expect 0 unlink ${n1}
+
+expect 0 mkfifo ${n1} 0644
+expect EISDIR rename ${n1} ${n0}
+expect dir lstat ${n0} type
+expect fifo lstat ${n1} type
+expect 0 unlink ${n1}
+
+expect 0 symlink test ${n1}
+expect EISDIR rename ${n1} ${n0}
+expect dir lstat ${n0} type
+expect symlink lstat ${n1} type
+expect 0 unlink ${n1}
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/15.t b/regress/sys/ffs/tests/rename/15.t
new file mode 100644
index 00000000000..2bca8bc2c63
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/15.t
@@ -0,0 +1,35 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/15.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EXDEV if the link named by 'to' and the file named by 'from' are on different file systems"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+
+expect 0 create ${n0}/${n1} 0644
+expect EXDEV rename ${n0}/${n1} ${n2}
+expect 0 unlink ${n0}/${n1}
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect EXDEV rename ${n0}/${n1} ${n2}
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 mkfifo ${n0}/${n1} 0644
+expect EXDEV rename ${n0}/${n1} ${n2}
+expect 0 unlink ${n0}/${n1}
+
+expect 0 symlink test ${n0}/${n1}
+expect EXDEV rename ${n0}/${n1} ${n2}
+expect 0 unlink ${n0}/${n1}
+
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/16.t b/regress/sys/ffs/tests/rename/16.t
new file mode 100644
index 00000000000..41a653bce50
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/16.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/16.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EROFS if the requested link requires writing in a directory on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+mount -ur /dev/svnd1c
+
+expect EROFS rename ${n0}/${n1} ${n0}/${n2}
+expect EROFS rename ${n0}/${n1} ${n2}
+expect 0 create ${n2} 0644
+expect EROFS rename ${n2} ${n0}/${n2}
+expect 0 unlink ${n2}
+
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/17.t b/regress/sys/ffs/tests/rename/17.t
new file mode 100644
index 00000000000..287a6095437
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/17.t
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/17.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EFAULT if one of the pathnames specified is outside the process's allocated address space"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect EFAULT rename ${n0} NULL
+expect EFAULT rename ${n0} DEADCODE
+expect 0 unlink ${n0}
+expect EFAULT rename NULL ${n0}
+expect EFAULT rename DEADCODE ${n0}
+expect EFAULT rename NULL DEADCODE
+expect EFAULT rename DEADCODE NULL
diff --git a/regress/sys/ffs/tests/rename/18.t b/regress/sys/ffs/tests/rename/18.t
new file mode 100644
index 00000000000..2a5f4a68166
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/18.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/18.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EINVAL when the 'from' argument is a parent directory of 'to'"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkdir ${n0}/${n1} 0755
+
+expect EINVAL rename ${n0} ${n0}/${n1}
+expect EINVAL rename ${n0} ${n0}/${n1}/${n2}
+
+expect 0 rmdir ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/19.t b/regress/sys/ffs/tests/rename/19.t
new file mode 100644
index 00000000000..2dde8ab16ff
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/19.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/19.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EINVAL when an attempt is made to rename '.' or '..'"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkdir ${n0}/${n1} 0755
+
+expect EINVAL rename ${n0}/${n1}/. ${n2}
+expect EINVAL rename ${n0}/${n1}/.. ${n2}
+
+expect 0 rmdir ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rename/20.t b/regress/sys/ffs/tests/rename/20.t
new file mode 100644
index 00000000000..3c9eaf02c7b
--- /dev/null
+++ b/regress/sys/ffs/tests/rename/20.t
@@ -0,0 +1,30 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rename/20.t,v 1.1 2007/01/17 01:42:10 pjd Exp $
+
+desc="rename returns EEXIST or ENOTEMPTY if the 'to' argument is a directory and is not empty"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkdir ${n1} 0755
+
+expect 0 create ${n1}/${n2} 0644
+expect "EEXIST|ENOTEMPTY" rename ${n0} ${n1}
+expect 0 unlink ${n1}/${n2}
+
+expect 0 mkdir ${n1}/${n2} 0755
+expect "EEXIST|ENOTEMPTY" rename ${n0} ${n1}
+expect 0 rmdir ${n1}/${n2}
+
+expect 0 mkfifo ${n1}/${n2} 0644
+expect "EEXIST|ENOTEMPTY" rename ${n0} ${n1}
+expect 0 unlink ${n1}/${n2}
+
+expect 0 symlink test ${n1}/${n2}
+expect "EEXIST|ENOTEMPTY" rename ${n0} ${n1}
+expect 0 unlink ${n1}/${n2}
+
+expect 0 rmdir ${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/00.t b/regress/sys/ffs/tests/rmdir/00.t
new file mode 100644
index 00000000000..6086173f175
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/00.t
@@ -0,0 +1,23 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/00.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir removes directories"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect dir lstat ${n0} type
+expect 0 rmdir ${n0}
+expect ENOENT lstat ${n0} type
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkdir ${n0}/${n1} 0755
+time=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 rmdir ${n0}/${n1}
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/01.t b/regress/sys/ffs/tests/rmdir/01.t
new file mode 100644
index 00000000000..cd98094a39b
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/01.t
@@ -0,0 +1,25 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/01.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns ENOTDIR if a component of the path is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR rmdir ${n0}/${n1}/test
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
+
+expect 0 create ${n0} 0644
+expect ENOTDIR rmdir ${n0}
+expect 0 unlink ${n0}
+
+expect 0 symlink ${n1} ${n0}
+expect ENOTDIR rmdir ${n0}
+expect 0 unlink ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect ENOTDIR rmdir ${n0}
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/02.t b/regress/sys/ffs/tests/rmdir/02.t
new file mode 100644
index 00000000000..cc184e5da3b
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/02.t
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/02.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 rmdir ${name255}
+expect ENOENT rmdir ${name255}
+expect ENAMETOOLONG rmdir ${name256}
diff --git a/regress/sys/ffs/tests/rmdir/03.t b/regress/sys/ffs/tests/rmdir/03.t
new file mode 100644
index 00000000000..c311fbf5b12
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/03.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/03.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 mkdir ${path1023} 0755
+expect 0 rmdir ${path1023}
+expect ENOENT rmdir ${path1023}
+expect ENAMETOOLONG rmdir ${path1024}
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/rmdir/04.t b/regress/sys/ffs/tests/rmdir/04.t
new file mode 100644
index 00000000000..0f5baa2ba05
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/04.t
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/04.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns ENOENT if the named directory does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 rmdir ${n0}
+expect ENOENT rmdir ${n0}
+expect ENOENT rmdir ${n1}
diff --git a/regress/sys/ffs/tests/rmdir/05.t b/regress/sys/ffs/tests/rmdir/05.t
new file mode 100644
index 00000000000..120e3cc48f3
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/05.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/05.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP rmdir ${n0}/test
+expect ELOOP rmdir ${n1}/test
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/rmdir/06.t b/regress/sys/ffs/tests/rmdir/06.t
new file mode 100644
index 00000000000..ce3313f3e7c
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/06.t
@@ -0,0 +1,31 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/06.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EEXIST or ENOTEMPTY the named directory contains files other than '.' and '..' in it"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkdir ${n0}/${n1} 0755
+expect "EEXIST|ENOTEMPTY" rmdir ${n0}
+expect 0 rmdir ${n0}/${n1}
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect "EEXIST|ENOTEMPTY" rmdir ${n0}
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 symlink test ${n0}/${n1}
+expect "EEXIST|ENOTEMPTY" rmdir ${n0}
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkfifo ${n0}/${n1} 0644
+expect "EEXIST|ENOTEMPTY" rmdir ${n0}
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/07.t b/regress/sys/ffs/tests/rmdir/07.t
new file mode 100644
index 00000000000..8e99d13eebd
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/07.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/07.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/08.t b/regress/sys/ffs/tests/rmdir/08.t
new file mode 100644
index 00000000000..c60c44b16fa
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/08.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/08.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EACCES when write permission is denied on the directory containing the link to be removed"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 mkdir ${n1}/${n2} 0755
+expect 0 chmod ${n1} 0555
+expect EACCES -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/09.t b/regress/sys/ffs/tests/rmdir/09.t
new file mode 100644
index 00000000000..93e00085cb8
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/09.t
@@ -0,0 +1,42 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/09.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EPERM if the named file has its immutable, undeletable or append-only flag set"
+
+n0=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM rmdir ${n0}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM rmdir ${n0}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chflags ${n0} SF_NOUNLINK
+expect EPERM rmdir ${n0}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chflags ${n0} UF_NOUNLINK
+expect EPERM rmdir ${n0}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM rmdir ${n0}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM rmdir ${n0}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/10.t b/regress/sys/ffs/tests/rmdir/10.t
new file mode 100644
index 00000000000..7e51a85c37e
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/10.t
@@ -0,0 +1,45 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/10.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EPERM if the parent directory of the named file has its immutable or append-only flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 mkdir ${n0}/${n1} 0755
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 rmdir ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/11.t b/regress/sys/ffs/tests/rmdir/11.t
new file mode 100644
index 00000000000..7869a79c17e
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/11.t
@@ -0,0 +1,35 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/11.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EACCES or EPERM if the directory containing the directory to be removed is marked sticky, and neither the containing directory nor the directory to be removed are owned by the effective user ID"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n2} 0755
+cdir=`pwd`
+cd ${n2}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65534
+expect 0 chmod ${n0} 01777
+
+# User owns both: the sticky directory and the directory to be removed.
+expect 0 -u 65534 -g 65534 mkdir ${n0}/${n1} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n0}/${n1}
+# User owns the directory to be removed, but doesn't own the sticky directory.
+expect 0 -u 65533 -g 65533 mkdir ${n0}/${n1} 0755
+expect 0 -u 65533 -g 65533 rmdir ${n0}/${n1}
+# User owns the sticky directory, but doesn't own the directory to be removed.
+expect 0 -u 65533 -g 65533 mkdir ${n0}/${n1} 0755
+expect 0 -u 65534 -g 65534 rmdir ${n0}/${n1}
+# User doesn't own the sticky directory nor the directory to be removed.
+expect 0 -u 65534 -g 65534 mkdir ${n0}/${n1} 0755
+expect "EACCES|EPERM" -u 65533 -g 65533 rmdir ${n0}/${n1}
+expect 0 rmdir ${n0}/${n1}
+
+expect 0 rmdir ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n2}
diff --git a/regress/sys/ffs/tests/rmdir/12.t b/regress/sys/ffs/tests/rmdir/12.t
new file mode 100644
index 00000000000..a3fb0a87e09
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/12.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/12.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EINVAL if the last component of the path is '.' or '..'"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkdir ${n0}/${n1} 0755
+expect EINVAL rmdir ${n0}/${n1}/.
+expect EINVAL rmdir ${n0}/${n1}/..
+expect 0 rmdir ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/13.t b/regress/sys/ffs/tests/rmdir/13.t
new file mode 100644
index 00000000000..64c475dae28
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/13.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/13.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EBUSY if the directory to be removed is the mount point for a mounted file system"
+
+n0=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect EBUSY rmdir ${n0}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/14.t b/regress/sys/ffs/tests/rmdir/14.t
new file mode 100644
index 00000000000..d9d6703965b
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/14.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/14.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 mkdir ${n0}/${n1} 0755
+mount -ur /dev/svnd1c
+expect EROFS rmdir ${n0}/${n1}
+mount -uw /dev/svnd1c
+expect 0 rmdir ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/rmdir/15.t b/regress/sys/ffs/tests/rmdir/15.t
new file mode 100644
index 00000000000..1b719e977a4
--- /dev/null
+++ b/regress/sys/ffs/tests/rmdir/15.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/rmdir/15.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="rmdir returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT rmdir NULL
+expect EFAULT rmdir DEADCODE
diff --git a/regress/sys/ffs/tests/symlink/00.t b/regress/sys/ffs/tests/symlink/00.t
new file mode 100644
index 00000000000..51ac0e47778
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/00.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/00.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink creates symbolic links"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 create ${n0} 0644
+expect regular,0644 lstat ${n0} type,mode
+expect 0 symlink ${n0} ${n1}
+expect symlink lstat ${n1} type
+expect regular,0644 stat ${n1} type,mode
+expect 0 unlink ${n0}
+expect ENOENT stat ${n1} type,mode
+expect 0 unlink ${n1}
+
+expect 0 mkdir ${n0} 0755
+time=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 symlink test ${n0}/${n1}
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/01.t b/regress/sys/ffs/tests/symlink/01.t
new file mode 100644
index 00000000000..8a3c0727f7c
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/01.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns ENOTDIR if a component of the name2 path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR symlink test ${n0}/${n1}/test
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/02.t b/regress/sys/ffs/tests/symlink/02.t
new file mode 100644
index 00000000000..0c79c29099b
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/02.t
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/02.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns ENAMETOOLONG if a component of the name2 pathname exceeded 255 characters"
+
+n0=`namegen`
+
+expect 0 symlink ${name255} ${n0}
+expect 0 unlink ${n0}
+expect 0 symlink ${n0} ${name255}
+expect 0 unlink ${name255}
+
+expect ENAMETOOLONG symlink ${n0} ${name256}
+expect 0 symlink ${name256} ${n0}
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/symlink/03.t b/regress/sys/ffs/tests/symlink/03.t
new file mode 100644
index 00000000000..341eb66b115
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/03.t
@@ -0,0 +1,21 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/03.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns ENAMETOOLONG if an entire length of either path name exceeded 1023 characters"
+
+n0=`namegen`
+
+expect 0 symlink ${path1023} ${n0}
+expect 0 unlink ${n0}
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 symlink ${n0} ${path1023}
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG symlink ${n0} ${path1024}
+expect ENAMETOOLONG symlink ${path1024} ${n0}
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/symlink/04.t b/regress/sys/ffs/tests/symlink/04.t
new file mode 100644
index 00000000000..c8ca3ba5327
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/04.t
@@ -0,0 +1,11 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/04.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns ENOENT if a component of the name2 path prefix does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT symlink test ${n0}/${n1}/test
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/05.t b/regress/sys/ffs/tests/symlink/05.t
new file mode 100644
index 00000000000..b3cfd61698c
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/05.t
@@ -0,0 +1,29 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/05.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns EACCES when a component of the name2 path prefix denies search permission"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n2}
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 symlink test ${n1}/${n2}
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n2}
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+
+expect 0 rmdir ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/06.t b/regress/sys/ffs/tests/symlink/06.t
new file mode 100644
index 00000000000..e3393645be6
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/06.t
@@ -0,0 +1,29 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/06.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns EACCES if the parent directory of the file to be created denies write permission"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n2}
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+
+expect 0 chmod ${n1} 0555
+expect EACCES -u 65534 -g 65534 symlink test ${n1}/${n2}
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 symlink test ${n1}/${n2}
+expect 0 unlink ${n1}/${n2}
+
+expect 0 rmdir ${n1}
+
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/07.t b/regress/sys/ffs/tests/symlink/07.t
new file mode 100644
index 00000000000..1c72c4b176d
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/07.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/07.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns ELOOP if too many symbolic links were encountered in translating the name2 path name"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP symlink test ${n0}/test
+expect ELOOP symlink test ${n1}/test
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/symlink/08.t b/regress/sys/ffs/tests/symlink/08.t
new file mode 100644
index 00000000000..98128a12b5d
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/08.t
@@ -0,0 +1,18 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/08.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns EEXIST if the name2 argument already exists"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect EEXIST symlink test ${n0}
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect EEXIST symlink test ${n0}
+expect 0 rmdir ${n0}
+
+expect 0 symlink test ${n0}
+expect EEXIST symlink test ${n0}
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/symlink/09.t b/regress/sys/ffs/tests/symlink/09.t
new file mode 100644
index 00000000000..9cc96ad2c1e
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/09.t
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/09.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns EPERM if the parent directory of the file named by name2 has its immutable flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 symlink test ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM symlink test ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 symlink test ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM symlink test ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 symlink test ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_APPEND
+expect 0 symlink test ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_APPEND
+expect 0 symlink test ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 symlink test ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 symlink test ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/10.t b/regress/sys/ffs/tests/symlink/10.t
new file mode 100644
index 00000000000..c9230802f5d
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/10.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/10.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns EROFS if the file name2 would reside on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+
+expect 0 symlink test ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+mount -ur /dev/svnd1c
+expect EROFS symlink test ${n0}/${n1}
+mount -uw /dev/svnd1c
+expect 0 symlink test ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/11.t b/regress/sys/ffs/tests/symlink/11.t
new file mode 100644
index 00000000000..27c26401f2d
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/11.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/11.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns ENOSPC if there are no free inodes on the file system on which the symbolic link is being created"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=256 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+
+i=0
+while :; do
+ ln -s test ${n0}/${i} >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ break
+ fi
+ i=`expr $i + 1`
+done
+expect ENOSPC symlink test ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/symlink/12.t b/regress/sys/ffs/tests/symlink/12.t
new file mode 100644
index 00000000000..a5468c83d65
--- /dev/null
+++ b/regress/sys/ffs/tests/symlink/12.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/symlink/12.t,v 1.1 2007/01/17 01:42:11 pjd Exp $
+
+desc="symlink returns EFAULT if one of the pathnames specified is outside the process's allocated address space"
+
+n0=`namegen`
+
+expect EFAULT symlink NULL ${n0}
+expect EFAULT symlink DEADCODE ${n0}
+expect EFAULT symlink test NULL
+expect EFAULT symlink test DEADCODE
+expect EFAULT symlink NULL DEADCODE
+expect EFAULT symlink DEADCODE NULL
diff --git a/regress/sys/ffs/tests/truncate/00.t b/regress/sys/ffs/tests/truncate/00.t
new file mode 100644
index 00000000000..295ec7b9158
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/00.t
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/00.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate descrease/increase file size"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n1} 0755
+cdir=`pwd`
+cd ${n1}
+
+expect 0 create ${n0} 0644
+expect 0 truncate ${n0} 1234567
+expect 1234567 lstat ${n0} size
+expect 0 truncate ${n0} 567
+expect 567 lstat ${n0} size
+expect 0 unlink ${n0}
+
+dd if=/dev/random of=${n0} bs=12345 count=1 >/dev/null 2>&1
+expect 0 truncate ${n0} 23456
+expect 23456 lstat ${n0} size
+expect 0 truncate ${n0} 1
+expect 1 lstat ${n0} size
+expect 0 unlink ${n0}
+
+# successful truncate(2) updates ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 truncate ${n0} 123
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+
+# unsuccessful truncate(2) does not update ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EACCES -u 65534 truncate ${n0} 123
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n1}
diff --git a/regress/sys/ffs/tests/truncate/01.t b/regress/sys/ffs/tests/truncate/01.t
new file mode 100644
index 00000000000..d70cd3fd931
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/01.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR truncate ${n0}/${n1}/test 123
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/truncate/02.t b/regress/sys/ffs/tests/truncate/02.t
new file mode 100644
index 00000000000..65adbb546fa
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/02.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/02.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 create ${name255} 0644
+expect 0 truncate ${name255} 123
+expect 123 stat ${name255} size
+expect 0 unlink ${name255}
+expect ENAMETOOLONG truncate ${name256} 123
diff --git a/regress/sys/ffs/tests/truncate/03.t b/regress/sys/ffs/tests/truncate/03.t
new file mode 100644
index 00000000000..c61ca57a34a
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/03.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/03.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 create ${path1023} 0644
+expect 0 truncate ${path1023} 123
+expect 0 unlink ${path1023}
+expect ENAMETOOLONG truncate ${path1024} 123
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/truncate/04.t b/regress/sys/ffs/tests/truncate/04.t
new file mode 100644
index 00000000000..5ab0a1e664d
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/04.t
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/04.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns ENOENT if the named file does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect ENOENT truncate ${n0}/${n1}/test 123
+expect ENOENT truncate ${n0}/${n1} 123
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/truncate/05.t b/regress/sys/ffs/tests/truncate/05.t
new file mode 100644
index 00000000000..e0134729e79
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/05.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/05.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 -u 65534 -g 65534 truncate ${n1}/${n2} 123
+expect 123 -u 65534 -g 65534 stat ${n1}/${n2} size
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 truncate ${n1}/${n2} 1234
+expect 0 chmod ${n1} 0755
+expect 123 -u 65534 -g 65534 stat ${n1}/${n2} size
+expect 0 -u 65534 -g 65534 truncate ${n1}/${n2} 1234
+expect 1234 -u 65534 -g 65534 stat ${n1}/${n2} size
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/truncate/06.t b/regress/sys/ffs/tests/truncate/06.t
new file mode 100644
index 00000000000..d7a3eda2816
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/06.t
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/06.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EACCES if the named file is not writable by the user"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 create ${n1} 0644
+expect EACCES -u 65534 -g 65534 truncate ${n1} 123
+expect 0 chown ${n1} 65534 65534
+expect 0 chmod ${n1} 0444
+expect EACCES -u 65534 -g 65534 truncate ${n1} 123
+expect 0 unlink ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/truncate/07.t b/regress/sys/ffs/tests/truncate/07.t
new file mode 100644
index 00000000000..98c70a0ef58
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/07.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/07.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP truncate ${n0}/test 123
+expect ELOOP truncate ${n1}/test 123
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/truncate/08.t b/regress/sys/ffs/tests/truncate/08.t
new file mode 100644
index 00000000000..48ab6a843d8
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/08.t
@@ -0,0 +1,52 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/08.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EPERM if the named file has its immutable or append-only flag set"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM truncate ${n0} 123
+expect 0 stat ${n0} size
+expect 0 chflags ${n0} none
+expect 0 truncate ${n0} 123
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM truncate ${n0} 123
+expect 0 stat ${n0} size
+expect 0 chflags ${n0} none
+expect 0 truncate ${n0} 123
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM truncate ${n0} 123
+expect 0 stat ${n0} size
+expect 0 chflags ${n0} none
+expect 0 truncate ${n0} 123
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM truncate ${n0} 123
+expect 0 stat ${n0} size
+expect 0 chflags ${n0} none
+expect 0 truncate ${n0} 123
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 truncate ${n0} 123
+expect 123 stat ${n0} size
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 truncate ${n0} 123
+expect 123 stat ${n0} size
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/truncate/09.t b/regress/sys/ffs/tests/truncate/09.t
new file mode 100644
index 00000000000..897ab0a575a
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/09.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/09.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EISDIR if the named file is a directory"
+
+n0=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect EISDIR truncate ${n0} 123
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/truncate/10.t b/regress/sys/ffs/tests/truncate/10.t
new file mode 100644
index 00000000000..5479cefde7c
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/10.t
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/10.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+expect 0 truncate ${n0}/${n1} 123
+expect 123 stat ${n0}/${n1} size
+mount -ur /dev/svnd1c
+expect EROFS truncate ${n0}/${n1} 1234
+expect 123 stat ${n0}/${n1} size
+mount -uw /dev/svnd1c
+expect 0 truncate ${n0}/${n1} 1234
+expect 1234 stat ${n0}/${n1} size
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/truncate/11.t b/regress/sys/ffs/tests/truncate/11.t
new file mode 100644
index 00000000000..87b339db538
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/11.t
@@ -0,0 +1,11 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/11.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns ETXTBSY the file is a pure procedure (shared text) file that is being executed"
+
+n0=`namegen`
+
+cp -pf `which sleep` ${n0}
+./${n0} 3 &
+expect ETXTBSY truncate ${n0} 123
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/truncate/12.t b/regress/sys/ffs/tests/truncate/12.t
new file mode 100644
index 00000000000..c3786f1719d
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/12.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/12.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EFBIG or EINVAL if the length argument was greater than the maximum file size"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+r=`${FSTEST} truncate ${n0} 999999999999999 2>/dev/null`
+case "${r}" in
+EFBIG|EINVAL)
+ expect 0 stat ${n0} size
+ ;;
+0)
+ expect 999999999999999 stat ${n0} size
+ ;;
+*)
+ echo "not ok ${ntest}"
+ ntest=`expr ${ntest} + 1`
+ ;;
+esac
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/truncate/13.t b/regress/sys/ffs/tests/truncate/13.t
new file mode 100644
index 00000000000..30c63cf5ac7
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/13.t
@@ -0,0 +1,11 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/13.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EINVAL if the length argument was less than 0"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect EINVAL truncate ${n0} -1
+expect EINVAL truncate ${n0} -999999
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/truncate/14.t b/regress/sys/ffs/tests/truncate/14.t
new file mode 100644
index 00000000000..84723d2d211
--- /dev/null
+++ b/regress/sys/ffs/tests/truncate/14.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/truncate/14.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="truncate returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT truncate NULL 123
+expect EFAULT truncate DEADCODE 123
diff --git a/regress/sys/ffs/tests/unlink/00.t b/regress/sys/ffs/tests/unlink/00.t
new file mode 100644
index 00000000000..e09922f7251
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/00.t
@@ -0,0 +1,110 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/00.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink removes regular files, symbolic links, fifos and sockets"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n2} 0755
+cdir=`pwd`
+cd ${n2}
+
+expect 0 create ${n0} 0644
+expect regular lstat ${n0} type
+expect 0 unlink ${n0}
+expect ENOENT lstat ${n0} type
+
+expect 0 symlink ${n1} ${n0}
+expect symlink lstat ${n0} type
+expect 0 unlink ${n0}
+expect ENOENT lstat ${n0} type
+
+expect 0 mkfifo ${n0} 0644
+expect fifo lstat ${n0} type
+expect 0 unlink ${n0}
+expect ENOENT lstat ${n0} type
+
+# TODO: sockets removal
+
+# successful unlink(2) updates ctime.
+expect 0 create ${n0} 0644
+expect 0 link ${n0} ${n1}
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 unlink ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+
+expect 0 mkfifo ${n0} 0644
+expect 0 link ${n0} ${n1}
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 unlink ${n1}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -lt $ctime2
+expect 0 unlink ${n0}
+
+# unsuccessful unlink(2) does not update ctime.
+expect 0 create ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EACCES -u 65534 unlink ${n0}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+expect 0 mkfifo ${n0} 0644
+ctime1=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect EACCES -u 65534 unlink ${n0}
+ctime2=`${FSTEST} stat ${n0} ctime`
+test_check $ctime1 -eq $ctime2
+expect 0 unlink ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+time=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 unlink ${n0}/${n1}
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 mkfifo ${n0}/${n1} 0644
+time=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 unlink ${n0}/${n1}
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+expect 0 rmdir ${n0}
+
+expect 0 mkdir ${n0} 0755
+expect 0 symlink test ${n0}/${n1}
+time=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 unlink ${n0}/${n1}
+mtime=`${FSTEST} stat ${n0} mtime`
+test_check $time -lt $mtime
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+expect 0 rmdir ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 link ${n0} ${n1}
+time=`${FSTEST} stat ${n0} ctime`
+sleep 1
+expect 0 unlink ${n1}
+ctime=`${FSTEST} stat ${n0} ctime`
+test_check $time -lt $ctime
+expect 0 unlink ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n2}
diff --git a/regress/sys/ffs/tests/unlink/01.t b/regress/sys/ffs/tests/unlink/01.t
new file mode 100644
index 00000000000..3cf7219b8d8
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/01.t
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/01.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns ENOTDIR if a component of the path prefix is not a directory"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect 0 create ${n0}/${n1} 0644
+expect ENOTDIR unlink ${n0}/${n1}/test
+expect 0 unlink ${n0}/${n1}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/unlink/02.t b/regress/sys/ffs/tests/unlink/02.t
new file mode 100644
index 00000000000..6f2fe41f08c
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/02.t
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/02.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns ENAMETOOLONG if a component of a pathname exceeded 255 characters"
+
+expect 0 create ${name255} 0644
+expect 0 unlink ${name255}
+expect ENOENT unlink ${name255}
+expect ENAMETOOLONG unlink ${name256}
diff --git a/regress/sys/ffs/tests/unlink/03.t b/regress/sys/ffs/tests/unlink/03.t
new file mode 100644
index 00000000000..3e791a6cb1c
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/03.t
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/03.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns ENAMETOOLONG if an entire path name exceeded 1023 characters"
+
+expect 0 mkdir ${name255} 0755
+expect 0 mkdir ${name255}/${name255} 0755
+expect 0 mkdir ${name255}/${name255}/${name255} 0755
+expect 0 mkdir ${path1021} 0755
+expect 0 create ${path1023} 0644
+expect 0 unlink ${path1023}
+expect ENOENT unlink ${path1023}
+expect ENAMETOOLONG unlink ${path1024}
+expect 0 rmdir ${path1021}
+expect 0 rmdir ${name255}/${name255}/${name255}
+expect 0 rmdir ${name255}/${name255}
+expect 0 rmdir ${name255}
diff --git a/regress/sys/ffs/tests/unlink/04.t b/regress/sys/ffs/tests/unlink/04.t
new file mode 100644
index 00000000000..3854264a68d
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/04.t
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/04.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns ENOENT if the named file does not exist"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 unlink ${n0}
+expect ENOENT unlink ${n0}
+expect ENOENT unlink ${n1}
diff --git a/regress/sys/ffs/tests/unlink/05.t b/regress/sys/ffs/tests/unlink/05.t
new file mode 100644
index 00000000000..c81cfffdd0d
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/05.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/05.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EACCES when search permission is denied for a component of the path prefix"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 chmod ${n1} 0644
+expect EACCES -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/unlink/06.t b/regress/sys/ffs/tests/unlink/06.t
new file mode 100644
index 00000000000..9d0b3c9e331
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/06.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/06.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EACCES when write permission is denied on the directory containing the link to be removed"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n0} 0755
+cdir=`pwd`
+cd ${n0}
+expect 0 mkdir ${n1} 0755
+expect 0 chown ${n1} 65534 65534
+expect 0 -u 65534 -g 65534 create ${n1}/${n2} 0644
+expect 0 chmod ${n1} 0555
+expect EACCES -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 chmod ${n1} 0755
+expect 0 -u 65534 -g 65534 unlink ${n1}/${n2}
+expect 0 rmdir ${n1}
+cd ${cdir}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/unlink/07.t b/regress/sys/ffs/tests/unlink/07.t
new file mode 100644
index 00000000000..050da586078
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/07.t
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/07.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns ELOOP if too many symbolic links were encountered in translating the pathname"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 symlink ${n0} ${n1}
+expect 0 symlink ${n1} ${n0}
+expect ELOOP unlink ${n0}/test
+expect ELOOP unlink ${n1}/test
+expect 0 unlink ${n0}
+expect 0 unlink ${n1}
diff --git a/regress/sys/ffs/tests/unlink/08.t b/regress/sys/ffs/tests/unlink/08.t
new file mode 100644
index 00000000000..f684f5b2315
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/08.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/08.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EPERM if the named file is a directory"
+
+n0=`namegen`
+
+expect 0 mkdir ${n0} 0755
+expect EPERM unlink ${n0}
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/unlink/09.t b/regress/sys/ffs/tests/unlink/09.t
new file mode 100644
index 00000000000..f5a5a24d599
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/09.t
@@ -0,0 +1,42 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/09.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EPERM if the named file has its immutable, undeletable or append-only flag set"
+
+n0=`namegen`
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM unlink ${n0}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM unlink ${n0}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_NOUNLINK
+expect EPERM unlink ${n0}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_NOUNLINK
+expect EPERM unlink ${n0}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM unlink ${n0}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
+
+expect 0 create ${n0} 0644
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM unlink ${n0}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}
diff --git a/regress/sys/ffs/tests/unlink/10.t b/regress/sys/ffs/tests/unlink/10.t
new file mode 100644
index 00000000000..5128bb97a73
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/10.t
@@ -0,0 +1,45 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/10.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EPERM if the parent directory of the named file has its immutable or append-only flag set"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+
+expect 0 create ${n0}/${n1} 0644
+expect 0 chflags ${n0} SF_IMMUTABLE
+expect EPERM unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 create ${n0}/${n1} 0644
+expect 0 chflags ${n0} UF_IMMUTABLE
+expect EPERM unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 create ${n0}/${n1} 0644
+expect 0 chflags ${n0} SF_APPEND
+expect EPERM unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 create ${n0}/${n1} 0644
+expect 0 chflags ${n0} UF_APPEND
+expect EPERM unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+expect 0 unlink ${n0}/${n1}
+
+expect 0 create ${n0}/${n1} 0644
+expect 0 chflags ${n0} SF_NOUNLINK
+expect 0 unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 create ${n0}/${n1} 0644
+expect 0 chflags ${n0} UF_NOUNLINK
+expect 0 unlink ${n0}/${n1}
+expect 0 chflags ${n0} none
+
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/unlink/11.t b/regress/sys/ffs/tests/unlink/11.t
new file mode 100644
index 00000000000..21ca3088826
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/11.t
@@ -0,0 +1,63 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/11.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EACCES or EPERM if the directory containing the file is marked sticky, and neither the containing directory nor the file to be removed are owned by the effective user ID"
+
+n0=`namegen`
+n1=`namegen`
+n2=`namegen`
+
+expect 0 mkdir ${n2} 0755
+cdir=`pwd`
+cd ${n2}
+
+expect 0 mkdir ${n0} 0755
+expect 0 chown ${n0} 65534 65534
+expect 0 chmod ${n0} 01777
+
+# User owns both: the sticky directory and the file to be removed.
+expect 0 -u 65534 -g 65534 create ${n0}/${n1} 0644
+expect 0 -u 65534 -g 65534 unlink ${n0}/${n1}
+# User owns the file to be removed, but doesn't own the sticky directory.
+expect 0 -u 65533 -g 65533 create ${n0}/${n1} 0644
+expect 0 -u 65533 -g 65533 unlink ${n0}/${n1}
+# User owns the sticky directory, but doesn't own the file to be removed.
+expect 0 -u 65533 -g 65533 create ${n0}/${n1} 0644
+expect 0 -u 65534 -g 65534 unlink ${n0}/${n1}
+# User doesn't own the sticky directory nor the file to be removed.
+expect 0 -u 65534 -g 65534 create ${n0}/${n1} 0644
+expect "EACCES|EPERM" -u 65533 -g 65533 unlink ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+
+# User owns both: the sticky directory and the fifo to be removed.
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n1} 0644
+expect 0 -u 65534 -g 65534 unlink ${n0}/${n1}
+# User owns the fifo to be removed, but doesn't own the sticky directory.
+expect 0 -u 65533 -g 65533 mkfifo ${n0}/${n1} 0644
+expect 0 -u 65533 -g 65533 unlink ${n0}/${n1}
+# User owns the sticky directory, but doesn't own the fifo to be removed.
+expect 0 -u 65533 -g 65533 mkfifo ${n0}/${n1} 0644
+expect 0 -u 65534 -g 65534 unlink ${n0}/${n1}
+# User doesn't own the sticky directory nor the fifo to be removed.
+expect 0 -u 65534 -g 65534 mkfifo ${n0}/${n1} 0644
+expect "EACCES|EPERM" -u 65533 -g 65533 unlink ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+
+# User owns both: the sticky directory and the symlink to be removed.
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n1}
+expect 0 -u 65534 -g 65534 unlink ${n0}/${n1}
+# User owns the symlink to be removed, but doesn't own the sticky directory.
+expect 0 -u 65533 -g 65533 symlink test ${n0}/${n1}
+expect 0 -u 65533 -g 65533 unlink ${n0}/${n1}
+# User owns the sticky directory, but doesn't own the symlink to be removed.
+expect 0 -u 65533 -g 65533 symlink test ${n0}/${n1}
+expect 0 -u 65534 -g 65534 unlink ${n0}/${n1}
+# User doesn't own the sticky directory nor the symlink to be removed.
+expect 0 -u 65534 -g 65534 symlink test ${n0}/${n1}
+expect "EACCES|EPERM" -u 65533 -g 65533 unlink ${n0}/${n1}
+expect 0 unlink ${n0}/${n1}
+
+expect 0 rmdir ${n0}
+
+cd ${cdir}
+expect 0 rmdir ${n2}
diff --git a/regress/sys/ffs/tests/unlink/12.t b/regress/sys/ffs/tests/unlink/12.t
new file mode 100644
index 00000000000..60d070352f6
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/12.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/12.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EROFS if the named file resides on a read-only file system"
+
+n0=`namegen`
+n1=`namegen`
+
+expect 0 mkdir ${n0} 0755
+dd if=/dev/zero of=tmpdisk bs=1k count=1024 2>/dev/null
+vnconfig svnd1 tmpdisk
+newfs /dev/rsvnd1c >/dev/null
+mount /dev/svnd1c ${n0}
+expect 0 create ${n0}/${n1} 0644
+mount -ur /dev/svnd1c
+expect EROFS unlink ${n0}/${n1}
+mount -uw /dev/svnd1c
+expect 0 unlink ${n0}/${n1}
+umount /dev/svnd1c
+vnconfig -u svnd1
+rm tmpdisk
+expect 0 rmdir ${n0}
diff --git a/regress/sys/ffs/tests/unlink/13.t b/regress/sys/ffs/tests/unlink/13.t
new file mode 100644
index 00000000000..5eddae1e5b7
--- /dev/null
+++ b/regress/sys/ffs/tests/unlink/13.t
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $FreeBSD: src/tools/regression/fstest/tests/unlink/13.t,v 1.1 2007/01/17 01:42:12 pjd Exp $
+
+desc="unlink returns EFAULT if the path argument points outside the process's allocated address space"
+
+expect EFAULT unlink NULL
+expect EFAULT unlink DEADCODE