summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-03-11 20:02:06 +0000
committerpeter <peter@FreeBSD.org>1996-03-11 20:02:06 +0000
commit072464b1987f27964703650957bbf91f8350ace1 (patch)
tree14f0006877c226dd95425d7f980e0bc9326977fa /sys
parentf8b9f31b0ab6a6d7514f307d7a789fc9157a4a7a (diff)
downloadFreeBSD-src-072464b1987f27964703650957bbf91f8350ace1.zip
FreeBSD-src-072464b1987f27964703650957bbf91f8350ace1.tar.gz
Import 4.4BSD-Lite2 onto the vendor branch, note that in the kernel, all
files are off the vendor branch, so this should not change anything. A "U" marker generally means that the file was not changed in between the 4.4Lite and Lite-2 releases, and does not need a merge. "C" generally means that there was a change. [note new unused (in this form) syscalls.conf, to be 'cvs rm'ed]
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/Make.tags.inc3
-rw-r--r--sys/kern/Makefile6
-rw-r--r--sys/kern/init_main.c82
-rw-r--r--sys/kern/init_sysent.c819
-rw-r--r--sys/kern/kern_acct.c23
-rw-r--r--sys/kern/kern_descrip.c240
-rw-r--r--sys/kern/kern_exit.c73
-rw-r--r--sys/kern/kern_fork.c66
-rw-r--r--sys/kern/kern_ktrace.c85
-rw-r--r--sys/kern/kern_malloc.c17
-rw-r--r--sys/kern/kern_proc.c159
-rw-r--r--sys/kern/kern_prot.c277
-rw-r--r--sys/kern/kern_resource.c183
-rw-r--r--sys/kern/kern_sig.c290
-rw-r--r--sys/kern/kern_subr.c15
-rw-r--r--sys/kern/kern_synch.c11
-rw-r--r--sys/kern/kern_sysctl.c140
-rw-r--r--sys/kern/kern_time.c129
-rw-r--r--sys/kern/kern_xxx.c85
-rw-r--r--sys/kern/makesyscalls.sh476
-rw-r--r--sys/kern/subr_autoconf.c13
-rw-r--r--sys/kern/subr_log.c10
-rw-r--r--sys/kern/subr_prf.c7
-rw-r--r--sys/kern/subr_prof.c36
-rw-r--r--sys/kern/subr_xxx.c19
-rw-r--r--sys/kern/sys_generic.c253
-rw-r--r--sys/kern/sys_socket.c10
-rw-r--r--sys/kern/syscalls.c202
-rw-r--r--sys/kern/syscalls.conf12
-rw-r--r--sys/kern/syscalls.master557
-rw-r--r--sys/kern/tty.c20
-rw-r--r--sys/kern/tty_compat.c4
-rw-r--r--sys/kern/tty_conf.c10
-rw-r--r--sys/kern/tty_pty.c6
-rw-r--r--sys/kern/tty_tb.c4
-rw-r--r--sys/kern/tty_tty.c24
-rw-r--r--sys/kern/uipc_domain.c13
-rw-r--r--sys/kern/uipc_mbuf.c23
-rw-r--r--sys/kern/uipc_proto.c4
-rw-r--r--sys/kern/uipc_socket.c40
-rw-r--r--sys/kern/uipc_socket2.c28
-rw-r--r--sys/kern/uipc_syscalls.c642
-rw-r--r--sys/kern/uipc_usrreq.c40
-rw-r--r--sys/kern/vfs_cache.c314
-rw-r--r--sys/kern/vfs_cluster.c66
-rw-r--r--sys/kern/vfs_conf.c174
-rw-r--r--sys/kern/vfs_init.c19
-rw-r--r--sys/kern/vfs_lookup.c217
-rw-r--r--sys/kern/vfs_subr.c826
-rw-r--r--sys/kern/vfs_syscalls.c1538
-rw-r--r--sys/kern/vfs_vnops.c89
-rw-r--r--sys/kern/vnode_if.sh611
-rw-r--r--sys/kern/vnode_if.src206
53 files changed, 5554 insertions, 3662 deletions
diff --git a/sys/kern/Make.tags.inc b/sys/kern/Make.tags.inc
index 1563c41..79cb83a 100644
--- a/sys/kern/Make.tags.inc
+++ b/sys/kern/Make.tags.inc
@@ -1,4 +1,4 @@
-# @(#)Make.tags.inc 8.1 (Berkeley) 6/11/93
+# @(#)Make.tags.inc 8.2 (Berkeley) 11/23/94
# Common files for "make tags".
# Included by the Makefile for each architecture.
@@ -9,6 +9,7 @@
COMM= /sys/conf/*.[ch] \
/sys/dev/*.[ch] /sys/dev/scsi/*.[ch] \
+ /sys/isofs/*/*.[ch] \
/sys/kern/*.[ch] /sys/libkern/*.[ch] \
/sys/miscfs/*/*.[ch] \
/sys/net/*.[ch] /sys/netccitt/*.[ch] /sys/netinet/*.[ch] \
diff --git a/sys/kern/Makefile b/sys/kern/Makefile
index cfe962a..3159d20 100644
--- a/sys/kern/Makefile
+++ b/sys/kern/Makefile
@@ -1,4 +1,4 @@
-# @(#)Makefile 8.2 (Berkeley) 3/21/94
+# @(#)Makefile 8.3 (Berkeley) 2/14/95
# Makefile for kernel tags files, init_sysent, etc.
@@ -7,11 +7,11 @@ ARCH= hp300 i386 luna68k news3400 pmax sparc tahoe vax
all:
@echo "make tags, make links or init_sysent.c only"
-init_sysent.c syscalls.c ../sys/syscall.h: makesyscalls.sh syscalls.master
+init_sysent.c syscalls.c ../sys/syscall.h ../sys/syscallargs.h: makesyscalls.sh syscalls.master
-mv -f init_sysent.c init_sysent.c.bak
-mv -f syscalls.c syscalls.c.bak
-mv -f ../sys/syscall.h ../sys/syscall.h.bak
- sh makesyscalls.sh syscalls.master
+ sh makesyscalls.sh syscalls.conf syscalls.master
# Kernel tags:
# Tags files are built in the top-level directory for each architecture,
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index c649715..61a0a14 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)init_main.c 8.9 (Berkeley) 1/21/94
+ * @(#)init_main.c 8.16 (Berkeley) 5/14/95
*/
#include <sys/param.h>
@@ -57,6 +57,7 @@
#include <sys/protosw.h>
#include <sys/reboot.h>
#include <sys/user.h>
+#include <sys/syscallargs.h>
#include <ufs/ufs/quota.h>
@@ -106,8 +107,8 @@ main(framep)
register struct filedesc0 *fdp;
register struct pdevinit *pdev;
register int i;
- int s, rval[2];
- extern int (*mountroot) __P((void));
+ int s;
+ register_t rval[2];
extern struct pdevinit pdevinit[];
extern void roundrobin __P((void *));
extern void schedcpu __P((void *));
@@ -130,13 +131,19 @@ main(framep)
cpu_startup();
/*
+ * Initialize process and pgrp structures.
+ */
+ procinit();
+
+ /*
* Create process 0 (the swapper).
*/
- allproc = (volatile struct proc *)p;
- p->p_prev = (struct proc **)&allproc;
+ LIST_INSERT_HEAD(&allproc, p, p_list);
p->p_pgrp = &pgrp0;
- pgrphash[0] = &pgrp0;
- pgrp0.pg_mem = p;
+ LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
+ LIST_INIT(&pgrp0.pg_members);
+ LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
+
pgrp0.pg_session = &session0;
session0.s_count = 1;
session0.s_leader = p;
@@ -191,10 +198,8 @@ main(framep)
p->p_sigacts = &p->p_addr->u_sigacts;
/*
- * Initialize per uid information structure and charge
- * root for one process.
+ * Charge root for one process.
*/
- usrinfoinit();
(void)chgproccnt(0, 1);
rqinit();
@@ -242,15 +247,16 @@ main(framep)
schedcpu(NULL);
/* Mount the root file system. */
- if ((*mountroot)())
+ if (vfs_mountroot())
panic("cannot mount root");
+ mountlist.cqh_first->mnt_flag |= MNT_ROOTFS;
/* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
- if (VFS_ROOT(mountlist.tqh_first, &rootvnode))
+ if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
panic("cannot find root vnode");
fdp->fd_fd.fd_cdir = rootvnode;
VREF(fdp->fd_fd.fd_cdir);
- VOP_UNLOCK(rootvnode);
+ VOP_UNLOCK(rootvnode, 0, p);
fdp->fd_fd.fd_rdir = NULL;
swapinit();
@@ -313,8 +319,14 @@ start_init(p, framep)
void *framep;
{
vm_offset_t addr;
- struct execve_args args;
- int options, i, retval[2], error;
+ struct execve_args /* {
+ syscallarg(char *) path;
+ syscallarg(char **) argp;
+ syscallarg(char **) envp;
+ } */ args;
+ int options, i, error;
+ register_t retval[2];
+ char flags[4] = "-", *flagsp;
char **pathp, *path, *ucp, **uap, *arg0, *arg1;
initproc = p;
@@ -338,53 +350,59 @@ start_init(p, framep)
for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
/*
- * Move out the boot flag argument.
+ * Construct the boot flag argument.
*/
options = 0;
+ flagsp = flags + 1;
ucp = (char *)USRSTACK;
- (void)subyte(--ucp, 0); /* trailing zero */
if (boothowto & RB_SINGLE) {
- (void)subyte(--ucp, 's');
+ *flagsp++ = 's';
options = 1;
}
#ifdef notyet
if (boothowto & RB_FASTBOOT) {
- (void)subyte(--ucp, 'f');
+ *flagsp++ = 'f';
options = 1;
}
#endif
- if (options == 0)
- (void)subyte(--ucp, '-');
- (void)subyte(--ucp, '-'); /* leading hyphen */
- arg1 = ucp;
+ /*
+ * Move out the flags (arg 1), if necessary.
+ */
+ if (options != 0) {
+ *flagsp++ = '\0';
+ i = flagsp - flags;
+ (void)copyout((caddr_t)flags, (caddr_t)(ucp -= i), i);
+ arg1 = ucp;
+ }
/*
* Move out the file name (also arg 0).
*/
- for (i = strlen(path) + 1; i >= 0; i--)
- (void)subyte(--ucp, path[i]);
+ i = strlen(path) + 1;
+ (void)copyout((caddr_t)path, (caddr_t)(ucp -= i), i);
arg0 = ucp;
/*
* Move out the arg pointers.
*/
- uap = (char **)((int)ucp & ~(NBPW-1));
+ uap = (char **)((long)ucp & ~ALIGNBYTES);
(void)suword((caddr_t)--uap, 0); /* terminator */
- (void)suword((caddr_t)--uap, (int)arg1);
- (void)suword((caddr_t)--uap, (int)arg0);
+ if (options != 0)
+ (void)suword((caddr_t)--uap, (long)arg1);
+ (void)suword((caddr_t)--uap, (long)arg0);
/*
* Point at the arguments.
*/
- args.fname = arg0;
- args.argp = uap;
- args.envp = NULL;
+ SCARG(&args, path) = arg0;
+ SCARG(&args, argp) = uap;
+ SCARG(&args, envp) = NULL;
/*
* Now try to exec the program. If can't for any reason
* other than it doesn't exist, complain.
*/
- if ((error = execve(p, &args, &retval)) == 0)
+ if ((error = execve(p, &args, retval)) == 0)
return;
if (error != ENOENT)
printf("exec %s: error %d\n", path, error);
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 4b25c06..0bbdd20 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -2,14 +2,14 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from @(#)syscalls.master 8.2 (Berkeley) 1/13/94
+ * created from @(#)syscalls.master 8.6 (Berkeley) 3/30/95
*/
#include <sys/param.h>
#include <sys/systm.h>
-
-int nosys();
-
+#include <sys/signal.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
int nosys();
int exit();
int fork();
@@ -138,8 +138,7 @@ int fstatfs();
int getfh();
#else
#endif
-#ifdef SYSVSHM
-int shmsys();
+#if defined(SYSVSHM) && !defined(alpha)
#else
#endif
int setgid();
@@ -168,313 +167,601 @@ int ftruncate();
int __sysctl();
int mlock();
int munlock();
+int undelete();
+#if defined(SYSVSHM) && 0
+int shmat();
+int shmctl();
+int shmdt();
+int shmget();
+#else
+#endif
#ifdef COMPAT_43
-#define compat(n, name) n, __CONCAT(o,name)
+#define compat_43(func) __CONCAT(compat_43_,func)
-int ocreat();
-int olseek();
-int ostat();
-int olstat();
+int compat_43(creat)();
+int compat_43(lseek)();
+int compat_43(stat)();
+int compat_43(lstat)();
#ifdef KTRACE
#else
#endif
-int ofstat();
-int ogetkerninfo();
-int ogetpagesize();
-int ommap();
-int owait();
-int ogethostname();
-int osethostname();
-int oaccept();
-int osend();
-int orecv();
-int osigvec();
-int osigblock();
-int osigsetmask();
-int osigstack();
-int orecvmsg();
-int osendmsg();
+int compat_43(fstat)();
+int compat_43(getkerninfo)();
+int compat_43(getpagesize)();
+int compat_43(mmap)();
+int compat_43(wait)();
+int compat_43(gethostname)();
+int compat_43(sethostname)();
+int compat_43(accept)();
+int compat_43(send)();
+int compat_43(recv)();
+int compat_43(sigvec)();
+int compat_43(sigblock)();
+int compat_43(sigsetmask)();
+int compat_43(sigstack)();
+int compat_43(recvmsg)();
+int compat_43(sendmsg)();
#ifdef TRACE
#else
#endif
#ifdef vax
#else
#endif
-int orecvfrom();
-int osetreuid();
-int osetregid();
-int otruncate();
-int oftruncate();
-int ogetpeername();
-int ogethostid();
-int osethostid();
-int ogetrlimit();
-int osetrlimit();
-int okillpg();
-int oquota();
-int ogetsockname();
+int compat_43(recvfrom)();
+int compat_43(setreuid)();
+int compat_43(setregid)();
+int compat_43(truncate)();
+int compat_43(ftruncate)();
+int compat_43(getpeername)();
+int compat_43(gethostid)();
+int compat_43(sethostid)();
+int compat_43(getrlimit)();
+int compat_43(setrlimit)();
+int compat_43(killpg)();
+int compat_43(quota)();
+int compat_43(getsockname)();
#ifdef NFS
#else
#endif
-int ogetdirentries();
+int compat_43(getdirentries)();
#ifdef NFS
#else
#endif
-#ifdef SYSVSHM
+#if defined(SYSVSHM) && !defined(alpha)
+int compat_43(shmsys)();
#else
#endif
#ifdef LFS
#else
#endif
+#if defined(SYSVSHM) && 0
+#else
+#endif
#else /* COMPAT_43 */
-#define compat(n, name) 0, nosys
+#define compat_43(func) nosys
#endif /* COMPAT_43 */
+#define s(type) sizeof(type)
+
struct sysent sysent[] = {
- { 0, nosys }, /* 0 = syscall */
- { 1, exit }, /* 1 = exit */
- { 0, fork }, /* 2 = fork */
- { 3, read }, /* 3 = read */
- { 3, write }, /* 4 = write */
- { 3, open }, /* 5 = open */
- { 1, close }, /* 6 = close */
- { 4, wait4 }, /* 7 = wait4 */
- { compat(2,creat) }, /* 8 = old creat */
- { 2, link }, /* 9 = link */
- { 1, unlink }, /* 10 = unlink */
- { 0, nosys }, /* 11 = obsolete execv */
- { 1, chdir }, /* 12 = chdir */
- { 1, fchdir }, /* 13 = fchdir */
- { 3, mknod }, /* 14 = mknod */
- { 2, chmod }, /* 15 = chmod */
- { 3, chown }, /* 16 = chown */
- { 1, obreak }, /* 17 = break */
- { 3, getfsstat }, /* 18 = getfsstat */
- { compat(3,lseek) }, /* 19 = old lseek */
- { 0, getpid }, /* 20 = getpid */
- { 4, mount }, /* 21 = mount */
- { 2, unmount }, /* 22 = unmount */
- { 1, setuid }, /* 23 = setuid */
- { 0, getuid }, /* 24 = getuid */
- { 0, geteuid }, /* 25 = geteuid */
- { 4, ptrace }, /* 26 = ptrace */
- { 3, recvmsg }, /* 27 = recvmsg */
- { 3, sendmsg }, /* 28 = sendmsg */
- { 6, recvfrom }, /* 29 = recvfrom */
- { 3, accept }, /* 30 = accept */
- { 3, getpeername }, /* 31 = getpeername */
- { 3, getsockname }, /* 32 = getsockname */
- { 2, access }, /* 33 = access */
- { 2, chflags }, /* 34 = chflags */
- { 2, fchflags }, /* 35 = fchflags */
- { 0, sync }, /* 36 = sync */
- { 2, kill }, /* 37 = kill */
- { compat(2,stat) }, /* 38 = old stat */
- { 0, getppid }, /* 39 = getppid */
- { compat(2,lstat) }, /* 40 = old lstat */
- { 2, dup }, /* 41 = dup */
- { 0, pipe }, /* 42 = pipe */
- { 0, getegid }, /* 43 = getegid */
- { 4, profil }, /* 44 = profil */
+ { 0, 0,
+ nosys }, /* 0 = syscall */
+ { 1, s(struct exit_args),
+ exit }, /* 1 = exit */
+ { 0, 0,
+ fork }, /* 2 = fork */
+ { 3, s(struct read_args),
+ read }, /* 3 = read */
+ { 3, s(struct write_args),
+ write }, /* 4 = write */
+ { 3, s(struct open_args),
+ open }, /* 5 = open */
+ { 1, s(struct close_args),
+ close }, /* 6 = close */
+ { 4, s(struct wait4_args),
+ wait4 }, /* 7 = wait4 */
+ { 2, s(struct compat_43_creat_args),
+ compat_43(creat) }, /* 8 = compat_43 creat */
+ { 2, s(struct link_args),
+ link }, /* 9 = link */
+ { 1, s(struct unlink_args),
+ unlink }, /* 10 = unlink */
+ { 0, 0,
+ nosys }, /* 11 = obsolete execv */
+ { 1, s(struct chdir_args),
+ chdir }, /* 12 = chdir */
+ { 1, s(struct fchdir_args),
+ fchdir }, /* 13 = fchdir */
+ { 3, s(struct mknod_args),
+ mknod }, /* 14 = mknod */
+ { 2, s(struct chmod_args),
+ chmod }, /* 15 = chmod */
+ { 3, s(struct chown_args),
+ chown }, /* 16 = chown */
+ { 1, s(struct obreak_args),
+ obreak }, /* 17 = break */
+ { 3, s(struct getfsstat_args),
+ getfsstat }, /* 18 = getfsstat */
+ { 3, s(struct compat_43_lseek_args),
+ compat_43(lseek) }, /* 19 = compat_43 lseek */
+ { 0, 0,
+ getpid }, /* 20 = getpid */
+ { 4, s(struct mount_args),
+ mount }, /* 21 = mount */
+ { 2, s(struct unmount_args),
+ unmount }, /* 22 = unmount */
+ { 1, s(struct setuid_args),
+ setuid }, /* 23 = setuid */
+ { 0, 0,
+ getuid }, /* 24 = getuid */
+ { 0, 0,
+ geteuid }, /* 25 = geteuid */
+ { 4, s(struct ptrace_args),
+ ptrace }, /* 26 = ptrace */
+ { 3, s(struct recvmsg_args),
+ recvmsg }, /* 27 = recvmsg */
+ { 3, s(struct sendmsg_args),
+ sendmsg }, /* 28 = sendmsg */
+ { 6, s(struct recvfrom_args),
+ recvfrom }, /* 29 = recvfrom */
+ { 3, s(struct accept_args),
+ accept }, /* 30 = accept */
+ { 3, s(struct getpeername_args),
+ getpeername }, /* 31 = getpeername */
+ { 3, s(struct getsockname_args),
+ getsockname }, /* 32 = getsockname */
+ { 2, s(struct access_args),
+ access }, /* 33 = access */
+ { 2, s(struct chflags_args),
+ chflags }, /* 34 = chflags */
+ { 2, s(struct fchflags_args),
+ fchflags }, /* 35 = fchflags */
+ { 0, 0,
+ sync }, /* 36 = sync */
+ { 2, s(struct kill_args),
+ kill }, /* 37 = kill */
+ { 2, s(struct compat_43_stat_args),
+ compat_43(stat) }, /* 38 = compat_43 stat */
+ { 0, 0,
+ getppid }, /* 39 = getppid */
+ { 2, s(struct compat_43_lstat_args),
+ compat_43(lstat) }, /* 40 = compat_43 lstat */
+ { 1, s(struct dup_args),
+ dup }, /* 41 = dup */
+ { 0, 0,
+ pipe }, /* 42 = pipe */
+ { 0, 0,
+ getegid }, /* 43 = getegid */
+ { 4, s(struct profil_args),
+ profil }, /* 44 = profil */
#ifdef KTRACE
- { 4, ktrace }, /* 45 = ktrace */
+ { 4, s(struct ktrace_args),
+ ktrace }, /* 45 = ktrace */
#else
- { 0, nosys }, /* 45 = ktrace */
+ { 0, 0,
+ nosys }, /* 45 = unimplemented ktrace */
#endif
- { 3, sigaction }, /* 46 = sigaction */
- { 0, getgid }, /* 47 = getgid */
- { 2, sigprocmask }, /* 48 = sigprocmask */
- { 2, getlogin }, /* 49 = getlogin */
- { 1, setlogin }, /* 50 = setlogin */
- { 1, acct }, /* 51 = acct */
- { 0, sigpending }, /* 52 = sigpending */
- { 2, sigaltstack }, /* 53 = sigaltstack */
- { 3, ioctl }, /* 54 = ioctl */
- { 1, reboot }, /* 55 = reboot */
- { 1, revoke }, /* 56 = revoke */
- { 2, symlink }, /* 57 = symlink */
- { 3, readlink }, /* 58 = readlink */
- { 3, execve }, /* 59 = execve */
- { 1, umask }, /* 60 = umask */
- { 1, chroot }, /* 61 = chroot */
- { compat(2,fstat) }, /* 62 = old fstat */
- { compat(4,getkerninfo) }, /* 63 = old getkerninfo */
- { compat(0,getpagesize) }, /* 64 = old getpagesize */
- { 2, msync }, /* 65 = msync */
- { 0, vfork }, /* 66 = vfork */
- { 0, nosys }, /* 67 = obsolete vread */
- { 0, nosys }, /* 68 = obsolete vwrite */
- { 1, sbrk }, /* 69 = sbrk */
- { 1, sstk }, /* 70 = sstk */
- { compat(7,mmap) }, /* 71 = old mmap */
- { 1, ovadvise }, /* 72 = vadvise */
- { 2, munmap }, /* 73 = munmap */
- { 3, mprotect }, /* 74 = mprotect */
- { 3, madvise }, /* 75 = madvise */
- { 0, nosys }, /* 76 = obsolete vhangup */
- { 0, nosys }, /* 77 = obsolete vlimit */
- { 3, mincore }, /* 78 = mincore */
- { 2, getgroups }, /* 79 = getgroups */
- { 2, setgroups }, /* 80 = setgroups */
- { 0, getpgrp }, /* 81 = getpgrp */
- { 2, setpgid }, /* 82 = setpgid */
- { 3, setitimer }, /* 83 = setitimer */
- { compat(0,wait) }, /* 84 = old wait */
- { 1, swapon }, /* 85 = swapon */
- { 2, getitimer }, /* 86 = getitimer */
- { compat(2,gethostname) }, /* 87 = old gethostname */
- { compat(2,sethostname) }, /* 88 = old sethostname */
- { 0, getdtablesize }, /* 89 = getdtablesize */
- { 2, dup2 }, /* 90 = dup2 */
- { 0, nosys }, /* 91 = getdopt */
- { 3, fcntl }, /* 92 = fcntl */
- { 5, select }, /* 93 = select */
- { 0, nosys }, /* 94 = setdopt */
- { 1, fsync }, /* 95 = fsync */
- { 3, setpriority }, /* 96 = setpriority */
- { 3, socket }, /* 97 = socket */
- { 3, connect }, /* 98 = connect */
- { compat(3,accept) }, /* 99 = old accept */
- { 2, getpriority }, /* 100 = getpriority */
- { compat(4,send) }, /* 101 = old send */
- { compat(4,recv) }, /* 102 = old recv */
- { 1, sigreturn }, /* 103 = sigreturn */
- { 3, bind }, /* 104 = bind */
- { 5, setsockopt }, /* 105 = setsockopt */
- { 2, listen }, /* 106 = listen */
- { 0, nosys }, /* 107 = obsolete vtimes */
- { compat(3,sigvec) }, /* 108 = old sigvec */
- { compat(1,sigblock) }, /* 109 = old sigblock */
- { compat(1,sigsetmask) }, /* 110 = old sigsetmask */
- { 1, sigsuspend }, /* 111 = sigsuspend */
- { compat(2,sigstack) }, /* 112 = old sigstack */
- { compat(3,recvmsg) }, /* 113 = old recvmsg */
- { compat(3,sendmsg) }, /* 114 = old sendmsg */
+ { 3, s(struct sigaction_args),
+ sigaction }, /* 46 = sigaction */
+ { 0, 0,
+ getgid }, /* 47 = getgid */
+ { 2, s(struct sigprocmask_args),
+ sigprocmask }, /* 48 = sigprocmask */
+ { 2, s(struct getlogin_args),
+ getlogin }, /* 49 = getlogin */
+ { 1, s(struct setlogin_args),
+ setlogin }, /* 50 = setlogin */
+ { 1, s(struct acct_args),
+ acct }, /* 51 = acct */
+ { 0, 0,
+ sigpending }, /* 52 = sigpending */
+ { 2, s(struct sigaltstack_args),
+ sigaltstack }, /* 53 = sigaltstack */
+ { 3, s(struct ioctl_args),
+ ioctl }, /* 54 = ioctl */
+ { 1, s(struct reboot_args),
+ reboot }, /* 55 = reboot */
+ { 1, s(struct revoke_args),
+ revoke }, /* 56 = revoke */
+ { 2, s(struct symlink_args),
+ symlink }, /* 57 = symlink */
+ { 3, s(struct readlink_args),
+ readlink }, /* 58 = readlink */
+ { 3, s(struct execve_args),
+ execve }, /* 59 = execve */
+ { 1, s(struct umask_args),
+ umask }, /* 60 = umask */
+ { 1, s(struct chroot_args),
+ chroot }, /* 61 = chroot */
+ { 2, s(struct compat_43_fstat_args),
+ compat_43(fstat) }, /* 62 = compat_43 fstat */
+ { 4, s(struct compat_43_getkerninfo_args),
+ compat_43(getkerninfo) }, /* 63 = compat_43 getkerninfo */
+ { 0, 0,
+ compat_43(getpagesize) }, /* 64 = compat_43 getpagesize */
+ { 2, s(struct msync_args),
+ msync }, /* 65 = msync */
+ { 0, 0,
+ vfork }, /* 66 = vfork */
+ { 0, 0,
+ nosys }, /* 67 = obsolete vread */
+ { 0, 0,
+ nosys }, /* 68 = obsolete vwrite */
+ { 1, s(struct sbrk_args),
+ sbrk }, /* 69 = sbrk */
+ { 1, s(struct sstk_args),
+ sstk }, /* 70 = sstk */
+ { 6, s(struct compat_43_mmap_args),
+ compat_43(mmap) }, /* 71 = compat_43 mmap */
+ { 1, s(struct ovadvise_args),
+ ovadvise }, /* 72 = vadvise */
+ { 2, s(struct munmap_args),
+ munmap }, /* 73 = munmap */
+ { 3, s(struct mprotect_args),
+ mprotect }, /* 74 = mprotect */
+ { 3, s(struct madvise_args),
+ madvise }, /* 75 = madvise */
+ { 0, 0,
+ nosys }, /* 76 = obsolete vhangup */
+ { 0, 0,
+ nosys }, /* 77 = obsolete vlimit */
+ { 3, s(struct mincore_args),
+ mincore }, /* 78 = mincore */
+ { 2, s(struct getgroups_args),
+ getgroups }, /* 79 = getgroups */
+ { 2, s(struct setgroups_args),
+ setgroups }, /* 80 = setgroups */
+ { 0, 0,
+ getpgrp }, /* 81 = getpgrp */
+ { 2, s(struct setpgid_args),
+ setpgid }, /* 82 = setpgid */
+ { 3, s(struct setitimer_args),
+ setitimer }, /* 83 = setitimer */
+ { 0, 0,
+ compat_43(wait) }, /* 84 = compat_43 wait */
+ { 1, s(struct swapon_args),
+ swapon }, /* 85 = swapon */
+ { 2, s(struct getitimer_args),
+ getitimer }, /* 86 = getitimer */
+ { 2, s(struct compat_43_gethostname_args),
+ compat_43(gethostname) }, /* 87 = compat_43 gethostname */
+ { 2, s(struct compat_43_sethostname_args),
+ compat_43(sethostname) }, /* 88 = compat_43 sethostname */
+ { 0, 0,
+ getdtablesize }, /* 89 = getdtablesize */
+ { 2, s(struct dup2_args),
+ dup2 }, /* 90 = dup2 */
+ { 0, 0,
+ nosys }, /* 91 = unimplemented getdopt */
+ { 3, s(struct fcntl_args),
+ fcntl }, /* 92 = fcntl */
+ { 5, s(struct select_args),
+ select }, /* 93 = select */
+ { 0, 0,
+ nosys }, /* 94 = unimplemented setdopt */
+ { 1, s(struct fsync_args),
+ fsync }, /* 95 = fsync */
+ { 3, s(struct setpriority_args),
+ setpriority }, /* 96 = setpriority */
+ { 3, s(struct socket_args),
+ socket }, /* 97 = socket */
+ { 3, s(struct connect_args),
+ connect }, /* 98 = connect */
+ { 3, s(struct compat_43_accept_args),
+ compat_43(accept) }, /* 99 = compat_43 accept */
+ { 2, s(struct getpriority_args),
+ getpriority }, /* 100 = getpriority */
+ { 4, s(struct compat_43_send_args),
+ compat_43(send) }, /* 101 = compat_43 send */
+ { 4, s(struct compat_43_recv_args),
+ compat_43(recv) }, /* 102 = compat_43 recv */
+ { 1, s(struct sigreturn_args),
+ sigreturn }, /* 103 = sigreturn */
+ { 3, s(struct bind_args),
+ bind }, /* 104 = bind */
+ { 5, s(struct setsockopt_args),
+ setsockopt }, /* 105 = setsockopt */
+ { 2, s(struct listen_args),
+ listen }, /* 106 = listen */
+ { 0, 0,
+ nosys }, /* 107 = obsolete vtimes */
+ { 3, s(struct compat_43_sigvec_args),
+ compat_43(sigvec) }, /* 108 = compat_43 sigvec */
+ { 1, s(struct compat_43_sigblock_args),
+ compat_43(sigblock) }, /* 109 = compat_43 sigblock */
+ { 1, s(struct compat_43_sigsetmask_args),
+ compat_43(sigsetmask) }, /* 110 = compat_43 sigsetmask */
+ { 1, s(struct sigsuspend_args),
+ sigsuspend }, /* 111 = sigsuspend */
+ { 2, s(struct compat_43_sigstack_args),
+ compat_43(sigstack) }, /* 112 = compat_43 sigstack */
+ { 3, s(struct compat_43_recvmsg_args),
+ compat_43(recvmsg) }, /* 113 = compat_43 recvmsg */
+ { 3, s(struct compat_43_sendmsg_args),
+ compat_43(sendmsg) }, /* 114 = compat_43 sendmsg */
#ifdef TRACE
- { 2, vtrace }, /* 115 = vtrace */
+ { 2, s(struct vtrace_args),
+ vtrace }, /* 115 = vtrace */
#else
- { 0, nosys }, /* 115 = obsolete vtrace */
+ { 0, 0,
+ nosys }, /* 115 = obsolete vtrace */
#endif
- { 2, gettimeofday }, /* 116 = gettimeofday */
- { 2, getrusage }, /* 117 = getrusage */
- { 5, getsockopt }, /* 118 = getsockopt */
+ { 2, s(struct gettimeofday_args),
+ gettimeofday }, /* 116 = gettimeofday */
+ { 2, s(struct getrusage_args),
+ getrusage }, /* 117 = getrusage */
+ { 5, s(struct getsockopt_args),
+ getsockopt }, /* 118 = getsockopt */
#ifdef vax
- { 1, resuba }, /* 119 = resuba */
+ { 1, s(struct resuba_args),
+ resuba }, /* 119 = resuba */
#else
- { 0, nosys }, /* 119 = nosys */
+ { 0, 0,
+ nosys }, /* 119 = unimplemented resuba */
#endif
- { 3, readv }, /* 120 = readv */
- { 3, writev }, /* 121 = writev */
- { 2, settimeofday }, /* 122 = settimeofday */
- { 3, fchown }, /* 123 = fchown */
- { 2, fchmod }, /* 124 = fchmod */
- { compat(6,recvfrom) }, /* 125 = old recvfrom */
- { compat(2,setreuid) }, /* 126 = old setreuid */
- { compat(2,setregid) }, /* 127 = old setregid */
- { 2, rename }, /* 128 = rename */
- { compat(2,truncate) }, /* 129 = old truncate */
- { compat(2,ftruncate) }, /* 130 = old ftruncate */
- { 2, flock }, /* 131 = flock */
- { 2, mkfifo }, /* 132 = mkfifo */
- { 6, sendto }, /* 133 = sendto */
- { 2, shutdown }, /* 134 = shutdown */
- { 5, socketpair }, /* 135 = socketpair */
- { 2, mkdir }, /* 136 = mkdir */
- { 1, rmdir }, /* 137 = rmdir */
- { 2, utimes }, /* 138 = utimes */
- { 0, nosys }, /* 139 = obsolete 4.2 sigreturn */
- { 2, adjtime }, /* 140 = adjtime */
- { compat(3,getpeername) }, /* 141 = old getpeername */
- { compat(0,gethostid) }, /* 142 = old gethostid */
- { compat(1,sethostid) }, /* 143 = old sethostid */
- { compat(2,getrlimit) }, /* 144 = old getrlimit */
- { compat(2,setrlimit) }, /* 145 = old setrlimit */
- { compat(2,killpg) }, /* 146 = old killpg */
- { 0, setsid }, /* 147 = setsid */
- { 4, quotactl }, /* 148 = quotactl */
- { compat(4,quota) }, /* 149 = old quota */
- { compat(3,getsockname) }, /* 150 = old getsockname */
- { 0, nosys }, /* 151 = nosys */
- { 0, nosys }, /* 152 = nosys */
- { 0, nosys }, /* 153 = nosys */
- { 0, nosys }, /* 154 = nosys */
+ { 3, s(struct readv_args),
+ readv }, /* 120 = readv */
+ { 3, s(struct writev_args),
+ writev }, /* 121 = writev */
+ { 2, s(struct settimeofday_args),
+ settimeofday }, /* 122 = settimeofday */
+ { 3, s(struct fchown_args),
+ fchown }, /* 123 = fchown */
+ { 2, s(struct fchmod_args),
+ fchmod }, /* 124 = fchmod */
+ { 6, s(struct compat_43_recvfrom_args),
+ compat_43(recvfrom) }, /* 125 = compat_43 recvfrom */
+ { 2, s(struct compat_43_setreuid_args),
+ compat_43(setreuid) }, /* 126 = compat_43 setreuid */
+ { 2, s(struct compat_43_setregid_args),
+ compat_43(setregid) }, /* 127 = compat_43 setregid */
+ { 2, s(struct rename_args),
+ rename }, /* 128 = rename */
+ { 2, s(struct compat_43_truncate_args),
+ compat_43(truncate) }, /* 129 = compat_43 truncate */
+ { 2, s(struct compat_43_ftruncate_args),
+ compat_43(ftruncate) }, /* 130 = compat_43 ftruncate */
+ { 2, s(struct flock_args),
+ flock }, /* 131 = flock */
+ { 2, s(struct mkfifo_args),
+ mkfifo }, /* 132 = mkfifo */
+ { 6, s(struct sendto_args),
+ sendto }, /* 133 = sendto */
+ { 2, s(struct shutdown_args),
+ shutdown }, /* 134 = shutdown */
+ { 4, s(struct socketpair_args),
+ socketpair }, /* 135 = socketpair */
+ { 2, s(struct mkdir_args),
+ mkdir }, /* 136 = mkdir */
+ { 1, s(struct rmdir_args),
+ rmdir }, /* 137 = rmdir */
+ { 2, s(struct utimes_args),
+ utimes }, /* 138 = utimes */
+ { 0, 0,
+ nosys }, /* 139 = obsolete 4.2 sigreturn */
+ { 2, s(struct adjtime_args),
+ adjtime }, /* 140 = adjtime */
+ { 3, s(struct compat_43_getpeername_args),
+ compat_43(getpeername) }, /* 141 = compat_43 getpeername */
+ { 0, 0,
+ compat_43(gethostid) }, /* 142 = compat_43 gethostid */
+ { 1, s(struct compat_43_sethostid_args),
+ compat_43(sethostid) }, /* 143 = compat_43 sethostid */
+ { 2, s(struct compat_43_getrlimit_args),
+ compat_43(getrlimit) }, /* 144 = compat_43 getrlimit */
+ { 2, s(struct compat_43_setrlimit_args),
+ compat_43(setrlimit) }, /* 145 = compat_43 setrlimit */
+ { 2, s(struct compat_43_killpg_args),
+ compat_43(killpg) }, /* 146 = compat_43 killpg */
+ { 0, 0,
+ setsid }, /* 147 = setsid */
+ { 4, s(struct quotactl_args),
+ quotactl }, /* 148 = quotactl */
+ { 0, 0,
+ compat_43(quota) }, /* 149 = compat_43 quota */
+ { 3, s(struct compat_43_getsockname_args),
+ compat_43(getsockname) }, /* 150 = compat_43 getsockname */
+ { 0, 0,
+ nosys }, /* 151 = unimplemented */
+ { 0, 0,
+ nosys }, /* 152 = unimplemented */
+ { 0, 0,
+ nosys }, /* 153 = unimplemented */
+ { 0, 0,
+ nosys }, /* 154 = unimplemented */
#ifdef NFS
- { 2, nfssvc }, /* 155 = nfssvc */
+ { 2, s(struct nfssvc_args),
+ nfssvc }, /* 155 = nfssvc */
#else
- { 0, nosys }, /* 155 = nosys */
+ { 0, 0,
+ nosys }, /* 155 = unimplemented nfssvc */
#endif
- { compat(4,getdirentries) }, /* 156 = old getdirentries */
- { 2, statfs }, /* 157 = statfs */
- { 2, fstatfs }, /* 158 = fstatfs */
- { 0, nosys }, /* 159 = nosys */
- { 0, nosys }, /* 160 = nosys */
+ { 4, s(struct compat_43_getdirentries_args),
+ compat_43(getdirentries) }, /* 156 = compat_43 getdirentries */
+ { 2, s(struct statfs_args),
+ statfs }, /* 157 = statfs */
+ { 2, s(struct fstatfs_args),
+ fstatfs }, /* 158 = fstatfs */
+ { 0, 0,
+ nosys }, /* 159 = unimplemented */
+ { 0, 0,
+ nosys }, /* 160 = unimplemented */
#ifdef NFS
- { 2, getfh }, /* 161 = getfh */
+ { 2, s(struct getfh_args),
+ getfh }, /* 161 = getfh */
#else
- { 0, nosys }, /* 161 = nosys */
+ { 0, 0,
+ nosys }, /* 161 = unimplemented getfh */
#endif
- { 0, nosys }, /* 162 = nosys */
- { 0, nosys }, /* 163 = nosys */
- { 0, nosys }, /* 164 = nosys */
- { 0, nosys }, /* 165 = nosys */
- { 0, nosys }, /* 166 = nosys */
- { 0, nosys }, /* 167 = nosys */
- { 0, nosys }, /* 168 = nosys */
- { 0, nosys }, /* 169 = nosys */
- { 0, nosys }, /* 170 = nosys */
-#ifdef SYSVSHM
- { 4, shmsys }, /* 171 = shmsys */
+ { 0, 0,
+ nosys }, /* 162 = unimplemented getdomainname */
+ { 0, 0,
+ nosys }, /* 163 = unimplemented setdomainname */
+ { 0, 0,
+ nosys }, /* 164 = unimplemented */
+ { 0, 0,
+ nosys }, /* 165 = unimplemented */
+ { 0, 0,
+ nosys }, /* 166 = unimplemented */
+ { 0, 0,
+ nosys }, /* 167 = unimplemented */
+ { 0, 0,
+ nosys }, /* 168 = unimplemented */
+ { 0, 0,
+ nosys }, /* 169 = unimplemented semsys */
+ { 0, 0,
+ nosys }, /* 170 = unimplemented msgsys */
+#if defined(SYSVSHM) && !defined(alpha)
+ { 4, s(struct compat_43_shmsys_args),
+ compat_43(shmsys) }, /* 171 = compat_43 shmsys */
#else
- { 0, nosys }, /* 171 = nosys */
+ { 0, 0,
+ nosys }, /* 171 = unimplemented shmsys */
#endif
- { 0, nosys }, /* 172 = nosys */
- { 0, nosys }, /* 173 = nosys */
- { 0, nosys }, /* 174 = nosys */
- { 0, nosys }, /* 175 = nosys */
- { 0, nosys }, /* 176 = nosys */
- { 0, nosys }, /* 177 = nosys */
- { 0, nosys }, /* 178 = nosys */
- { 0, nosys }, /* 179 = nosys */
- { 0, nosys }, /* 180 = nosys */
- { 1, setgid }, /* 181 = setgid */
- { 1, setegid }, /* 182 = setegid */
- { 1, seteuid }, /* 183 = seteuid */
+ { 0, 0,
+ nosys }, /* 172 = unimplemented */
+ { 0, 0,
+ nosys }, /* 173 = unimplemented */
+ { 0, 0,
+ nosys }, /* 174 = unimplemented */
+ { 0, 0,
+ nosys }, /* 175 = unimplemented */
+ { 0, 0,
+ nosys }, /* 176 = unimplemented */
+ { 0, 0,
+ nosys }, /* 177 = unimplemented */
+ { 0, 0,
+ nosys }, /* 178 = unimplemented */
+ { 0, 0,
+ nosys }, /* 179 = unimplemented */
+ { 0, 0,
+ nosys }, /* 180 = unimplemented */
+ { 1, s(struct setgid_args),
+ setgid }, /* 181 = setgid */
+ { 1, s(struct setegid_args),
+ setegid }, /* 182 = setegid */
+ { 1, s(struct seteuid_args),
+ seteuid }, /* 183 = seteuid */
#ifdef LFS
- { 3, lfs_bmapv }, /* 184 = lfs_bmapv */
- { 3, lfs_markv }, /* 185 = lfs_markv */
- { 2, lfs_segclean }, /* 186 = lfs_segclean */
- { 2, lfs_segwait }, /* 187 = lfs_segwait */
+ { 3, s(struct lfs_bmapv_args),
+ lfs_bmapv }, /* 184 = lfs_bmapv */
+ { 3, s(struct lfs_markv_args),
+ lfs_markv }, /* 185 = lfs_markv */
+ { 2, s(struct lfs_segclean_args),
+ lfs_segclean }, /* 186 = lfs_segclean */
+ { 2, s(struct lfs_segwait_args),
+ lfs_segwait }, /* 187 = lfs_segwait */
+#else
+ { 0, 0,
+ nosys }, /* 184 = unimplemented lfs_bmapv */
+ { 0, 0,
+ nosys }, /* 185 = unimplemented lfs_markv */
+ { 0, 0,
+ nosys }, /* 186 = unimplemented lfs_segclean */
+ { 0, 0,
+ nosys }, /* 187 = unimplemented lfs_segwait */
+#endif
+ { 2, s(struct stat_args),
+ stat }, /* 188 = stat */
+ { 2, s(struct fstat_args),
+ fstat }, /* 189 = fstat */
+ { 2, s(struct lstat_args),
+ lstat }, /* 190 = lstat */
+ { 2, s(struct pathconf_args),
+ pathconf }, /* 191 = pathconf */
+ { 2, s(struct fpathconf_args),
+ fpathconf }, /* 192 = fpathconf */
+ { 0, 0,
+ nosys }, /* 193 = unimplemented */
+ { 2, s(struct getrlimit_args),
+ getrlimit }, /* 194 = getrlimit */
+ { 2, s(struct setrlimit_args),
+ setrlimit }, /* 195 = setrlimit */
+ { 4, s(struct getdirentries_args),
+ getdirentries }, /* 196 = getdirentries */
+ { 7, s(struct mmap_args),
+ mmap }, /* 197 = mmap */
+ { 0, 0,
+ nosys }, /* 198 = __syscall */
+ { 4, s(struct lseek_args),
+ lseek }, /* 199 = lseek */
+ { 3, s(struct truncate_args),
+ truncate }, /* 200 = truncate */
+ { 3, s(struct ftruncate_args),
+ ftruncate }, /* 201 = ftruncate */
+ { 6, s(struct __sysctl_args),
+ __sysctl }, /* 202 = __sysctl */
+ { 2, s(struct mlock_args),
+ mlock }, /* 203 = mlock */
+ { 2, s(struct munlock_args),
+ munlock }, /* 204 = munlock */
+ { 1, s(struct undelete_args),
+ undelete }, /* 205 = undelete */
+ { 0, 0,
+ nosys }, /* 206 = unimplemented */
+ { 0, 0,
+ nosys }, /* 207 = unimplemented */
+ { 0, 0,
+ nosys }, /* 208 = unimplemented */
+ { 0, 0,
+ nosys }, /* 209 = unimplemented */
+ { 0, 0,
+ nosys }, /* 210 = unimplemented */
+ { 0, 0,
+ nosys }, /* 211 = unimplemented */
+ { 0, 0,
+ nosys }, /* 212 = unimplemented */
+ { 0, 0,
+ nosys }, /* 213 = unimplemented */
+ { 0, 0,
+ nosys }, /* 214 = unimplemented */
+ { 0, 0,
+ nosys }, /* 215 = unimplemented */
+ { 0, 0,
+ nosys }, /* 216 = unimplemented */
+ { 0, 0,
+ nosys }, /* 217 = unimplemented */
+ { 0, 0,
+ nosys }, /* 218 = unimplemented */
+ { 0, 0,
+ nosys }, /* 219 = unimplemented */
+ { 0, 0,
+ nosys }, /* 220 = unimplemented semctl */
+ { 0, 0,
+ nosys }, /* 221 = unimplemented semget */
+ { 0, 0,
+ nosys }, /* 222 = unimplemented semop */
+ { 0, 0,
+ nosys }, /* 223 = unimplemented semconfig */
+ { 0, 0,
+ nosys }, /* 224 = unimplemented msgctl */
+ { 0, 0,
+ nosys }, /* 225 = unimplemented msgget */
+ { 0, 0,
+ nosys }, /* 226 = unimplemented msgsnd */
+ { 0, 0,
+ nosys }, /* 227 = unimplemented msgrcv */
+#if defined(SYSVSHM) && 0
+ { 3, s(struct shmat_args),
+ shmat }, /* 228 = shmat */
+ { 3, s(struct shmctl_args),
+ shmctl }, /* 229 = shmctl */
+ { 1, s(struct shmdt_args),
+ shmdt }, /* 230 = shmdt */
+ { 3, s(struct shmget_args),
+ shmget }, /* 231 = shmget */
#else
- { 0, nosys }, /* 184 = nosys */
- { 0, nosys }, /* 185 = nosys */
- { 0, nosys }, /* 186 = nosys */
- { 0, nosys }, /* 187 = nosys */
+ { 0, 0,
+ nosys }, /* 228 = unimplemented shmat */
+ { 0, 0,
+ nosys }, /* 229 = unimplemented shmctl */
+ { 0, 0,
+ nosys }, /* 230 = unimplemented shmdt */
+ { 0, 0,
+ nosys }, /* 231 = unimplemented shmget */
#endif
- { 2, stat }, /* 188 = stat */
- { 2, fstat }, /* 189 = fstat */
- { 2, lstat }, /* 190 = lstat */
- { 2, pathconf }, /* 191 = pathconf */
- { 2, fpathconf }, /* 192 = fpathconf */
- { 0, nosys }, /* 193 = nosys */
- { 2, getrlimit }, /* 194 = getrlimit */
- { 2, setrlimit }, /* 195 = setrlimit */
- { 4, getdirentries }, /* 196 = getdirentries */
- { 8, mmap }, /* 197 = mmap */
- { 0, nosys }, /* 198 = __syscall */
- { 5, lseek }, /* 199 = lseek */
- { 4, truncate }, /* 200 = truncate */
- { 4, ftruncate }, /* 201 = ftruncate */
- { 6, __sysctl }, /* 202 = __sysctl */
- { 2, mlock }, /* 203 = mlock */
- { 2, munlock }, /* 204 = munlock */
- { 0, nosys }, /* 205 = nosys */
- { 0, nosys }, /* 206 = nosys */
- { 0, nosys }, /* 207 = nosys */
- { 0, nosys }, /* 208 = nosys */
- { 0, nosys }, /* 209 = nosys */
- { 0, nosys }, /* 210 = nosys */
};
-int nsysent = sizeof(sysent) / sizeof(sysent[0]);
+int nsysent= sizeof(sysent) / sizeof(sysent[0]);
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
index b752279..a23543c 100644
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)kern_acct.c 8.1 (Berkeley) 6/14/93
+ * from: @(#)kern_acct.c 8.8 (Berkeley) 5/14/95
*/
#include <sys/param.h>
@@ -46,12 +46,11 @@
#include <sys/syslog.h>
#include <sys/kernel.h>
-struct acct_args {
- char *fname;
-};
acct(a1, a2, a3)
struct proc *a1;
- struct acct_args *a2;
+ struct acct_args /* {
+ syscallarg(char *) path;
+ } */ *a2;
int *a3;
{
/*
@@ -72,7 +71,9 @@ acct_process(a1)
/*
* Periodically check the file system to see if accounting
- * should be turned on or off.
+ * should be turned on or off. Beware the case where the vnode
+ * has been vgone()'d out from underneath us, e.g. when the file
+ * system containing the accounting file has been forcibly unmounted.
*/
/*
@@ -96,6 +97,11 @@ acctwatch(a)
struct statfs sb;
if (savacctp) {
+ if (savacctp->v_type == VBAD) {
+ (void) vn_close(savacctp, FWRITE, NOCRED, NULL);
+ savacctp = NULL;
+ return;
+ }
(void)VFS_STATFS(savacctp->v_mount, &sb, (struct proc *)0);
if (sb.f_bavail > acctresume * sb.f_blocks / 100) {
acctp = savacctp;
@@ -105,6 +111,11 @@ acctwatch(a)
} else {
if (acctp == NULL)
return;
+ if (acctp->v_type == VBAD) {
+ (void) vn_close(acctp, FWRITE, NOCRED, NULL);
+ acctp = NULL;
+ return;
+ }
(void)VFS_STATFS(acctp->v_mount, &sb, (struct proc *)0);
if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) {
savacctp = acctp;
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 543946d..3f2e424 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
+ * @(#)kern_descrip.c 8.8 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -55,23 +55,24 @@
#include <sys/unistd.h>
#include <sys/resourcevar.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
/*
* Descriptor management.
*/
-struct file *filehead; /* head of list of open files */
-int nfiles; /* actual number of open files */
+struct filelist filehead; /* head of list of open files */
+int nfiles; /* actual number of open files */
/*
* System calls on descriptors.
*/
-struct getdtablesize_args {
- int dummy;
-};
/* ARGSUSED */
+int
getdtablesize(p, uap, retval)
struct proc *p;
- struct getdtablesize_args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
@@ -81,24 +82,27 @@ getdtablesize(p, uap, retval)
/*
* Duplicate a file descriptor.
*/
-struct dup_args {
- u_int fd;
-};
/* ARGSUSED */
+int
dup(p, uap, retval)
struct proc *p;
- struct dup_args *uap;
- int *retval;
+ struct dup_args /* {
+ syscallarg(u_int) fd;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp;
u_int old;
int new, error;
- old = uap->fd;
+ old = SCARG(uap, fd);
/*
* XXX Compatibility
*/
- if (old &~ 077) { uap->fd &= 077; return (dup2(p, uap, retval)); }
+ if (old &~ 077) {
+ SCARG(uap, fd) &= 077;
+ return (dup2(p, uap, retval));
+ }
fdp = p->p_fd;
if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL)
@@ -111,18 +115,18 @@ dup(p, uap, retval)
/*
* Duplicate a file descriptor to a particular value.
*/
-struct dup2_args {
- u_int from;
- u_int to;
-};
/* ARGSUSED */
+int
dup2(p, uap, retval)
struct proc *p;
- struct dup2_args *uap;
- int *retval;
+ struct dup2_args /* {
+ syscallarg(u_int) from;
+ syscallarg(u_int) to;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
- register u_int old = uap->from, new = uap->to;
+ register int old = SCARG(uap, from), new = SCARG(uap, to);
int i, error;
if (old >= fdp->fd_nfiles ||
@@ -153,17 +157,18 @@ dup2(p, uap, retval)
/*
* The file control system call.
*/
-struct fcntl_args {
- int fd;
- int cmd;
- int arg;
-};
/* ARGSUSED */
+int
fcntl(p, uap, retval)
struct proc *p;
- register struct fcntl_args *uap;
- int *retval;
+ register struct fcntl_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) cmd;
+ syscallarg(void *) arg;
+ } */ *uap;
+ register_t *retval;
{
+ int fd = SCARG(uap, fd);
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
register char *pop;
@@ -172,27 +177,27 @@ fcntl(p, uap, retval)
struct flock fl;
u_int newmin;
- if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ if ((u_int)fd >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fd]) == NULL)
return (EBADF);
- pop = &fdp->fd_ofileflags[uap->fd];
- switch (uap->cmd) {
+ pop = &fdp->fd_ofileflags[fd];
+ switch (SCARG(uap, cmd)) {
case F_DUPFD:
- newmin = uap->arg;
+ newmin = (long)SCARG(uap, arg);
if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
newmin >= maxfiles)
return (EINVAL);
if (error = fdalloc(p, newmin, &i))
return (error);
- return (finishdup(fdp, uap->fd, i, retval));
+ return (finishdup(fdp, fd, i, retval));
case F_GETFD:
*retval = *pop & 1;
return (0);
case F_SETFD:
- *pop = (*pop &~ 1) | (uap->arg & 1);
+ *pop = (*pop &~ 1) | ((long)SCARG(uap, arg) & 1);
return (0);
case F_GETFL:
@@ -201,7 +206,7 @@ fcntl(p, uap, retval)
case F_SETFL:
fp->f_flag &= ~FCNTLFLAGS;
- fp->f_flag |= FFLAGS(uap->arg) & FCNTLFLAGS;
+ fp->f_flag |= FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS;
tmp = fp->f_flag & FNONBLOCK;
error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
if (error)
@@ -221,25 +226,26 @@ fcntl(p, uap, retval)
return (0);
}
error = (*fp->f_ops->fo_ioctl)
- (fp, (int)TIOCGPGRP, (caddr_t)retval, p);
+ (fp, TIOCGPGRP, (caddr_t)retval, p);
*retval = -*retval;
return (error);
case F_SETOWN:
if (fp->f_type == DTYPE_SOCKET) {
- ((struct socket *)fp->f_data)->so_pgid = uap->arg;
+ ((struct socket *)fp->f_data)->so_pgid =
+ (long)SCARG(uap, arg);
return (0);
}
- if (uap->arg <= 0) {
- uap->arg = -uap->arg;
+ if ((long)SCARG(uap, arg) <= 0) {
+ SCARG(uap, arg) = (void *)(-(long)SCARG(uap, arg));
} else {
- struct proc *p1 = pfind(uap->arg);
+ struct proc *p1 = pfind((long)SCARG(uap, arg));
if (p1 == 0)
return (ESRCH);
- uap->arg = p1->p_pgrp->pg_id;
+ SCARG(uap, arg) = (void *)(long)p1->p_pgrp->pg_id;
}
return ((*fp->f_ops->fo_ioctl)
- (fp, (int)TIOCSPGRP, (caddr_t)&uap->arg, p));
+ (fp, TIOCSPGRP, (caddr_t)&SCARG(uap, arg), p));
case F_SETLKW:
flg |= F_WAIT;
@@ -250,7 +256,8 @@ fcntl(p, uap, retval)
return (EBADF);
vp = (struct vnode *)fp->f_data;
/* Copy in the lock structure */
- error = copyin((caddr_t)uap->arg, (caddr_t)&fl, sizeof (fl));
+ error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&fl,
+ sizeof (fl));
if (error)
return (error);
if (fl.l_whence == SEEK_CUR)
@@ -282,14 +289,16 @@ fcntl(p, uap, retval)
return (EBADF);
vp = (struct vnode *)fp->f_data;
/* Copy in the lock structure */
- error = copyin((caddr_t)uap->arg, (caddr_t)&fl, sizeof (fl));
+ error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&fl,
+ sizeof (fl));
if (error)
return (error);
if (fl.l_whence == SEEK_CUR)
fl.l_start += fp->f_offset;
if (error = VOP_ADVLOCK(vp, (caddr_t)p, F_GETLK, &fl, F_POSIX))
return (error);
- return (copyout((caddr_t)&fl, (caddr_t)uap->arg, sizeof (fl)));
+ return (copyout((caddr_t)&fl, (caddr_t)SCARG(uap, arg),
+ sizeof (fl)));
default:
return (EINVAL);
@@ -303,7 +312,8 @@ fcntl(p, uap, retval)
int
finishdup(fdp, old, new, retval)
register struct filedesc *fdp;
- register int old, new, *retval;
+ register int old, new;
+ register_t *retval;
{
register struct file *fp;
@@ -320,21 +330,21 @@ finishdup(fdp, old, new, retval)
/*
* Close a file descriptor.
*/
-struct close_args {
- int fd;
-};
/* ARGSUSED */
+int
close(p, uap, retval)
struct proc *p;
- struct close_args *uap;
- int *retval;
+ struct close_args /* {
+ syscallarg(int) fd;
+ } */ *uap;
+ register_t *retval;
{
+ int fd = SCARG(uap, fd);
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
- register int fd = uap->fd;
register u_char *pf;
- if ((unsigned)fd >= fdp->fd_nfiles ||
+ if ((u_int)fd >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[fd]) == NULL)
return (EBADF);
pf = (u_char *)&fdp->fd_ofileflags[fd];
@@ -353,24 +363,25 @@ close(p, uap, retval)
/*
* Return status information about a file descriptor.
*/
-struct ofstat_args {
- int fd;
- struct ostat *sb;
-};
/* ARGSUSED */
-ofstat(p, uap, retval)
+int
+compat_43_fstat(p, uap, retval)
struct proc *p;
- register struct ofstat_args *uap;
- int *retval;
+ register struct compat_43_fstat_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct ostat *) sb;
+ } */ *uap;
+ register_t *retval;
{
+ int fd = SCARG(uap, fd);
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
struct stat ub;
struct ostat oub;
int error;
- if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ if ((u_int)fd >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fd]) == NULL)
return (EBADF);
switch (fp->f_type) {
@@ -388,7 +399,8 @@ ofstat(p, uap, retval)
}
cvtstat(&ub, &oub);
if (error == 0)
- error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub));
+ error = copyout((caddr_t)&oub, (caddr_t)SCARG(uap, sb),
+ sizeof (oub));
return (error);
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
@@ -396,23 +408,24 @@ ofstat(p, uap, retval)
/*
* Return status information about a file descriptor.
*/
-struct fstat_args {
- int fd;
- struct stat *sb;
-};
/* ARGSUSED */
+int
fstat(p, uap, retval)
struct proc *p;
- register struct fstat_args *uap;
- int *retval;
+ register struct fstat_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct stat *) sb;
+ } */ *uap;
+ register_t *retval;
{
+ int fd = SCARG(uap, fd);
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
struct stat ub;
int error;
- if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ if ((u_int)fd >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fd]) == NULL)
return (EBADF);
switch (fp->f_type) {
@@ -429,41 +442,43 @@ fstat(p, uap, retval)
/*NOTREACHED*/
}
if (error == 0)
- error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
+ error = copyout((caddr_t)&ub, (caddr_t)SCARG(uap, sb),
+ sizeof (ub));
return (error);
}
/*
* Return pathconf information about a file descriptor.
*/
-struct fpathconf_args {
- int fd;
- int name;
-};
/* ARGSUSED */
+int
fpathconf(p, uap, retval)
struct proc *p;
- register struct fpathconf_args *uap;
- int *retval;
+ register struct fpathconf_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) name;
+ } */ *uap;
+ register_t *retval;
{
+ int fd = SCARG(uap, fd);
struct filedesc *fdp = p->p_fd;
struct file *fp;
struct vnode *vp;
- if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ if ((u_int)fd >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fd]) == NULL)
return (EBADF);
switch (fp->f_type) {
case DTYPE_SOCKET:
- if (uap->name != _PC_PIPE_BUF)
+ if (SCARG(uap, name) != _PC_PIPE_BUF)
return (EINVAL);
*retval = PIPE_BUF;
return (0);
case DTYPE_VNODE:
vp = (struct vnode *)fp->f_data;
- return (VOP_PATHCONF(vp, uap->name, retval));
+ return (VOP_PATHCONF(vp, SCARG(uap, name), retval));
default:
panic("fpathconf");
@@ -476,6 +491,7 @@ fpathconf(p, uap, retval)
*/
int fdexpand;
+int
fdalloc(p, want, result)
struct proc *p;
int want;
@@ -544,6 +560,7 @@ fdalloc(p, want, result)
* Check to see whether n user file descriptors
* are available to the process p.
*/
+int
fdavail(p, n)
struct proc *p;
register int n;
@@ -566,12 +583,13 @@ fdavail(p, n)
* Create a new open file structure and allocate
* a file decriptor for the process that refers to it.
*/
+int
falloc(p, resultfp, resultfd)
register struct proc *p;
struct file **resultfp;
int *resultfd;
{
- register struct file *fp, *fq, **fpp;
+ register struct file *fp, *fq;
int error, i;
if (error = fdalloc(p, 0, &i))
@@ -589,16 +607,12 @@ falloc(p, resultfp, resultfd)
nfiles++;
MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK);
bzero(fp, sizeof(struct file));
- if (fq = p->p_fd->fd_ofiles[0])
- fpp = &fq->f_filef;
- else
- fpp = &filehead;
+ if (fq = p->p_fd->fd_ofiles[0]) {
+ LIST_INSERT_AFTER(fq, fp, f_list);
+ } else {
+ LIST_INSERT_HEAD(&filehead, fp, f_list);
+ }
p->p_fd->fd_ofiles[i] = fp;
- if (fq = *fpp)
- fq->f_fileb = &fp->f_filef;
- fp->f_filef = fq;
- fp->f_fileb = fpp;
- *fpp = fp;
fp->f_count = 1;
fp->f_cred = p->p_ucred;
crhold(fp->f_cred);
@@ -612,18 +626,15 @@ falloc(p, resultfp, resultfd)
/*
* Free a file descriptor.
*/
+void
ffree(fp)
register struct file *fp;
{
register struct file *fq;
- if (fq = fp->f_filef)
- fq->f_fileb = fp->f_fileb;
- *fp->f_fileb = fq;
+ LIST_REMOVE(fp, f_list);
crfree(fp->f_cred);
#ifdef DIAGNOSTIC
- fp->f_filef = NULL;
- fp->f_fileb = NULL;
fp->f_count = 0;
#endif
nfiles--;
@@ -714,6 +725,7 @@ fdfree(p)
* Note: p may be NULL when closing a file
* that was being passed in a message.
*/
+int
closef(fp, p)
register struct file *fp;
register struct proc *p;
@@ -766,23 +778,25 @@ closef(fp, p)
* Just attempt to get a record lock of the requested type on
* the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
*/
-struct flock_args {
- int fd;
- int how;
-};
/* ARGSUSED */
+int
flock(p, uap, retval)
struct proc *p;
- register struct flock_args *uap;
- int *retval;
+ register struct flock_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) how;
+ } */ *uap;
+ register_t *retval;
{
+ int fd = SCARG(uap, fd);
+ int how = SCARG(uap, how);
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
struct vnode *vp;
struct flock lf;
- if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ if ((u_int)fd >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fd]) == NULL)
return (EBADF);
if (fp->f_type != DTYPE_VNODE)
return (EOPNOTSUPP);
@@ -790,19 +804,19 @@ flock(p, uap, retval)
lf.l_whence = SEEK_SET;
lf.l_start = 0;
lf.l_len = 0;
- if (uap->how & LOCK_UN) {
+ if (how & LOCK_UN) {
lf.l_type = F_UNLCK;
fp->f_flag &= ~FHASLOCK;
return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));
}
- if (uap->how & LOCK_EX)
+ if (how & LOCK_EX)
lf.l_type = F_WRLCK;
- else if (uap->how & LOCK_SH)
+ else if (how & LOCK_SH)
lf.l_type = F_RDLCK;
else
return (EBADF);
fp->f_flag |= FHASLOCK;
- if (uap->how & LOCK_NB)
+ if (how & LOCK_NB)
return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
}
@@ -816,6 +830,7 @@ flock(p, uap, retval)
* references to this file will be direct to the other driver.
*/
/* ARGSUSED */
+int
fdopen(dev, mode, type, p)
dev_t dev;
int mode, type;
@@ -837,6 +852,7 @@ fdopen(dev, mode, type, p)
/*
* Duplicate the specified descriptor to a free descriptor.
*/
+int
dupfdopen(fdp, indx, dfd, mode, error)
register struct filedesc *fdp;
register int indx, dfd;
@@ -845,7 +861,7 @@ dupfdopen(fdp, indx, dfd, mode, error)
{
register struct file *wfp;
struct file *fp;
-
+
/*
* If the to-be-dup'd fd number is greater than the allowed number
* of file descriptors, or the fd to be dup'd has already been
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 03353c7..4ed48ac 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
+ * @(#)kern_exit.c 8.10 (Berkeley) 2/23/95
*/
#include <sys/param.h>
@@ -163,7 +163,7 @@ exit1(p, rv)
* if we blocked.
*/
if (sp->s_ttyvp)
- vgoneall(sp->s_ttyvp);
+ VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
}
if (sp->s_ttyvp)
vrele(sp->s_ttyvp);
@@ -191,34 +191,19 @@ exit1(p, rv)
* Remove proc from allproc queue and pidhash chain.
* Place onto zombproc. Unlink from parent's child list.
*/
- if (*p->p_prev = p->p_next)
- p->p_next->p_prev = p->p_prev;
- if (p->p_next = zombproc)
- p->p_next->p_prev = &p->p_next;
- p->p_prev = &zombproc;
- zombproc = p;
+ LIST_REMOVE(p, p_list);
+ LIST_INSERT_HEAD(&zombproc, p, p_list);
p->p_stat = SZOMB;
- for (pp = &pidhash[PIDHASH(p->p_pid)]; *pp; pp = &(*pp)->p_hash)
- if (*pp == p) {
- *pp = p->p_hash;
- goto done;
- }
- panic("exit");
-done:
+ LIST_REMOVE(p, p_hash);
- if (p->p_cptr) /* only need this if any child is S_ZOMB */
+ q = p->p_children.lh_first;
+ if (q) /* only need this if any child is S_ZOMB */
wakeup((caddr_t) initproc);
- for (q = p->p_cptr; q != NULL; q = nq) {
- nq = q->p_osptr;
- if (nq != NULL)
- nq->p_ysptr = NULL;
- if (initproc->p_cptr)
- initproc->p_cptr->p_ysptr = q;
- q->p_osptr = initproc->p_cptr;
- q->p_ysptr = NULL;
- initproc->p_cptr = q;
-
+ for (; q != 0; q = nq) {
+ nq = q->p_sibling.le_next;
+ LIST_REMOVE(q, p_sibling);
+ LIST_INSERT_HEAD(&initproc->p_children, q, p_sibling);
q->p_pptr = initproc;
/*
* Traced processes are killed
@@ -229,7 +214,6 @@ done:
psignal(q, SIGKILL);
}
}
- p->p_cptr = NULL;
/*
* Save exit status and final rusage info, adding in child rusage
@@ -293,7 +277,7 @@ struct wait_args {
#define GETPS(rp) (rp)[PS]
#endif
-owait(p, uap, retval)
+compat_43_wait(p, uap, retval)
struct proc *p;
register struct wait_args *uap;
int *retval;
@@ -348,7 +332,7 @@ wait1(q, uap, retval)
#endif
loop:
nfound = 0;
- for (p = q->p_cptr; p; p = p->p_osptr) {
+ for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
if (uap->pid != WAIT_ANY &&
p->p_pid != uap->pid && p->p_pgid != -uap->pid)
continue;
@@ -408,14 +392,8 @@ loop:
* Unlink it from its process group and free it.
*/
leavepgrp(p);
- if (*p->p_prev = p->p_next) /* off zombproc */
- p->p_next->p_prev = p->p_prev;
- if (q = p->p_ysptr)
- q->p_osptr = p->p_osptr;
- if (q = p->p_osptr)
- q->p_ysptr = p->p_ysptr;
- if ((q = p->p_pptr)->p_cptr == p)
- q->p_cptr = p->p_osptr;
+ LIST_REMOVE(p, p_list); /* off zombproc */
+ LIST_REMOVE(p, p_sibling);
/*
* Give machine-dependent layer a chance
@@ -465,28 +443,11 @@ proc_reparent(child, parent)
register struct proc *child;
register struct proc *parent;
{
- register struct proc *o;
- register struct proc *y;
if (child->p_pptr == parent)
return;
- /* fix up the child linkage for the old parent */
- o = child->p_osptr;
- y = child->p_ysptr;
- if (y)
- y->p_osptr = o;
- if (o)
- o->p_ysptr = y;
- if (child->p_pptr->p_cptr == child)
- child->p_pptr->p_cptr = o;
-
- /* fix up child linkage for new parent */
- o = parent->p_cptr;
- if (o)
- o->p_ysptr = child;
- child->p_osptr = o;
- child->p_ysptr = NULL;
- parent->p_cptr = child;
+ LIST_REMOVE(child, p_sibling);
+ LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
child->p_pptr = parent;
}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 8bec2fa..6c5f22f 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
+ * @(#)kern_fork.c 8.8 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -51,14 +51,11 @@
#include <sys/acct.h>
#include <sys/ktrace.h>
-struct fork_args {
- int dummy;
-};
/* ARGSUSED */
fork(p, uap, retval)
struct proc *p;
- struct fork_args *uap;
- int retval[];
+ void *uap;
+ register_t *retval;
{
return (fork1(p, 0, retval));
@@ -67,8 +64,8 @@ fork(p, uap, retval)
/* ARGSUSED */
vfork(p, uap, retval)
struct proc *p;
- struct fork_args *uap;
- int retval[];
+ void *uap;
+ register_t *retval;
{
return (fork1(p, 1, retval));
@@ -78,7 +75,8 @@ int nprocs = 1; /* process 0 */
fork1(p1, isvfork, retval)
register struct proc *p1;
- int isvfork, retval[];
+ int isvfork;
+ register_t *retval;
{
register struct proc *p2;
register uid_t uid;
@@ -99,6 +97,7 @@ fork1(p1, isvfork, retval)
tablefull("proc");
return (EAGAIN);
}
+
/*
* Increment the count of procs running with this uid. Don't allow
* a nonprivileged user to exceed their current limit.
@@ -136,9 +135,9 @@ retry:
* is in use. Remember the lowest pid that's greater
* than nextpid, so we can avoid checking for a while.
*/
- p2 = (struct proc *)allproc;
+ p2 = allproc.lh_first;
again:
- for (; p2 != NULL; p2 = p2->p_next) {
+ for (; p2 != 0; p2 = p2->p_list.le_next) {
while (p2->p_pid == nextpid ||
p2->p_pgrp->pg_id == nextpid) {
nextpid++;
@@ -153,43 +152,18 @@ again:
}
if (!doingzomb) {
doingzomb = 1;
- p2 = zombproc;
+ p2 = zombproc.lh_first;
goto again;
}
}
-
- /*
- * Link onto allproc (this should probably be delayed).
- * Heavy use of volatile here to prevent the compiler from
- * rearranging code. Yes, it *is* terribly ugly, but at least
- * it works.
- */
nprocs++;
p2 = newproc;
-#define Vp2 ((volatile struct proc *)p2)
- Vp2->p_stat = SIDL; /* protect against others */
- Vp2->p_pid = nextpid;
- /*
- * This is really:
- * p2->p_next = allproc;
- * allproc->p_prev = &p2->p_next;
- * p2->p_prev = &allproc;
- * allproc = p2;
- * The assignment via allproc is legal since it is never NULL.
- */
- *(volatile struct proc **)&Vp2->p_next = allproc;
- *(volatile struct proc ***)&allproc->p_prev =
- (volatile struct proc **)&Vp2->p_next;
- *(volatile struct proc ***)&Vp2->p_prev = &allproc;
- allproc = Vp2;
-#undef Vp2
+ p2->p_stat = SIDL; /* protect against others */
+ p2->p_pid = nextpid;
+ LIST_INSERT_HEAD(&allproc, p2, p_list);
p2->p_forw = p2->p_back = NULL; /* shouldn't be necessary */
-
- /* Insert on the hash chain. */
- hash = &pidhash[PIDHASH(p2->p_pid)];
- p2->p_hash = *hash;
- *hash = p2;
+ LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
/*
* Make a proc table entry for the new process.
@@ -238,13 +212,11 @@ again:
p2->p_flag |= P_CONTROLT;
if (isvfork)
p2->p_flag |= P_PPWAIT;
- p2->p_pgrpnxt = p1->p_pgrpnxt;
- p1->p_pgrpnxt = p2;
+ LIST_INSERT_AFTER(p1, p2, p_pglist);
p2->p_pptr = p1;
- p2->p_osptr = p1->p_cptr;
- if (p1->p_cptr)
- p1->p_cptr->p_ysptr = p2;
- p1->p_cptr = p2;
+ LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling);
+ LIST_INIT(&p2->p_children);
+
#ifdef KTRACE
/*
* Copy traceflag and tracefile if enabled.
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 763cfb2..b841754 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -30,12 +30,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_ktrace.c 8.2 (Berkeley) 9/23/93
+ * @(#)kern_ktrace.c 8.5 (Berkeley) 5/14/95
*/
#ifdef KTRACE
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/file.h>
#include <sys/namei.h>
@@ -44,6 +45,9 @@
#include <sys/malloc.h>
#include <sys/syslog.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
struct ktr_header *
ktrgetheader(type)
int type;
@@ -60,23 +64,26 @@ ktrgetheader(type)
return (kth);
}
-ktrsyscall(vp, code, narg, args)
+void
+ktrsyscall(vp, code, argsize, args)
struct vnode *vp;
- int code, narg, args[];
+ int code, argsize;
+ register_t args[];
{
struct ktr_header *kth;
struct ktr_syscall *ktp;
- register len = sizeof(struct ktr_syscall) + (narg * sizeof(int));
+ register len = sizeof(struct ktr_syscall) + argsize;
struct proc *p = curproc; /* XXX */
- int *argp, i;
+ register_t *argp;
+ int i;
p->p_traceflag |= KTRFAC_ACTIVE;
kth = ktrgetheader(KTR_SYSCALL);
MALLOC(ktp, struct ktr_syscall *, len, M_TEMP, M_WAITOK);
ktp->ktr_code = code;
- ktp->ktr_narg = narg;
- argp = (int *)((char *)ktp + sizeof(struct ktr_syscall));
- for (i = 0; i < narg; i++)
+ ktp->ktr_argsize = argsize;
+ argp = (register_t *)((char *)ktp + sizeof(struct ktr_syscall));
+ for (i = 0; i < (argsize / sizeof *argp); i++)
*argp++ = args[i];
kth->ktr_buf = (caddr_t)ktp;
kth->ktr_len = len;
@@ -86,6 +93,7 @@ ktrsyscall(vp, code, narg, args)
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
+void
ktrsysret(vp, code, error, retval)
struct vnode *vp;
int code, error, retval;
@@ -108,6 +116,7 @@ ktrsysret(vp, code, error, retval)
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
+void
ktrnamei(vp, path)
struct vnode *vp;
char *path;
@@ -125,6 +134,7 @@ ktrnamei(vp, path)
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
+void
ktrgenio(vp, fd, rw, iov, len, error)
struct vnode *vp;
int fd;
@@ -166,6 +176,7 @@ done:
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
+void
ktrpsig(vp, sig, action, mask, code)
struct vnode *vp;
int sig;
@@ -190,6 +201,7 @@ ktrpsig(vp, sig, action, mask, code)
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
+void
ktrcsw(vp, out, user)
struct vnode *vp;
int out, user;
@@ -215,24 +227,24 @@ ktrcsw(vp, out, user)
/*
* ktrace system call
*/
-struct ktrace_args {
- char *fname;
- int ops;
- int facs;
- int pid;
-};
/* ARGSUSED */
+int
ktrace(curp, uap, retval)
struct proc *curp;
- register struct ktrace_args *uap;
- int *retval;
+ register struct ktrace_args /* {
+ syscallarg(char *) fname;
+ syscallarg(int) ops;
+ syscallarg(int) facs;
+ syscallarg(int) pid;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp = NULL;
register struct proc *p;
struct pgrp *pg;
- int facs = uap->facs & ~KTRFAC_ROOT;
- int ops = KTROP(uap->ops);
- int descend = uap->ops & KTRFLAG_DESCEND;
+ int facs = SCARG(uap, facs) & ~KTRFAC_ROOT;
+ int ops = KTROP(SCARG(uap, ops));
+ int descend = SCARG(uap, ops) & KTRFLAG_DESCEND;
int ret = 0;
int error = 0;
struct nameidata nd;
@@ -242,13 +254,14 @@ ktrace(curp, uap, retval)
/*
* an operation which requires a file argument.
*/
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, curp);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, fname),
+ curp);
if (error = vn_open(&nd, FREAD|FWRITE, 0)) {
curp->p_traceflag &= ~KTRFAC_ACTIVE;
return (error);
}
vp = nd.ni_vp;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
if (vp->v_type != VREG) {
(void) vn_close(vp, FREAD|FWRITE, curp->p_ucred, curp);
curp->p_traceflag &= ~KTRFAC_ACTIVE;
@@ -259,7 +272,7 @@ ktrace(curp, uap, retval)
* Clear all uses of the tracefile
*/
if (ops == KTROP_CLEARFILE) {
- for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_tracep == vp) {
if (ktrcanset(curp, p)) {
p->p_tracep = NULL;
@@ -282,16 +295,16 @@ ktrace(curp, uap, retval)
/*
* do it
*/
- if (uap->pid < 0) {
+ if (SCARG(uap, pid) < 0) {
/*
* by process group
*/
- pg = pgfind(-uap->pid);
+ pg = pgfind(-SCARG(uap, pid));
if (pg == NULL) {
error = ESRCH;
goto done;
}
- for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt)
+ for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next)
if (descend)
ret |= ktrsetchildren(curp, p, ops, facs, vp);
else
@@ -301,7 +314,7 @@ ktrace(curp, uap, retval)
/*
* by pid
*/
- p = pfind(uap->pid);
+ p = pfind(SCARG(uap, pid));
if (p == NULL) {
error = ESRCH;
goto done;
@@ -373,20 +386,16 @@ ktrsetchildren(curp, top, ops, facs, vp)
* otherwise do any siblings, and if done with this level,
* follow back up the tree (but not past top).
*/
- if (p->p_cptr)
- p = p->p_cptr;
- else if (p == top)
- return (ret);
- else if (p->p_osptr)
- p = p->p_osptr;
+ if (p->p_children.lh_first)
+ p = p->p_children.lh_first;
else for (;;) {
- p = p->p_pptr;
if (p == top)
return (ret);
- if (p->p_osptr) {
- p = p->p_osptr;
+ if (p->p_sibling.le_next) {
+ p = p->p_sibling.le_next;
break;
}
+ p = p->p_pptr;
}
}
/*NOTREACHED*/
@@ -418,9 +427,9 @@ ktrwrite(vp, kth)
aiov[1].iov_len = kth->ktr_len;
auio.uio_resid += kth->ktr_len;
}
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_WRITE(vp, &auio, IO_UNIT|IO_APPEND, p->p_ucred);
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
if (!error)
return;
/*
@@ -428,7 +437,7 @@ ktrwrite(vp, kth)
*/
log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
error);
- for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_tracep == vp) {
p->p_tracep = NULL;
p->p_traceflag = 0;
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index c6276bc..363cde5 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_malloc.c 8.3 (Berkeley) 1/4/94
+ * @(#)kern_malloc.c 8.4 (Berkeley) 5/20/95
*/
#include <sys/param.h>
@@ -103,6 +103,9 @@ malloc(size, type, flags)
int copysize;
char *savedtype;
#endif
+#ifdef DEBUG
+ extern int simplelockrecurse;
+#endif
#ifdef KMEMSTATS
register struct kmemstats *ksp = &kmemstats[type];
@@ -127,6 +130,10 @@ malloc(size, type, flags)
#ifdef DIAGNOSTIC
copysize = 1 << indx < MAX_COPY ? 1 << indx : MAX_COPY;
#endif
+#ifdef DEBUG
+ if (flags & M_NOWAIT)
+ simplelockrecurse++;
+#endif
if (kbp->kb_next == NULL) {
kbp->kb_last = NULL;
if (size > MAXALLOCSAVE)
@@ -138,6 +145,10 @@ malloc(size, type, flags)
!(flags & M_NOWAIT));
if (va == NULL) {
splx(s);
+#ifdef DEBUG
+ if (flags & M_NOWAIT)
+ simplelockrecurse--;
+#endif
return ((void *) NULL);
}
#ifdef KMEMSTATS
@@ -239,6 +250,10 @@ out:
out:
#endif
splx(s);
+#ifdef DEBUG
+ if (flags & M_NOWAIT)
+ simplelockrecurse--;
+#endif
return ((void *) va);
}
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 91d9e21..6701793 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_proc.c 8.4 (Berkeley) 1/4/94
+ * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -53,20 +53,35 @@
* Structure associated with user cacheing.
*/
struct uidinfo {
- struct uidinfo *ui_next;
- struct uidinfo **ui_prev;
+ LIST_ENTRY(uidinfo) ui_hash;
uid_t ui_uid;
long ui_proccnt;
-} **uihashtbl;
-u_long uihash; /* size of hash table - 1 */
-#define UIHASH(uid) ((uid) & uihash)
+};
+#define UIHASH(uid) (&uihashtbl[(uid) & uihash])
+LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
+u_long uihash; /* size of hash table - 1 */
/*
- * Allocate a hash table.
+ * Other process lists
*/
-usrinfoinit()
+struct pidhashhead *pidhashtbl;
+u_long pidhash;
+struct pgrphashhead *pgrphashtbl;
+u_long pgrphash;
+struct proclist allproc;
+struct proclist zombproc;
+
+/*
+ * Initialize global process hashing structures.
+ */
+void
+procinit()
{
+ LIST_INIT(&allproc);
+ LIST_INIT(&zombproc);
+ pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
+ pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
}
@@ -79,10 +94,11 @@ chgproccnt(uid, diff)
uid_t uid;
int diff;
{
- register struct uidinfo **uipp, *uip, *uiq;
+ register struct uidinfo *uip;
+ register struct uihashhead *uipp;
- uipp = &uihashtbl[UIHASH(uid)];
- for (uip = *uipp; uip; uip = uip->ui_next)
+ uipp = UIHASH(uid);
+ for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next)
if (uip->ui_uid == uid)
break;
if (uip) {
@@ -91,9 +107,7 @@ chgproccnt(uid, diff)
return (uip->ui_proccnt);
if (uip->ui_proccnt < 0)
panic("chgproccnt: procs < 0");
- if (uiq = uip->ui_next)
- uiq->ui_prev = uip->ui_prev;
- *uip->ui_prev = uiq;
+ LIST_REMOVE(uip, ui_hash);
FREE(uip, M_PROC);
return (0);
}
@@ -103,11 +117,7 @@ chgproccnt(uid, diff)
panic("chgproccnt: lost user");
}
MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
- if (uiq = *uipp)
- uiq->ui_prev = &uip->ui_next;
- uip->ui_next = uiq;
- uip->ui_prev = uipp;
- *uipp = uip;
+ LIST_INSERT_HEAD(uipp, uip, ui_hash);
uip->ui_uid = uid;
uip->ui_proccnt = diff;
return (diff);
@@ -135,7 +145,7 @@ pfind(pid)
{
register struct proc *p;
- for (p = pidhash[PIDHASH(pid)]; p != NULL; p = p->p_hash)
+ for (p = PIDHASH(pid)->lh_first; p != 0; p = p->p_hash.le_next)
if (p->p_pid == pid)
return (p);
return (NULL);
@@ -150,8 +160,8 @@ pgfind(pgid)
{
register struct pgrp *pgrp;
- for (pgrp = pgrphash[PIDHASH(pgid)];
- pgrp != NULL; pgrp = pgrp->pg_hforw)
+ for (pgrp = PGRPHASH(pgid)->lh_first; pgrp != 0;
+ pgrp = pgrp->pg_hash.le_next)
if (pgrp->pg_id == pgid)
return (pgrp);
return (NULL);
@@ -160,14 +170,13 @@ pgfind(pgid)
/*
* Move p to a new or existing process group (and session)
*/
+int
enterpgrp(p, pgid, mksess)
register struct proc *p;
pid_t pgid;
int mksess;
{
register struct pgrp *pgrp = pgfind(pgid);
- register struct proc **pp;
- int n;
#ifdef DIAGNOSTIC
if (pgrp != NULL && mksess) /* firewalls */
@@ -186,7 +195,7 @@ enterpgrp(p, pgid, mksess)
panic("enterpgrp: new pgrp and pid != pgid");
#endif
MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
- M_WAITOK);
+ M_WAITOK);
if ((np = pfind(savepid)) == NULL || np != p)
return (ESRCH);
if (mksess) {
@@ -196,7 +205,7 @@ enterpgrp(p, pgid, mksess)
* new session
*/
MALLOC(sess, struct session *, sizeof(struct session),
- M_SESSION, M_WAITOK);
+ M_SESSION, M_WAITOK);
sess->s_leader = p;
sess->s_count = 1;
sess->s_ttyvp = NULL;
@@ -214,10 +223,9 @@ enterpgrp(p, pgid, mksess)
pgrp->pg_session->s_count++;
}
pgrp->pg_id = pgid;
- pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)];
- pgrphash[n] = pgrp;
+ LIST_INIT(&pgrp->pg_members);
+ LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
pgrp->pg_jobc = 0;
- pgrp->pg_mem = NULL;
} else if (pgrp == p->p_pgrp)
return (0);
@@ -229,52 +237,24 @@ enterpgrp(p, pgid, mksess)
fixjobc(p, pgrp, 1);
fixjobc(p, p->p_pgrp, 0);
- /*
- * unlink p from old process group
- */
- for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) {
- if (*pp == p) {
- *pp = p->p_pgrpnxt;
- break;
- }
- }
-#ifdef DIAGNOSTIC
- if (pp == NULL)
- panic("enterpgrp: can't find p on old pgrp");
-#endif
- /*
- * delete old if empty
- */
- if (p->p_pgrp->pg_mem == 0)
+ LIST_REMOVE(p, p_pglist);
+ if (p->p_pgrp->pg_members.lh_first == 0)
pgdelete(p->p_pgrp);
- /*
- * link into new one
- */
p->p_pgrp = pgrp;
- p->p_pgrpnxt = pgrp->pg_mem;
- pgrp->pg_mem = p;
+ LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
return (0);
}
/*
* remove process from process group
*/
+int
leavepgrp(p)
register struct proc *p;
{
- register struct proc **pp = &p->p_pgrp->pg_mem;
- for (; *pp; pp = &(*pp)->p_pgrpnxt) {
- if (*pp == p) {
- *pp = p->p_pgrpnxt;
- break;
- }
- }
-#ifdef DIAGNOSTIC
- if (pp == NULL)
- panic("leavepgrp: can't find p in pgrp");
-#endif
- if (!p->p_pgrp->pg_mem)
+ LIST_REMOVE(p, p_pglist);
+ if (p->p_pgrp->pg_members.lh_first == 0)
pgdelete(p->p_pgrp);
p->p_pgrp = 0;
return (0);
@@ -283,24 +263,15 @@ leavepgrp(p)
/*
* delete a process group
*/
+void
pgdelete(pgrp)
register struct pgrp *pgrp;
{
- register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
if (pgrp->pg_session->s_ttyp != NULL &&
pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
pgrp->pg_session->s_ttyp->t_pgrp = NULL;
- for (; *pgp; pgp = &(*pgp)->pg_hforw) {
- if (*pgp == pgrp) {
- *pgp = pgrp->pg_hforw;
- break;
- }
- }
-#ifdef DIAGNOSTIC
- if (pgp == NULL)
- panic("pgdelete: can't find pgrp on hash chain");
-#endif
+ LIST_REMOVE(pgrp, pg_hash);
if (--pgrp->pg_session->s_count == 0)
FREE(pgrp->pg_session, M_SESSION);
FREE(pgrp, M_PGRP);
@@ -318,6 +289,7 @@ static void orphanpg();
* entering == 0 => p is leaving specified group.
* entering == 1 => p is entering specified group.
*/
+void
fixjobc(p, pgrp, entering)
register struct proc *p;
register struct pgrp *pgrp;
@@ -342,7 +314,7 @@ fixjobc(p, pgrp, entering)
* their process groups; if so, adjust counts for children's
* process groups.
*/
- for (p = p->p_cptr; p; p = p->p_osptr)
+ for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next)
if ((hispgrp = p->p_pgrp) != pgrp &&
hispgrp->pg_session == mysession &&
p->p_stat != SZOMB)
@@ -363,9 +335,10 @@ orphanpg(pg)
{
register struct proc *p;
- for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
+ for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) {
if (p->p_stat == SSTOP) {
- for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
+ for (p = pg->pg_members.lh_first; p != 0;
+ p = p->p_pglist.le_next) {
psignal(p, SIGHUP);
psignal(p, SIGCONT);
}
@@ -374,28 +347,28 @@ orphanpg(pg)
}
}
-#ifdef debug
-/* DEBUG */
+#ifdef DEBUG
pgrpdump()
{
register struct pgrp *pgrp;
register struct proc *p;
register i;
- for (i=0; i<PIDHSZ; i++) {
- if (pgrphash[i]) {
- printf("\tindx %d\n", i);
- for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
- printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
- pgrp, pgrp->pg_id, pgrp->pg_session,
- pgrp->pg_session->s_count, pgrp->pg_mem);
- for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
- printf("\t\tpid %d addr %x pgrp %x\n",
- p->p_pid, p, p->p_pgrp);
- }
- }
-
+ for (i = 0; i <= pgrphash; i++) {
+ if (pgrp = pgrphashtbl[i].lh_first) {
+ printf("\tindx %d\n", i);
+ for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) {
+ printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
+ pgrp, pgrp->pg_id, pgrp->pg_session,
+ pgrp->pg_session->s_count,
+ pgrp->pg_members.lh_first);
+ for (p = pgrp->pg_members.lh_first; p != 0;
+ p = p->p_pglist.le_next) {
+ printf("\t\tpid %d addr %x pgrp %x\n",
+ p->p_pid, p, p->p_pgrp);
+ }
+ }
}
}
}
-#endif /* debug */
+#endif /* DEBUG */
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index ef40077..29e4c67 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
+ * @(#)kern_prot.c 8.9 (Berkeley) 2/14/95
*/
/*
@@ -51,15 +51,15 @@
#include <sys/times.h>
#include <sys/malloc.h>
-struct args {
- int dummy;
-};
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
/* ARGSUSED */
+int
getpid(p, uap, retval)
struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_pid;
@@ -70,10 +70,11 @@ getpid(p, uap, retval)
}
/* ARGSUSED */
+int
getppid(p, uap, retval)
struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_pptr->p_pid;
@@ -81,10 +82,11 @@ getppid(p, uap, retval)
}
/* Get process group ID; note that POSIX getpgrp takes no parameter */
+int
getpgrp(p, uap, retval)
struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_pgrp->pg_id;
@@ -92,10 +94,11 @@ getpgrp(p, uap, retval)
}
/* ARGSUSED */
+int
getuid(p, uap, retval)
struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_cred->p_ruid;
@@ -106,10 +109,11 @@ getuid(p, uap, retval)
}
/* ARGSUSED */
+int
geteuid(p, uap, retval)
struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_ucred->cr_uid;
@@ -117,10 +121,11 @@ geteuid(p, uap, retval)
}
/* ARGSUSED */
+int
getgid(p, uap, retval)
struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_cred->p_rgid;
@@ -136,30 +141,31 @@ getgid(p, uap, retval)
* correctly in a library function.
*/
/* ARGSUSED */
+int
getegid(p, uap, retval)
struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_ucred->cr_groups[0];
return (0);
}
-struct getgroups_args {
- u_int gidsetsize;
- gid_t *gidset;
-};
+int
getgroups(p, uap, retval)
struct proc *p;
- register struct getgroups_args *uap;
- int *retval;
+ register struct getgroups_args /* {
+ syscallarg(u_int) gidsetsize;
+ syscallarg(gid_t *) gidset;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
register u_int ngrp;
int error;
- if ((ngrp = uap->gidsetsize) == 0) {
+ if ((ngrp = SCARG(uap, gidsetsize)) == 0) {
*retval = pc->pc_ucred->cr_ngroups;
return (0);
}
@@ -167,17 +173,18 @@ getgroups(p, uap, retval)
return (EINVAL);
ngrp = pc->pc_ucred->cr_ngroups;
if (error = copyout((caddr_t)pc->pc_ucred->cr_groups,
- (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))
+ (caddr_t)SCARG(uap, gidset), ngrp * sizeof(gid_t)))
return (error);
*retval = ngrp;
return (0);
}
/* ARGSUSED */
+int
setsid(p, uap, retval)
register struct proc *p;
- struct args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
@@ -202,21 +209,21 @@ setsid(p, uap, retval)
* there must exist some pid in same session having pgid (EPERM)
* pid must not be session leader (EPERM)
*/
-struct setpgid_args {
- int pid; /* target process id */
- int pgid; /* target pgrp id */
-};
/* ARGSUSED */
+int
setpgid(curp, uap, retval)
struct proc *curp;
- register struct setpgid_args *uap;
- int *retval;
+ register struct setpgid_args /* {
+ syscallarg(int) pid;
+ syscallarg(int) pgid;
+ } */ *uap;
+ register_t *retval;
{
register struct proc *targp; /* target process */
register struct pgrp *pgrp; /* target pgrp */
- if (uap->pid != 0 && uap->pid != curp->p_pid) {
- if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
+ if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != curp->p_pid) {
+ if ((targp = pfind(SCARG(uap, pid))) == 0 || !inferior(targp))
return (ESRCH);
if (targp->p_session != curp->p_session)
return (EPERM);
@@ -226,29 +233,29 @@ setpgid(curp, uap, retval)
targp = curp;
if (SESS_LEADER(targp))
return (EPERM);
- if (uap->pgid == 0)
- uap->pgid = targp->p_pid;
- else if (uap->pgid != targp->p_pid)
- if ((pgrp = pgfind(uap->pgid)) == 0 ||
+ if (SCARG(uap, pgid) == 0)
+ SCARG(uap, pgid) = targp->p_pid;
+ else if (SCARG(uap, pgid) != targp->p_pid)
+ if ((pgrp = pgfind(SCARG(uap, pgid))) == 0 ||
pgrp->pg_session != curp->p_session)
return (EPERM);
- return (enterpgrp(targp, uap->pgid, 0));
+ return (enterpgrp(targp, SCARG(uap, pgid), 0));
}
-struct setuid_args {
- uid_t uid;
-};
/* ARGSUSED */
+int
setuid(p, uap, retval)
struct proc *p;
- struct setuid_args *uap;
- int *retval;
+ struct setuid_args /* {
+ syscallarg(uid_t) uid;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
register uid_t uid;
int error;
- uid = uap->uid;
+ uid = SCARG(uap, uid);
if (uid != pc->p_ruid &&
(error = suser(pc->pc_ucred, &p->p_acflag)))
return (error);
@@ -267,20 +274,20 @@ setuid(p, uap, retval)
return (0);
}
-struct seteuid_args {
- uid_t euid;
-};
/* ARGSUSED */
+int
seteuid(p, uap, retval)
struct proc *p;
- struct seteuid_args *uap;
- int *retval;
+ struct seteuid_args /* {
+ syscallarg(uid_t) euid;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
register uid_t euid;
int error;
- euid = uap->euid;
+ euid = SCARG(uap, euid);
if (euid != pc->p_ruid && euid != pc->p_svuid &&
(error = suser(pc->pc_ucred, &p->p_acflag)))
return (error);
@@ -294,20 +301,20 @@ seteuid(p, uap, retval)
return (0);
}
-struct setgid_args {
- gid_t gid;
-};
/* ARGSUSED */
+int
setgid(p, uap, retval)
struct proc *p;
- struct setgid_args *uap;
- int *retval;
+ struct setgid_args /* {
+ syscallarg(gid_t) gid;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
register gid_t gid;
int error;
- gid = uap->gid;
+ gid = SCARG(uap, gid);
if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
return (error);
pc->pc_ucred = crcopy(pc->pc_ucred);
@@ -318,20 +325,20 @@ setgid(p, uap, retval)
return (0);
}
-struct setegid_args {
- gid_t egid;
-};
/* ARGSUSED */
+int
setegid(p, uap, retval)
struct proc *p;
- struct setegid_args *uap;
- int *retval;
+ struct setegid_args /* {
+ syscallarg(gid_t) egid;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
register gid_t egid;
int error;
- egid = uap->egid;
+ egid = SCARG(uap, egid);
if (egid != pc->p_rgid && egid != pc->p_svgid &&
(error = suser(pc->pc_ucred, &p->p_acflag)))
return (error);
@@ -341,15 +348,15 @@ setegid(p, uap, retval)
return (0);
}
-struct setgroups_args {
- u_int gidsetsize;
- gid_t *gidset;
-};
/* ARGSUSED */
+int
setgroups(p, uap, retval)
struct proc *p;
- struct setgroups_args *uap;
- int *retval;
+ struct setgroups_args /* {
+ syscallarg(u_int) gidsetsize;
+ syscallarg(gid_t *) gidset;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
register u_int ngrp;
@@ -357,10 +364,11 @@ setgroups(p, uap, retval)
if (error = suser(pc->pc_ucred, &p->p_acflag))
return (error);
- if ((ngrp = uap->gidsetsize) > NGROUPS)
+ ngrp = SCARG(uap, gidsetsize);
+ if (ngrp < 1 || ngrp > NGROUPS)
return (EINVAL);
pc->pc_ucred = crcopy(pc->pc_ucred);
- if (error = copyin((caddr_t)uap->gidset,
+ if (error = copyin((caddr_t)SCARG(uap, gidset),
(caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t)))
return (error);
pc->pc_ucred->cr_ngroups = ngrp;
@@ -369,64 +377,89 @@ setgroups(p, uap, retval)
}
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-struct setreuid_args {
- int ruid;
- int euid;
-};
/* ARGSUSED */
-osetreuid(p, uap, retval)
+int
+compat_43_setreuid(p, uap, retval)
register struct proc *p;
- struct setreuid_args *uap;
- int *retval;
+ struct compat_43_setreuid_args /* {
+ syscallarg(int) ruid;
+ syscallarg(int) euid;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
- struct seteuid_args args;
+ union {
+ struct setuid_args sa;
+ struct seteuid_args ea;
+ } args;
/*
- * we assume that the intent of setting ruid is to be able to get
- * back ruid priviledge. So we make sure that we will be able to
- * do so, but do not actually set the ruid.
+ * If ruid == euid then setreuid is being used to emulate setuid,
+ * just do it.
*/
- if (uap->ruid != (uid_t)-1 && uap->ruid != pc->p_ruid &&
- uap->ruid != pc->p_svuid)
+ if (SCARG(uap, ruid) != -1 && SCARG(uap, ruid) == SCARG(uap, euid)) {
+ SCARG(&args.sa, uid) = SCARG(uap, ruid);
+ return (setuid(p, &args.sa, retval));
+ }
+ /*
+ * Otherwise we assume that the intent of setting ruid is to be
+ * able to get back ruid priviledge (i.e. swapping ruid and euid).
+ * So we make sure that we will be able to do so, but do not
+ * actually set the ruid.
+ */
+ if (SCARG(uap, ruid) != (uid_t)-1 && SCARG(uap, ruid) != pc->p_ruid &&
+ SCARG(uap, ruid) != pc->p_svuid)
return (EPERM);
- if (uap->euid == (uid_t)-1)
+ if (SCARG(uap, euid) == (uid_t)-1)
return (0);
- args.euid = uap->euid;
- return (seteuid(p, &args, retval));
+ SCARG(&args.ea, euid) = SCARG(uap, euid);
+ return (seteuid(p, &args.ea, retval));
}
-struct setregid_args {
- int rgid;
- int egid;
-};
/* ARGSUSED */
-osetregid(p, uap, retval)
+int
+compat_43_setregid(p, uap, retval)
register struct proc *p;
- struct setregid_args *uap;
- int *retval;
+ struct compat_43_setregid_args /* {
+ syscallarg(int) rgid;
+ syscallarg(int) egid;
+ } */ *uap;
+ register_t *retval;
{
register struct pcred *pc = p->p_cred;
- struct setegid_args args;
+ union {
+ struct setgid_args sa;
+ struct setegid_args ea;
+ } args;
/*
- * we assume that the intent of setting rgid is to be able to get
- * back rgid priviledge. So we make sure that we will be able to
- * do so, but do not actually set the rgid.
+ * If rgid == egid then setreuid is being used to emulate setgid,
+ * just do it.
+ */
+ if (SCARG(uap, rgid) != -1 && SCARG(uap, rgid) == SCARG(uap, egid)) {
+ SCARG(&args.sa, gid) = SCARG(uap, rgid);
+ return (setgid(p, &args.sa, retval));
+ }
+ /*
+ * Otherwise we assume that the intent of setting rgid is to be
+ * able to get back rgid priviledge (i.e. swapping rgid and egid).
+ * So we make sure that we will be able to do so, but do not
+ * actually set the rgid.
*/
- if (uap->rgid != (gid_t)-1 && uap->rgid != pc->p_rgid &&
- uap->rgid != pc->p_svgid)
+ if (SCARG(uap, rgid) != (gid_t)-1 && SCARG(uap, rgid) != pc->p_rgid &&
+ SCARG(uap, rgid) != pc->p_svgid)
return (EPERM);
- if (uap->egid == (gid_t)-1)
+ if (SCARG(uap, egid) == (gid_t)-1)
return (0);
- args.egid = uap->egid;
- return (setegid(p, &args, retval));
+ SCARG(&args.ea, egid) = SCARG(uap, egid);
+ return (setegid(p, &args.ea, retval));
}
#endif /* defined(COMPAT_43) || defined(COMPAT_SUNOS) */
/*
* Check if gid is a member of the group set.
*/
+int
groupmember(gid, cred)
gid_t gid;
register struct ucred *cred;
@@ -447,9 +480,10 @@ groupmember(gid, cred)
* indicating use of super-powers.
* Returns 0 or error.
*/
+int
suser(cred, acflag)
struct ucred *cred;
- short *acflag;
+ u_short *acflag;
{
if (cred->cr_uid == 0) {
if (acflag)
@@ -477,6 +511,7 @@ crget()
* Free a cred structure.
* Throws away space when ref count gets to 0.
*/
+void
crfree(cr)
struct ucred *cr;
{
@@ -524,40 +559,40 @@ crdup(cr)
/*
* Get login name, if available.
*/
-struct getlogin_args {
- char *namebuf;
- u_int namelen;
-};
/* ARGSUSED */
+int
getlogin(p, uap, retval)
struct proc *p;
- struct getlogin_args *uap;
- int *retval;
+ struct getlogin_args /* {
+ syscallarg(char *) namebuf;
+ syscallarg(u_int) namelen;
+ } */ *uap;
+ register_t *retval;
{
- if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
- uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
+ if (SCARG(uap, namelen) > sizeof (p->p_pgrp->pg_session->s_login))
+ SCARG(uap, namelen) = sizeof (p->p_pgrp->pg_session->s_login);
return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
- (caddr_t) uap->namebuf, uap->namelen));
+ (caddr_t) SCARG(uap, namebuf), SCARG(uap, namelen)));
}
/*
* Set login name.
*/
-struct setlogin_args {
- char *namebuf;
-};
/* ARGSUSED */
+int
setlogin(p, uap, retval)
struct proc *p;
- struct setlogin_args *uap;
- int *retval;
+ struct setlogin_args /* {
+ syscallarg(char *) namebuf;
+ } */ *uap;
+ register_t *retval;
{
int error;
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
- error = copyinstr((caddr_t) uap->namebuf,
+ error = copyinstr((caddr_t) SCARG(uap, namebuf),
(caddr_t) p->p_pgrp->pg_session->s_login,
sizeof (p->p_pgrp->pg_session->s_login) - 1, (u_int *)0);
if (error == ENAMETOOLONG)
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 68e9dfb..569b9d9 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -35,41 +35,48 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_resource.c 8.5 (Berkeley) 1/21/94
+ * @(#)kern_resource.c 8.8 (Berkeley) 2/14/95
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/file.h>
#include <sys/resourcevar.h>
#include <sys/malloc.h>
#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
#include <vm/vm.h>
+int donice __P((struct proc *curp, struct proc *chgp, int n));
+int dosetrlimit __P((struct proc *p, u_int which, struct rlimit *limp));
+
/*
* Resource controls and accounting.
*/
-struct getpriority_args {
- int which;
- int who;
-};
+int
getpriority(curp, uap, retval)
struct proc *curp;
- register struct getpriority_args *uap;
- int *retval;
+ register struct getpriority_args /* {
+ syscallarg(int) which;
+ syscallarg(int) who;
+ } */ *uap;
+ register_t *retval;
{
register struct proc *p;
register int low = PRIO_MAX + 1;
- switch (uap->which) {
+ switch (SCARG(uap, which)) {
case PRIO_PROCESS:
- if (uap->who == 0)
+ if (SCARG(uap, who) == 0)
p = curp;
else
- p = pfind(uap->who);
+ p = pfind(SCARG(uap, who));
if (p == 0)
break;
low = p->p_nice;
@@ -78,11 +85,12 @@ getpriority(curp, uap, retval)
case PRIO_PGRP: {
register struct pgrp *pg;
- if (uap->who == 0)
+ if (SCARG(uap, who) == 0)
pg = curp->p_pgrp;
- else if ((pg = pgfind(uap->who)) == NULL)
+ else if ((pg = pgfind(SCARG(uap, who))) == NULL)
break;
- for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
+ for (p = pg->pg_members.lh_first; p != 0;
+ p = p->p_pglist.le_next) {
if (p->p_nice < low)
low = p->p_nice;
}
@@ -90,13 +98,12 @@ getpriority(curp, uap, retval)
}
case PRIO_USER:
- if (uap->who == 0)
- uap->who = curp->p_ucred->cr_uid;
- for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
- if (p->p_ucred->cr_uid == uap->who &&
+ if (SCARG(uap, who) == 0)
+ SCARG(uap, who) = curp->p_ucred->cr_uid;
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next)
+ if (p->p_ucred->cr_uid == SCARG(uap, who) &&
p->p_nice < low)
low = p->p_nice;
- }
break;
default:
@@ -108,53 +115,54 @@ getpriority(curp, uap, retval)
return (0);
}
-struct setpriority_args {
- int which;
- int who;
- int prio;
-};
/* ARGSUSED */
+int
setpriority(curp, uap, retval)
struct proc *curp;
- register struct setpriority_args *uap;
- int *retval;
+ register struct setpriority_args /* {
+ syscallarg(int) which;
+ syscallarg(int) who;
+ syscallarg(int) prio;
+ } */ *uap;
+ register_t *retval;
{
register struct proc *p;
int found = 0, error = 0;
- switch (uap->which) {
+ switch (SCARG(uap, which)) {
case PRIO_PROCESS:
- if (uap->who == 0)
+ if (SCARG(uap, who) == 0)
p = curp;
else
- p = pfind(uap->who);
+ p = pfind(SCARG(uap, who));
if (p == 0)
break;
- error = donice(curp, p, uap->prio);
+ error = donice(curp, p, SCARG(uap, prio));
found++;
break;
case PRIO_PGRP: {
register struct pgrp *pg;
- if (uap->who == 0)
+ if (SCARG(uap, who) == 0)
pg = curp->p_pgrp;
- else if ((pg = pgfind(uap->who)) == NULL)
+ else if ((pg = pgfind(SCARG(uap, who))) == NULL)
break;
- for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
- error = donice(curp, p, uap->prio);
+ for (p = pg->pg_members.lh_first; p != 0;
+ p = p->p_pglist.le_next) {
+ error = donice(curp, p, SCARG(uap, prio));
found++;
}
break;
}
case PRIO_USER:
- if (uap->who == 0)
- uap->who = curp->p_ucred->cr_uid;
- for (p = (struct proc *)allproc; p != NULL; p = p->p_next)
- if (p->p_ucred->cr_uid == uap->who) {
- error = donice(curp, p, uap->prio);
+ if (SCARG(uap, who) == 0)
+ SCARG(uap, who) = curp->p_ucred->cr_uid;
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next)
+ if (p->p_ucred->cr_uid == SCARG(uap, who)) {
+ error = donice(curp, p, SCARG(uap, prio));
found++;
}
break;
@@ -167,6 +175,7 @@ setpriority(curp, uap, retval)
return (error);
}
+int
donice(curp, chgp, n)
register struct proc *curp, *chgp;
register int n;
@@ -189,71 +198,73 @@ donice(curp, chgp, n)
}
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-struct setrlimit_args {
- u_int which;
- struct orlimit *lim;
-};
/* ARGSUSED */
-osetrlimit(p, uap, retval)
+int
+compat_43_setrlimit(p, uap, retval)
struct proc *p;
- register struct setrlimit_args *uap;
- int *retval;
+ struct compat_43_setrlimit_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct ogetrlimit *) rlp;
+ } */ *uap;
+ register_t *retval;
{
struct orlimit olim;
struct rlimit lim;
int error;
- if (error =
- copyin((caddr_t)uap->lim, (caddr_t)&olim, sizeof (struct orlimit)))
+ if (error = copyin((caddr_t)SCARG(uap, rlp), (caddr_t)&olim,
+ sizeof (struct orlimit)))
return (error);
lim.rlim_cur = olim.rlim_cur;
lim.rlim_max = olim.rlim_max;
- return (dosetrlimit(p, uap->which, &lim));
+ return (dosetrlimit(p, SCARG(uap, which), &lim));
}
-struct getrlimit_args {
- u_int which;
- struct orlimit *rlp;
-};
/* ARGSUSED */
-ogetrlimit(p, uap, retval)
+int
+compat_43_getrlimit(p, uap, retval)
struct proc *p;
- register struct getrlimit_args *uap;
- int *retval;
+ register struct compat_43_getrlimit_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct ogetrlimit *) rlp;
+ } */ *uap;
+ register_t *retval;
{
struct orlimit olim;
- if (uap->which >= RLIM_NLIMITS)
+ if (SCARG(uap, which) >= RLIM_NLIMITS)
return (EINVAL);
- olim.rlim_cur = p->p_rlimit[uap->which].rlim_cur;
+ olim.rlim_cur = p->p_rlimit[SCARG(uap, which)].rlim_cur;
if (olim.rlim_cur == -1)
olim.rlim_cur = 0x7fffffff;
- olim.rlim_max = p->p_rlimit[uap->which].rlim_max;
+ olim.rlim_max = p->p_rlimit[SCARG(uap, which)].rlim_max;
if (olim.rlim_max == -1)
olim.rlim_max = 0x7fffffff;
- return (copyout((caddr_t)&olim, (caddr_t)uap->rlp, sizeof(olim)));
+ return (copyout((caddr_t)&olim, (caddr_t)SCARG(uap, rlp),
+ sizeof(olim)));
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
-struct __setrlimit_args {
- u_int which;
- struct rlimit *lim;
-};
/* ARGSUSED */
+int
setrlimit(p, uap, retval)
struct proc *p;
- register struct __setrlimit_args *uap;
- int *retval;
+ register struct setrlimit_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct rlimit *) rlp;
+ } */ *uap;
+ register_t *retval;
{
struct rlimit alim;
int error;
- if (error =
- copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit)))
+ if (error = copyin((caddr_t)SCARG(uap, rlp), (caddr_t)&alim,
+ sizeof (struct rlimit)))
return (error);
- return (dosetrlimit(p, uap->which, &alim));
+ return (dosetrlimit(p, SCARG(uap, which), &alim));
}
+int
dosetrlimit(p, which, limp)
struct proc *p;
u_int which;
@@ -337,27 +348,28 @@ dosetrlimit(p, which, limp)
return (0);
}
-struct __getrlimit_args {
- u_int which;
- struct rlimit *rlp;
-};
/* ARGSUSED */
+int
getrlimit(p, uap, retval)
struct proc *p;
- register struct __getrlimit_args *uap;
- int *retval;
+ register struct getrlimit_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct rlimit *) rlp;
+ } */ *uap;
+ register_t *retval;
{
- if (uap->which >= RLIM_NLIMITS)
+ if (SCARG(uap, which) >= RLIM_NLIMITS)
return (EINVAL);
- return (copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp,
- sizeof (struct rlimit)));
+ return (copyout((caddr_t)&p->p_rlimit[SCARG(uap, which)],
+ (caddr_t)SCARG(uap, rlp), sizeof (struct rlimit)));
}
/*
* Transform the running time and tick information in proc p into user,
* system, and interrupt time usage.
*/
+void
calcru(p, up, sp, ip)
register struct proc *p;
register struct timeval *up;
@@ -410,19 +422,19 @@ calcru(p, up, sp, ip)
}
}
-struct getrusage_args {
- int who;
- struct rusage *rusage;
-};
/* ARGSUSED */
+int
getrusage(p, uap, retval)
register struct proc *p;
- register struct getrusage_args *uap;
- int *retval;
+ register struct getrusage_args /* {
+ syscallarg(int) who;
+ syscallarg(struct rusage *) rusage;
+ } */ *uap;
+ register_t *retval;
{
register struct rusage *rup;
- switch (uap->who) {
+ switch (SCARG(uap, who)) {
case RUSAGE_SELF:
rup = &p->p_stats->p_ru;
@@ -436,10 +448,11 @@ getrusage(p, uap, retval)
default:
return (EINVAL);
}
- return (copyout((caddr_t)rup, (caddr_t)uap->rusage,
+ return (copyout((caddr_t)rup, (caddr_t)SCARG(uap, rusage),
sizeof (struct rusage)));
}
+void
ruadd(ru, ru2)
register struct rusage *ru, *ru2;
{
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 3dcff92..5683b9c 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
+ * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95
*/
#define SIGPROP /* include signal properties table */
@@ -57,11 +57,16 @@
#include <sys/syslog.h>
#include <sys/stat.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
#include <machine/cpu.h>
#include <vm/vm.h>
#include <sys/user.h> /* for coredump */
+void stop __P((struct proc *p));
+
/*
* Can process p, with pcred pc, send the signal signum to process q?
*/
@@ -73,16 +78,16 @@
(pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
((signum) == SIGCONT && (q)->p_session == (p)->p_session))
-struct sigaction_args {
- int signum;
- struct sigaction *nsa;
- struct sigaction *osa;
-};
/* ARGSUSED */
+int
sigaction(p, uap, retval)
struct proc *p;
- register struct sigaction_args *uap;
- int *retval;
+ register struct sigaction_args /* {
+ syscallarg(int) signum;
+ syscallarg(struct sigaction *) nsa;
+ syscallarg(struct sigaction *) osa;
+ } */ *uap;
+ register_t *retval;
{
struct sigaction vec;
register struct sigaction *sa;
@@ -90,12 +95,12 @@ sigaction(p, uap, retval)
register int signum;
int bit, error;
- signum = uap->signum;
+ signum = SCARG(uap, signum);
if (signum <= 0 || signum >= NSIG ||
signum == SIGKILL || signum == SIGSTOP)
return (EINVAL);
sa = &vec;
- if (uap->osa) {
+ if (SCARG(uap, osa)) {
sa->sa_handler = ps->ps_sigact[signum];
sa->sa_mask = ps->ps_catchmask[signum];
bit = sigmask(signum);
@@ -106,12 +111,12 @@ sigaction(p, uap, retval)
sa->sa_flags |= SA_RESTART;
if (p->p_flag & P_NOCLDSTOP)
sa->sa_flags |= SA_NOCLDSTOP;
- if (error = copyout((caddr_t)sa, (caddr_t)uap->osa,
+ if (error = copyout((caddr_t)sa, (caddr_t)SCARG(uap, osa),
sizeof (vec)))
return (error);
}
- if (uap->nsa) {
- if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
+ if (SCARG(uap, nsa)) {
+ if (error = copyin((caddr_t)SCARG(uap, nsa), (caddr_t)sa,
sizeof (vec)))
return (error);
setsigvec(p, signum, sa);
@@ -119,6 +124,7 @@ sigaction(p, uap, retval)
return (0);
}
+void
setsigvec(p, signum, sa)
register struct proc *p;
int signum;
@@ -233,31 +239,31 @@ execsigs(p)
* and return old mask as return value;
* the library stub does the rest.
*/
-struct sigprocmask_args {
- int how;
- sigset_t mask;
-};
+int
sigprocmask(p, uap, retval)
register struct proc *p;
- struct sigprocmask_args *uap;
- int *retval;
+ struct sigprocmask_args /* {
+ syscallarg(int) how;
+ syscallarg(sigset_t) mask;
+ } */ *uap;
+ register_t *retval;
{
int error = 0;
*retval = p->p_sigmask;
(void) splhigh();
- switch (uap->how) {
+ switch (SCARG(uap, how)) {
case SIG_BLOCK:
- p->p_sigmask |= uap->mask &~ sigcantmask;
+ p->p_sigmask |= SCARG(uap, mask) &~ sigcantmask;
break;
case SIG_UNBLOCK:
- p->p_sigmask &= ~uap->mask;
+ p->p_sigmask &= ~SCARG(uap, mask);
break;
case SIG_SETMASK:
- p->p_sigmask = uap->mask &~ sigcantmask;
+ p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
break;
default:
@@ -268,14 +274,12 @@ sigprocmask(p, uap, retval)
return (error);
}
-struct sigpending_args {
- int dummy;
-};
/* ARGSUSED */
+int
sigpending(p, uap, retval)
struct proc *p;
- struct sigpending_args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
*retval = p->p_siglist;
@@ -286,16 +290,16 @@ sigpending(p, uap, retval)
/*
* Generalized interface signal handler, 4.3-compatible.
*/
-struct osigvec_args {
- int signum;
- struct sigvec *nsv;
- struct sigvec *osv;
-};
/* ARGSUSED */
-osigvec(p, uap, retval)
+int
+compat_43_sigvec(p, uap, retval)
struct proc *p;
- register struct osigvec_args *uap;
- int *retval;
+ register struct compat_43_sigvec_args /* {
+ syscallarg(int) signum;
+ syscallarg(struct sigvec *) nsv;
+ syscallarg(struct sigvec *) osv;
+ } */ *uap;
+ register_t *retval;
{
struct sigvec vec;
register struct sigacts *ps = p->p_sigacts;
@@ -303,12 +307,12 @@ osigvec(p, uap, retval)
register int signum;
int bit, error;
- signum = uap->signum;
+ signum = SCARG(uap, signum);
if (signum <= 0 || signum >= NSIG ||
signum == SIGKILL || signum == SIGSTOP)
return (EINVAL);
sv = &vec;
- if (uap->osv) {
+ if (SCARG(uap, osv)) {
*(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
sv->sv_mask = ps->ps_catchmask[signum];
bit = sigmask(signum);
@@ -321,12 +325,12 @@ osigvec(p, uap, retval)
if (p->p_flag & P_NOCLDSTOP)
sv->sv_flags |= SA_NOCLDSTOP;
#endif
- if (error = copyout((caddr_t)sv, (caddr_t)uap->osv,
+ if (error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv),
sizeof (vec)))
return (error);
}
- if (uap->nsv) {
- if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv,
+ if (SCARG(uap, nsv)) {
+ if (error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv,
sizeof (vec)))
return (error);
#ifdef COMPAT_SUNOS
@@ -345,34 +349,34 @@ osigvec(p, uap, retval)
return (0);
}
-struct osigblock_args {
- int mask;
-};
-osigblock(p, uap, retval)
+int
+compat_43_sigblock(p, uap, retval)
register struct proc *p;
- struct osigblock_args *uap;
- int *retval;
+ struct compat_43_sigblock_args /* {
+ syscallarg(int) mask;
+ } */ *uap;
+ register_t *retval;
{
(void) splhigh();
*retval = p->p_sigmask;
- p->p_sigmask |= uap->mask &~ sigcantmask;
+ p->p_sigmask |= SCARG(uap, mask) &~ sigcantmask;
(void) spl0();
return (0);
}
-struct osigsetmask_args {
- int mask;
-};
-osigsetmask(p, uap, retval)
+int
+compat_43_sigsetmask(p, uap, retval)
struct proc *p;
- struct osigsetmask_args *uap;
- int *retval;
+ struct compat_43_sigsetmask_args /* {
+ syscallarg(int) mask;
+ } */ *uap;
+ register_t *retval;
{
(void) splhigh();
*retval = p->p_sigmask;
- p->p_sigmask = uap->mask &~ sigcantmask;
+ p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
(void) spl0();
return (0);
}
@@ -383,14 +387,14 @@ osigsetmask(p, uap, retval)
* in the meantime. Note nonstandard calling convention:
* libc stub passes mask, not pointer, to save a copyin.
*/
-struct sigsuspend_args {
- sigset_t mask;
-};
/* ARGSUSED */
+int
sigsuspend(p, uap, retval)
register struct proc *p;
- struct sigsuspend_args *uap;
- int *retval;
+ struct sigsuspend_args /* {
+ syscallarg(int) mask;
+ } */ *uap;
+ register_t *retval;
{
register struct sigacts *ps = p->p_sigacts;
@@ -403,7 +407,7 @@ sigsuspend(p, uap, retval)
*/
ps->ps_oldmask = p->p_sigmask;
ps->ps_flags |= SAS_OLDMASK;
- p->p_sigmask = uap->mask &~ sigcantmask;
+ p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
/* void */;
/* always return EINTR rather than ERESTART... */
@@ -411,15 +415,15 @@ sigsuspend(p, uap, retval)
}
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-struct osigstack_args {
- struct sigstack *nss;
- struct sigstack *oss;
-};
/* ARGSUSED */
-osigstack(p, uap, retval)
+int
+compat_43_sigstack(p, uap, retval)
struct proc *p;
- register struct osigstack_args *uap;
- int *retval;
+ register struct compat_43_sigstack_args /* {
+ syscallarg(struct sigstack *) nss;
+ syscallarg(struct sigstack *) oss;
+ } */ *uap;
+ register_t *retval;
{
struct sigstack ss;
struct sigacts *psp;
@@ -428,11 +432,11 @@ osigstack(p, uap, retval)
psp = p->p_sigacts;
ss.ss_sp = psp->ps_sigstk.ss_base;
ss.ss_onstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
- if (uap->oss && (error = copyout((caddr_t)&ss, (caddr_t)uap->oss,
- sizeof (struct sigstack))))
+ if (SCARG(uap, oss) && (error = copyout((caddr_t)&ss,
+ (caddr_t)SCARG(uap, oss), sizeof (struct sigstack))))
return (error);
- if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
- sizeof (ss))) == 0) {
+ if (SCARG(uap, nss) && (error = copyin((caddr_t)SCARG(uap, nss),
+ (caddr_t)&ss, sizeof (ss))) == 0) {
psp->ps_sigstk.ss_base = ss.ss_sp;
psp->ps_sigstk.ss_size = 0;
psp->ps_sigstk.ss_flags |= ss.ss_onstack & SA_ONSTACK;
@@ -442,15 +446,15 @@ osigstack(p, uap, retval)
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
-struct sigaltstack_args {
- struct sigaltstack *nss;
- struct sigaltstack *oss;
-};
/* ARGSUSED */
+int
sigaltstack(p, uap, retval)
struct proc *p;
- register struct sigaltstack_args *uap;
- int *retval;
+ register struct sigaltstack_args /* {
+ syscallarg(struct sigaltstack *) nss;
+ syscallarg(struct sigaltstack *) oss;
+ } */ *uap;
+ register_t *retval;
{
struct sigacts *psp;
struct sigaltstack ss;
@@ -459,12 +463,13 @@ sigaltstack(p, uap, retval)
psp = p->p_sigacts;
if ((psp->ps_flags & SAS_ALTSTACK) == 0)
psp->ps_sigstk.ss_flags |= SA_DISABLE;
- if (uap->oss && (error = copyout((caddr_t)&psp->ps_sigstk,
- (caddr_t)uap->oss, sizeof (struct sigaltstack))))
+ if (SCARG(uap, oss) && (error = copyout((caddr_t)&psp->ps_sigstk,
+ (caddr_t)SCARG(uap, oss), sizeof (struct sigaltstack))))
return (error);
- if (uap->nss == 0)
+ if (SCARG(uap, nss) == 0)
return (0);
- if (error = copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss)))
+ if (error = copyin((caddr_t)SCARG(uap, nss), (caddr_t)&ss,
+ sizeof (ss)))
return (error);
if (ss.ss_flags & SA_DISABLE) {
if (psp->ps_sigstk.ss_flags & SA_ONSTACK)
@@ -480,57 +485,57 @@ sigaltstack(p, uap, retval)
return (0);
}
-struct kill_args {
- int pid;
- int signum;
-};
/* ARGSUSED */
+int
kill(cp, uap, retval)
register struct proc *cp;
- register struct kill_args *uap;
- int *retval;
+ register struct kill_args /* {
+ syscallarg(int) pid;
+ syscallarg(int) signum;
+ } */ *uap;
+ register_t *retval;
{
register struct proc *p;
register struct pcred *pc = cp->p_cred;
- if ((u_int)uap->signum >= NSIG)
+ if ((u_int)SCARG(uap, signum) >= NSIG)
return (EINVAL);
- if (uap->pid > 0) {
+ if (SCARG(uap, pid) > 0) {
/* kill single process */
- if ((p = pfind(uap->pid)) == NULL)
+ if ((p = pfind(SCARG(uap, pid))) == NULL)
return (ESRCH);
- if (!CANSIGNAL(cp, pc, p, uap->signum))
+ if (!CANSIGNAL(cp, pc, p, SCARG(uap, signum)))
return (EPERM);
- if (uap->signum)
- psignal(p, uap->signum);
+ if (SCARG(uap, signum))
+ psignal(p, SCARG(uap, signum));
return (0);
}
- switch (uap->pid) {
+ switch (SCARG(uap, pid)) {
case -1: /* broadcast signal */
- return (killpg1(cp, uap->signum, 0, 1));
+ return (killpg1(cp, SCARG(uap, signum), 0, 1));
case 0: /* signal own process group */
- return (killpg1(cp, uap->signum, 0, 0));
+ return (killpg1(cp, SCARG(uap, signum), 0, 0));
default: /* negative explicit process group */
- return (killpg1(cp, uap->signum, -uap->pid, 0));
+ return (killpg1(cp, SCARG(uap, signum), -SCARG(uap, pid), 0));
}
/* NOTREACHED */
}
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-struct okillpg_args {
- int pgid;
- int signum;
-};
/* ARGSUSED */
-okillpg(p, uap, retval)
+int
+compat_43_killpg(p, uap, retval)
struct proc *p;
- register struct okillpg_args *uap;
- int *retval;
+ register struct compat_43_killpg_args /* {
+ syscallarg(int) pgid;
+ syscallarg(int) signum;
+ } */ *uap;
+ register_t *retval;
{
- if ((u_int)uap->signum >= NSIG)
+ if ((u_int)SCARG(uap, signum) >= NSIG)
return (EINVAL);
- return (killpg1(p, uap->signum, uap->pgid, 0));
+ return (killpg1(p, SCARG(uap, signum), SCARG(uap, pgid), 0));
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
@@ -538,6 +543,7 @@ okillpg(p, uap, retval)
* Common code for kill process group/broadcast kill.
* cp is calling process.
*/
+int
killpg1(cp, signum, pgid, all)
register struct proc *cp;
int signum, pgid, all;
@@ -551,7 +557,7 @@ killpg1(cp, signum, pgid, all)
/*
* broadcast
*/
- for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p == cp || !CANSIGNAL(cp, pc, p, signum))
continue;
@@ -570,7 +576,8 @@ killpg1(cp, signum, pgid, all)
if (pgrp == NULL)
return (ESRCH);
}
- for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) {
+ for (p = pgrp->pg_members.lh_first; p != 0;
+ p = p->p_pglist.le_next) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p->p_stat == SZOMB ||
!CANSIGNAL(cp, pc, p, signum))
@@ -597,7 +604,7 @@ gsignal(pgid, signum)
}
/*
- * Send a signal to a process group. If checktty is 1,
+ * Send a signal to a process group. If checktty is 1,
* limit to members which have a controlling terminal.
*/
void
@@ -608,7 +615,8 @@ pgsignal(pgrp, signum, checkctty)
register struct proc *p;
if (pgrp)
- for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt)
+ for (p = pgrp->pg_members.lh_first; p != 0;
+ p = p->p_pglist.le_next)
if (checkctty == 0 || p->p_flag & P_CONTROLT)
psignal(p, signum);
}
@@ -622,7 +630,7 @@ void
trapsignal(p, signum, code)
struct proc *p;
register int signum;
- u_int code;
+ u_long code;
{
register struct sigacts *ps = p->p_sigacts;
int mask;
@@ -640,6 +648,7 @@ trapsignal(p, signum, code)
p->p_sigmask |= ps->ps_catchmask[signum] | mask;
} else {
ps->ps_code = code; /* XXX for core dump/debugger */
+ ps->ps_sig = signum; /* XXX to verify code */
psignal(p, signum);
}
}
@@ -710,7 +719,7 @@ psignal(p, signum)
*/
if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
action == SIG_DFL)
- return;
+ return;
p->p_siglist &= ~contsigmask;
}
p->p_siglist |= mask;
@@ -864,6 +873,7 @@ out:
* while (signum = CURSIG(curproc))
* postsig(signum);
*/
+int
issignal(p)
register struct proc *p;
{
@@ -890,8 +900,17 @@ issignal(p)
/*
* If traced, always stop, and stay
* stopped until released by the parent.
+ *
+ * Note that we must clear the pending signal
+ * before we call trace_req since that routine
+ * might cause a fault, calling tsleep and
+ * leading us back here again with the same signal.
+ * Then we would be deadlocked because the tracer
+ * would still be blocked on the ipc struct from
+ * the initial request.
*/
p->p_xstat = signum;
+ p->p_siglist &= ~mask;
psignal(p->p_pptr, SIGCHLD);
do {
stop(p);
@@ -899,19 +918,10 @@ issignal(p)
} while (!trace_req(p) && p->p_flag & P_TRACED);
/*
- * If the traced bit got turned off, go back up
- * to the top to rescan signals. This ensures
- * that p_sig* and ps_sigact are consistent.
- */
- if ((p->p_flag & P_TRACED) == 0)
- continue;
-
- /*
* If parent wants us to take the signal,
* then it will leave it in p->p_xstat;
* otherwise we just look for signals again.
*/
- p->p_siglist &= ~mask; /* clear the old signal */
signum = p->p_xstat;
if (signum == 0)
continue;
@@ -924,6 +934,14 @@ issignal(p)
p->p_siglist |= mask;
if (p->p_sigmask & mask)
continue;
+
+ /*
+ * If the traced bit got turned off, go back up
+ * to the top to rescan signals. This ensures
+ * that p_sig* and ps_sigact are consistent.
+ */
+ if ((p->p_flag & P_TRACED) == 0)
+ continue;
}
/*
@@ -931,9 +949,9 @@ issignal(p)
* Return the signal's number, or fall through
* to clear it from the pending mask.
*/
- switch ((int)p->p_sigacts->ps_sigact[signum]) {
+ switch ((long)p->p_sigacts->ps_sigact[signum]) {
- case SIG_DFL:
+ case (long)SIG_DFL:
/*
* Don't take default actions on system processes.
*/
@@ -976,7 +994,7 @@ issignal(p)
return (signum);
/*NOTREACHED*/
- case SIG_IGN:
+ case (long)SIG_IGN:
/*
* Masking above should prevent us ever trying
* to take action on an ignored signal other
@@ -1004,6 +1022,7 @@ issignal(p)
* via wakeup. Signals are handled elsewhere. The process must not be
* on the run queue.
*/
+void
stop(p)
register struct proc *p;
{
@@ -1024,7 +1043,8 @@ postsig(signum)
register struct proc *p = curproc;
register struct sigacts *ps = p->p_sigacts;
register sig_t action;
- int code, mask, returnmask;
+ u_long code;
+ int mask, returnmask;
#ifdef DIAGNOSTIC
if (signum == 0)
@@ -1077,6 +1097,7 @@ postsig(signum)
} else {
code = ps->ps_code;
ps->ps_code = 0;
+ ps->ps_sig = 0;
}
sendsig(action, signum, returnmask, code);
}
@@ -1085,6 +1106,7 @@ postsig(signum)
/*
* Kill the current process for stated reason.
*/
+void
killproc(p, why)
struct proc *p;
char *why;
@@ -1103,6 +1125,7 @@ killproc(p, why)
* If dumping core, save the signal number for the debugger. Calls exit and
* does not return.
*/
+void
sigexit(p, signum)
register struct proc *p;
int signum;
@@ -1122,6 +1145,7 @@ sigexit(p, signum)
* Dump core, into a file named "progname.core", unless the process was
* setuid/setgid.
*/
+int
coredump(p)
register struct proc *p;
{
@@ -1154,7 +1178,7 @@ coredump(p)
}
VATTR_NULL(&vattr);
vattr.va_size = 0;
- LEASE_CHECK(vp, p, cred, LEASE_WRITE);
+ VOP_LEASE(vp, p, cred, LEASE_WRITE);
VOP_SETATTR(vp, &vattr, cred, p);
p->p_acflag |= ACORE;
bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
@@ -1171,7 +1195,7 @@ coredump(p)
(off_t)ctob(UPAGES) + ctob(vm->vm_dsize), UIO_USERSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
out:
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
error1 = vn_close(vp, FWRITE, cred, p);
if (error == 0)
error = error1;
@@ -1182,16 +1206,14 @@ out:
* Nonexistent system call-- signal process (may want to handle it).
* Flag error in case process won't see signal immediately (blocked or ignored).
*/
-struct nosys_args {
- int dummy;
-};
/* ARGSUSED */
+int
nosys(p, args, retval)
struct proc *p;
- struct nosys_args *args;
- int *retval;
+ void *args;
+ register_t *retval;
{
psignal(p, SIGSYS);
- return (EINVAL);
+ return (ENOSYS);
}
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index 5c12afc..df83710 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
+ * @(#)kern_subr.c 8.4 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -44,6 +44,7 @@
#include <sys/malloc.h>
#include <sys/queue.h>
+int
uiomove(cp, n, uio)
register caddr_t cp;
register int n;
@@ -101,17 +102,20 @@ uiomove(cp, n, uio)
/*
* Give next character to user as result of read.
*/
+int
ureadc(c, uio)
register int c;
register struct uio *uio;
{
register struct iovec *iov;
+ if (uio->uio_resid <= 0)
+ panic("ureadc: non-positive resid");
again:
- if (uio->uio_iovcnt == 0 || uio->uio_resid == 0)
- panic("ureadc");
+ if (uio->uio_iovcnt <= 0)
+ panic("ureadc: non-positive iovcnt");
iov = uio->uio_iov;
- if (iov->iov_len == 0) {
+ if (iov->iov_len <= 0) {
uio->uio_iovcnt--;
uio->uio_iov++;
goto again;
@@ -143,6 +147,7 @@ again:
/*
* Get next character written in by user from uio.
*/
+int
uwritec(uio)
struct uio *uio;
{
@@ -153,7 +158,7 @@ uwritec(uio)
return (-1);
again:
if (uio->uio_iovcnt <= 0)
- panic("uwritec");
+ panic("uwritec: non-positive iovcnt");
iov = uio->uio_iov;
if (iov->iov_len == 0) {
uio->uio_iov++;
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 1c2a578..6c82027 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_synch.c 8.6 (Berkeley) 1/21/94
+ * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
*/
#include <sys/param.h>
@@ -167,7 +167,7 @@ schedcpu(arg)
register unsigned int newcpu;
wakeup((caddr_t)&lbolt);
- for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
/*
* Increment time in/out of memory and sleep time
* (if sleeping). We ignore overflow; with 16-bit int's
@@ -249,7 +249,7 @@ updatepri(p)
* of 2. Shift right by 8, i.e. drop the bottom 256 worth.
*/
#define TABLESIZE 128
-#define LOOKUP(x) (((int)(x) >> 8) & (TABLESIZE - 1))
+#define LOOKUP(x) (((long)(x) >> 8) & (TABLESIZE - 1))
struct slpque {
struct proc *sq_head;
struct proc **sq_tailp;
@@ -551,6 +551,10 @@ mi_switch()
register long s, u;
struct timeval tv;
+#ifdef DEBUG
+ if (p->p_simple_locks)
+ panic("sleep: holding simple lock");
+#endif
/*
* Compute the amount of time during which the current
* process was running, and add that to its total so far.
@@ -600,6 +604,7 @@ mi_switch()
* Initialize the (doubly-linked) run queues
* to be empty.
*/
+void
rqinit()
{
register int i;
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index ae16dec..b178da3 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
+ * @(#)kern_sysctl.c 8.9 (Berkeley) 5/20/95
*/
/*
@@ -54,13 +54,16 @@
#include <vm/vm.h>
#include <sys/sysctl.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
sysctlfn kern_sysctl;
sysctlfn hw_sysctl;
#ifdef DEBUG
sysctlfn debug_sysctl;
#endif
extern sysctlfn vm_sysctl;
-extern sysctlfn fs_sysctl;
+extern sysctlfn vfs_sysctl;
extern sysctlfn net_sysctl;
extern sysctlfn cpu_sysctl;
@@ -73,40 +76,40 @@ static struct sysctl_lock {
int sl_locked;
} memlock;
-struct sysctl_args {
- int *name;
- u_int namelen;
- void *old;
- size_t *oldlenp;
- void *new;
- size_t newlen;
-};
-
int
__sysctl(p, uap, retval)
struct proc *p;
- register struct sysctl_args *uap;
- int *retval;
+ register struct __sysctl_args /* {
+ syscallarg(int *) name;
+ syscallarg(u_int) namelen;
+ syscallarg(void *) old;
+ syscallarg(size_t *) oldlenp;
+ syscallarg(void *) new;
+ syscallarg(size_t) newlen;
+ } */ *uap;
+ register_t *retval;
{
int error, dolock = 1;
- u_int savelen, oldlen = 0;
+ size_t savelen, oldlen = 0;
sysctlfn *fn;
int name[CTL_MAXNAME];
- if (uap->new != NULL && (error = suser(p->p_ucred, &p->p_acflag)))
+ if (SCARG(uap, new) != NULL &&
+ (error = suser(p->p_ucred, &p->p_acflag)))
return (error);
/*
* all top-level sysctl names are non-terminal
*/
- if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
+ if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
return (EINVAL);
- if (error = copyin(uap->name, &name, uap->namelen * sizeof(int)))
+ if (error =
+ copyin(SCARG(uap, name), &name, SCARG(uap, namelen) * sizeof(int)))
return (error);
switch (name[0]) {
case CTL_KERN:
fn = kern_sysctl;
- if (name[2] != KERN_VNODE) /* XXX */
+ if (name[2] == KERN_VNODE) /* XXX */
dolock = 0;
break;
case CTL_HW:
@@ -118,11 +121,9 @@ __sysctl(p, uap, retval)
case CTL_NET:
fn = net_sysctl;
break;
-#ifdef notyet
- case CTL_FS:
- fn = fs_sysctl;
+ case CTL_VFS:
+ fn = vfs_sysctl;
break;
-#endif
case CTL_MACHDEP:
fn = cpu_sysctl;
break;
@@ -135,11 +136,11 @@ __sysctl(p, uap, retval)
return (EOPNOTSUPP);
}
- if (uap->oldlenp &&
- (error = copyin(uap->oldlenp, &oldlen, sizeof(oldlen))))
+ if (SCARG(uap, oldlenp) &&
+ (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen))))
return (error);
- if (uap->old != NULL) {
- if (!useracc(uap->old, oldlen, B_WRITE))
+ if (SCARG(uap, old) != NULL) {
+ if (!useracc(SCARG(uap, old), oldlen, B_WRITE))
return (EFAULT);
while (memlock.sl_lock) {
memlock.sl_want = 1;
@@ -148,14 +149,14 @@ __sysctl(p, uap, retval)
}
memlock.sl_lock = 1;
if (dolock)
- vslock(uap->old, oldlen);
+ vslock(SCARG(uap, old), oldlen);
savelen = oldlen;
}
- error = (*fn)(name + 1, uap->namelen - 1, uap->old, &oldlen,
- uap->new, uap->newlen, p);
- if (uap->old != NULL) {
+ error = (*fn)(name + 1, SCARG(uap, namelen) - 1, SCARG(uap, old),
+ &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
+ if (SCARG(uap, old) != NULL) {
if (dolock)
- vsunlock(uap->old, savelen, B_WRITE);
+ vsunlock(SCARG(uap, old), savelen, B_WRITE);
memlock.sl_lock = 0;
if (memlock.sl_want) {
memlock.sl_want = 0;
@@ -164,8 +165,8 @@ __sysctl(p, uap, retval)
}
if (error)
return (error);
- if (uap->oldlenp)
- error = copyout(&oldlen, uap->oldlenp, sizeof(oldlen));
+ if (SCARG(uap, oldlenp))
+ error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen));
*retval = oldlen;
return (0);
}
@@ -240,7 +241,7 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime,
sizeof(struct timeval)));
case KERN_VNODE:
- return (sysctl_vnode(oldp, oldlenp));
+ return (sysctl_vnode(oldp, oldlenp, p));
case KERN_PROC:
return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));
case KERN_FILE:
@@ -338,7 +339,7 @@ debug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
if (namelen != 2)
return (ENOTDIR); /* overloaded */
cdp = debugvars[name[0]];
- if (cdp->debugname == 0)
+ if (name[0] >= CTL_DEBUG_MAXID || cdp->debugname == 0)
return (EOPNOTSUPP);
switch (name[1]) {
case CTL_DEBUG_NAME:
@@ -534,7 +535,7 @@ sysctl_file(where, sizep)
/*
* followed by an array of file structures
*/
- for (fp = filehead; fp != NULL; fp = fp->f_filef) {
+ for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) {
if (buflen < sizeof(struct file)) {
*sizep = where - start;
return (ENOMEM);
@@ -569,10 +570,10 @@ sysctl_doproc(name, namelen, where, sizep)
if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
return (EINVAL);
- p = (struct proc *)allproc;
+ p = allproc.lh_first;
doingzomb = 0;
again:
- for (; p != NULL; p = p->p_next) {
+ for (; p != 0; p = p->p_list.le_next) {
/*
* Skip embryonic processes.
*/
@@ -627,7 +628,7 @@ again:
needed += sizeof(struct kinfo_proc);
}
if (doingzomb == 0) {
- p = zombproc;
+ p = zombproc.lh_first;
doingzomb++;
goto again;
}
@@ -711,66 +712,71 @@ fill_eproc(p, ep)
#define KINFO_LOADAVG (5<<8)
#define KINFO_CLOCKRATE (6<<8)
-struct getkerninfo_args {
- int op;
- char *where;
- int *size;
- int arg;
-};
-
-ogetkerninfo(p, uap, retval)
+compat_43_getkerninfo(p, uap, retval)
struct proc *p;
- register struct getkerninfo_args *uap;
- int *retval;
+ register struct compat_43_getkerninfo_args /* {
+ syscallarg(int) op;
+ syscallarg(char *) where;
+ syscallarg(int *) size;
+ syscallarg(int) arg;
+ } */ *uap;
+ register_t *retval;
{
int error, name[5];
- u_int size;
+ size_t size;
- if (uap->size &&
- (error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size))))
+ if (SCARG(uap, size) && (error = copyin((caddr_t)SCARG(uap, size),
+ (caddr_t)&size, sizeof(size))))
return (error);
- switch (uap->op & 0xff00) {
+ switch (SCARG(uap, op) & 0xff00) {
case KINFO_RT:
name[0] = PF_ROUTE;
name[1] = 0;
- name[2] = (uap->op & 0xff0000) >> 16;
- name[3] = uap->op & 0xff;
- name[4] = uap->arg;
- error = net_sysctl(name, 5, uap->where, &size, NULL, 0, p);
+ name[2] = (SCARG(uap, op) & 0xff0000) >> 16;
+ name[3] = SCARG(uap, op) & 0xff;
+ name[4] = SCARG(uap, arg);
+ error =
+ net_sysctl(name, 5, SCARG(uap, where), &size, NULL, 0, p);
break;
case KINFO_VNODE:
name[0] = KERN_VNODE;
- error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p);
+ error =
+ kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
break;
case KINFO_PROC:
name[0] = KERN_PROC;
- name[1] = uap->op & 0xff;
- name[2] = uap->arg;
- error = kern_sysctl(name, 3, uap->where, &size, NULL, 0, p);
+ name[1] = SCARG(uap, op) & 0xff;
+ name[2] = SCARG(uap, arg);
+ error =
+ kern_sysctl(name, 3, SCARG(uap, where), &size, NULL, 0, p);
break;
case KINFO_FILE:
name[0] = KERN_FILE;
- error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p);
+ error =
+ kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
break;
case KINFO_METER:
name[0] = VM_METER;
- error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p);
+ error =
+ vm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
break;
case KINFO_LOADAVG:
name[0] = VM_LOADAVG;
- error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p);
+ error =
+ vm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
break;
case KINFO_CLOCKRATE:
name[0] = KERN_CLOCKRATE;
- error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p);
+ error =
+ kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
break;
default:
@@ -779,8 +785,8 @@ ogetkerninfo(p, uap, retval)
if (error)
return (error);
*retval = size;
- if (uap->size)
- error = copyout((caddr_t)&size, (caddr_t)uap->size,
+ if (SCARG(uap, size))
+ error = copyout((caddr_t)&size, (caddr_t)SCARG(uap, size),
sizeof(size));
return (error);
}
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 4dadcb8..f4facf6 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_time.c 8.1 (Berkeley) 6/10/93
+ * @(#)kern_time.c 8.4 (Berkeley) 5/26/95
*/
#include <sys/param.h>
@@ -40,6 +40,9 @@
#include <sys/proc.h>
#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
#include <machine/cpu.h>
/*
@@ -52,40 +55,40 @@
* timers when they expire.
*/
-struct gettimeofday_args {
- struct timeval *tp;
- struct timezone *tzp;
-};
/* ARGSUSED */
+int
gettimeofday(p, uap, retval)
struct proc *p;
- register struct gettimeofday_args *uap;
- int *retval;
+ register struct gettimeofday_args /* {
+ syscallarg(struct timeval *) tp;
+ syscallarg(struct timezone *) tzp;
+ } */ *uap;
+ register_t *retval;
{
struct timeval atv;
int error = 0;
- if (uap->tp) {
+ if (SCARG(uap, tp)) {
microtime(&atv);
- if (error = copyout((caddr_t)&atv, (caddr_t)uap->tp,
+ if (error = copyout((caddr_t)&atv, (caddr_t)SCARG(uap, tp),
sizeof (atv)))
return (error);
}
- if (uap->tzp)
- error = copyout((caddr_t)&tz, (caddr_t)uap->tzp,
+ if (SCARG(uap, tzp))
+ error = copyout((caddr_t)&tz, (caddr_t)SCARG(uap, tzp),
sizeof (tz));
return (error);
}
-struct settimeofday_args {
- struct timeval *tv;
- struct timezone *tzp;
-};
/* ARGSUSED */
+int
settimeofday(p, uap, retval)
struct proc *p;
- struct settimeofday_args *uap;
- int *retval;
+ struct settimeofday_args /* {
+ syscallarg(struct timeval *) tv;
+ syscallarg(struct timezone *) tzp;
+ } */ *uap;
+ register_t *retval;
{
struct timeval atv, delta;
struct timezone atz;
@@ -94,13 +97,21 @@ settimeofday(p, uap, retval)
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
/* Verify all parameters before changing time. */
- if (uap->tv &&
- (error = copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof(atv))))
+ if (SCARG(uap, tv) && (error = copyin((caddr_t)SCARG(uap, tv),
+ (caddr_t)&atv, sizeof(atv))))
return (error);
- if (uap->tzp &&
- (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz))))
+ if (SCARG(uap, tzp) && (error = copyin((caddr_t)SCARG(uap, tzp),
+ (caddr_t)&atz, sizeof(atz))))
return (error);
- if (uap->tv) {
+ if (SCARG(uap, tv)) {
+ /*
+ * If the system is secure, we do not allow the time to be
+ * set to an earlier value (it may be slowed using adjtime,
+ * but not set back). This feature prevent interlopers from
+ * setting arbitrary time stamps on files.
+ */
+ if (securelevel > 0 && timercmp(&atv, &time, <))
+ return (EPERM);
/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
s = splclock();
/* nb. delta.tv_usec may be < 0, but this is OK here */
@@ -112,11 +123,13 @@ settimeofday(p, uap, retval)
timevalfix(&boottime);
timevaladd(&runtime, &delta);
timevalfix(&runtime);
- LEASE_UPDATETIME(delta.tv_sec);
+# ifdef NFS
+ lease_updatetime(delta.tv_sec);
+# endif
splx(s);
resettodr();
}
- if (uap->tzp)
+ if (SCARG(uap, tzp))
tz = atz;
return (0);
}
@@ -126,15 +139,15 @@ int tickdelta; /* current clock skew, us. per tick */
long timedelta; /* unapplied time correction, us. */
long bigadj = 1000000; /* use 10x skew above bigadj us. */
-struct adjtime_args {
- struct timeval *delta;
- struct timeval *olddelta;
-};
/* ARGSUSED */
+int
adjtime(p, uap, retval)
struct proc *p;
- register struct adjtime_args *uap;
- int *retval;
+ register struct adjtime_args /* {
+ syscallarg(struct timeval *) delta;
+ syscallarg(struct timeval *) olddelta;
+ } */ *uap;
+ register_t *retval;
{
struct timeval atv;
register long ndelta, ntickdelta, odelta;
@@ -142,8 +155,8 @@ adjtime(p, uap, retval)
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
- if (error =
- copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval)))
+ if (error = copyin((caddr_t)SCARG(uap, delta), (caddr_t)&atv,
+ sizeof(struct timeval)))
return (error);
/*
@@ -174,10 +187,10 @@ adjtime(p, uap, retval)
tickdelta = ntickdelta;
splx(s);
- if (uap->olddelta) {
+ if (SCARG(uap, olddelta)) {
atv.tv_sec = odelta / 1000000;
atv.tv_usec = odelta % 1000000;
- (void) copyout((caddr_t)&atv, (caddr_t)uap->olddelta,
+ (void) copyout((caddr_t)&atv, (caddr_t)SCARG(uap, olddelta),
sizeof(struct timeval));
}
return (0);
@@ -204,25 +217,25 @@ adjtime(p, uap, retval)
* real time timers .it_interval. Rather, we compute the next time in
* absolute time the timer should go off.
*/
-struct getitimer_args {
- u_int which;
- struct itimerval *itv;
-};
/* ARGSUSED */
+int
getitimer(p, uap, retval)
struct proc *p;
- register struct getitimer_args *uap;
- int *retval;
+ register struct getitimer_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct itimerval *) itv;
+ } */ *uap;
+ register_t *retval;
{
struct itimerval aitv;
int s;
- if (uap->which > ITIMER_PROF)
+ if (SCARG(uap, which) > ITIMER_PROF)
return (EINVAL);
s = splclock();
- if (uap->which == ITIMER_REAL) {
+ if (SCARG(uap, which) == ITIMER_REAL) {
/*
- * Convert from absoulte to relative time in .it_value
+ * Convert from absolute to relative time in .it_value
* part of real time timer. If time for real time timer
* has passed return 0, else return difference between
* current time and time for the timer to go off.
@@ -235,40 +248,42 @@ getitimer(p, uap, retval)
timevalsub(&aitv.it_value,
(struct timeval *)&time);
} else
- aitv = p->p_stats->p_timer[uap->which];
+ aitv = p->p_stats->p_timer[SCARG(uap, which)];
splx(s);
- return (copyout((caddr_t)&aitv, (caddr_t)uap->itv,
+ return (copyout((caddr_t)&aitv, (caddr_t)SCARG(uap, itv),
sizeof (struct itimerval)));
}
-struct setitimer_args {
- u_int which;
- struct itimerval *itv, *oitv;
-};
/* ARGSUSED */
+int
setitimer(p, uap, retval)
struct proc *p;
- register struct setitimer_args *uap;
- int *retval;
+ register struct setitimer_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct itimerval *) itv;
+ syscallarg(struct itimerval *) oitv;
+ } */ *uap;
+ register_t *retval;
{
struct itimerval aitv;
register struct itimerval *itvp;
int s, error;
- if (uap->which > ITIMER_PROF)
+ if (SCARG(uap, which) > ITIMER_PROF)
return (EINVAL);
- itvp = uap->itv;
+ itvp = SCARG(uap, itv);
if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv,
sizeof(struct itimerval))))
return (error);
- if ((uap->itv = uap->oitv) && (error = getitimer(p, uap, retval)))
+ if ((SCARG(uap, itv) = SCARG(uap, oitv)) &&
+ (error = getitimer(p, uap, retval)))
return (error);
if (itvp == 0)
return (0);
if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
return (EINVAL);
s = splclock();
- if (uap->which == ITIMER_REAL) {
+ if (SCARG(uap, which) == ITIMER_REAL) {
untimeout(realitexpire, (caddr_t)p);
if (timerisset(&aitv.it_value)) {
timevaladd(&aitv.it_value, (struct timeval *)&time);
@@ -276,7 +291,7 @@ setitimer(p, uap, retval)
}
p->p_realtimer = aitv;
} else
- p->p_stats->p_timer[uap->which] = aitv;
+ p->p_stats->p_timer[SCARG(uap, which)] = aitv;
splx(s);
return (0);
}
@@ -322,6 +337,7 @@ realitexpire(arg)
* fix it to have at least minimal value (i.e. if it is less
* than the resolution of the clock, round it up.)
*/
+int
itimerfix(tv)
struct timeval *tv;
{
@@ -344,6 +360,7 @@ itimerfix(tv)
* that it is called in a context where the timers
* on which it is operating cannot change in value.
*/
+int
itimerdecr(itp, usec)
register struct itimerval *itp;
int usec;
diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c
index 64fac91..caa1cdd 100644
--- a/sys/kern/kern_xxx.c
+++ b/sys/kern/kern_xxx.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_xxx.c 8.2 (Berkeley) 11/14/93
+ * @(#)kern_xxx.c 8.3 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -41,50 +41,54 @@
#include <vm/vm.h>
#include <sys/sysctl.h>
-struct reboot_args {
- int opt;
-};
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
/* ARGSUSED */
+int
reboot(p, uap, retval)
struct proc *p;
- struct reboot_args *uap;
- int *retval;
+ struct reboot_args /* {
+ syscallarg(int) opt;
+ } */ *uap;
+ register_t *retval;
{
int error;
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
- boot(uap->opt);
+ boot(SCARG(uap, opt));
return (0);
}
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-struct gethostname_args {
- char *hostname;
- u_int len;
-};
/* ARGSUSED */
-ogethostname(p, uap, retval)
+int
+compat_43_gethostname(p, uap, retval)
struct proc *p;
- struct gethostname_args *uap;
- int *retval;
+ struct compat_43_gethostname_args /* {
+ syscallarg(char *) hostname;
+ syscallarg(u_int) len;
+ } */ *uap;
+ register_t *retval;
{
int name;
name = KERN_HOSTNAME;
- return (kern_sysctl(&name, 1, uap->hostname, &uap->len, 0, 0));
+ return (kern_sysctl(&name, 1, SCARG(uap, hostname), &SCARG(uap, len),
+ 0, 0));
}
-struct sethostname_args {
- char *hostname;
- u_int len;
-};
/* ARGSUSED */
-osethostname(p, uap, retval)
+int
+compat_43_sethostname(p, uap, retval)
struct proc *p;
- register struct sethostname_args *uap;
- int *retval;
+ register struct compat_43_sethostname_args /* {
+ syscallarg(char *) hostname;
+ syscallarg(u_int) len;
+ } */ *uap;
+ register_t *retval;
{
int name;
int error;
@@ -92,45 +96,46 @@ osethostname(p, uap, retval)
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
name = KERN_HOSTNAME;
- return (kern_sysctl(&name, 1, 0, 0, uap->hostname, uap->len));
+ return (kern_sysctl(&name, 1, 0, 0, SCARG(uap, hostname),
+ SCARG(uap, len)));
}
-extern long hostid;
-
-struct gethostid_args {
- int dummy;
-};
/* ARGSUSED */
-ogethostid(p, uap, retval)
+int
+compat_43_gethostid(p, uap, retval)
struct proc *p;
- struct gethostid_args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
- *(long *)retval = hostid;
+ *(int32_t *)retval = hostid;
return (0);
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
#ifdef COMPAT_43
-struct sethostid_args {
- long hostid;
-};
/* ARGSUSED */
-osethostid(p, uap, retval)
+int
+compat_43_sethostid(p, uap, retval)
struct proc *p;
- struct sethostid_args *uap;
- int *retval;
+ struct compat_43_sethostid_args /* {
+ syscallarg(int32_t) hostid;
+ } */ *uap;
+ register_t *retval;
{
int error;
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
- hostid = uap->hostid;
+ hostid = SCARG(uap, hostid);
return (0);
}
-oquota()
+int
+compat_43_quota(p, uap, retval)
+ struct proc *p;
+ void *uap;
+ register_t *retval;
{
return (ENOSYS);
diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh
index 0ddea0c..4e2c28c 100644
--- a/sys/kern/makesyscalls.sh
+++ b/sys/kern/makesyscalls.sh
@@ -1,171 +1,365 @@
#! /bin/sh -
-# @(#)makesyscalls.sh 8.1 (Berkeley) 6/10/93
+#
+# @(#)makesyscalls.sh 8.2 (Berkeley) 2/14/95
set -e
-# name of compat option:
-compat=COMPAT_43
+case $# in
+ 2) ;;
+ *) echo "Usage: $0 config-file input-file" 1>&2
+ exit 1
+ ;;
+esac
+
+# source the config file.
+. $1
-# output files:
-sysnames="syscalls.c"
-syshdr="../sys/syscall.h"
-syssw="init_sysent.c"
+# the config file sets the following variables:
+# sysnames the syscall names file
+# sysnumhdr the syscall numbers file
+# syssw the syscall switch file
+# sysarghdr the syscall argument struct definitions
+# compatopts those syscall types that are for 'compat' syscalls
+# switchname the name for the 'struct sysent' we define
+# namesname the name for the 'char *[]' we define
+# constprefix the prefix for the system call constants
+#
+# NOTE THAT THIS makesyscalls.sh DOES NOT SUPPORT 'LIBCOMPAT'.
# tmp files:
sysdcl="sysent.dcl"
-syscompat="sysent.compat"
+syscompat_pref="sysent."
sysent="sysent.switch"
-trap "rm $sysdcl $syscompat $sysent" 0
+syscompat_files=""
+for file in $compatopts; do
+ syscompat_files="$syscompat_files $syscompat_pref$file"
+done
-case $# in
- 0) echo "Usage: $0 input-file" 1>&2
- exit 1
- ;;
-esac
+trap "rm $sysdcl $syscompat_files $sysent" 0
+
+# Awk program (must support nawk extensions)
+# Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
+awk=${AWK:-awk}
-awk < $1 "
- BEGIN {
- sysdcl = \"$sysdcl\"
- syscompat = \"$syscompat\"
- sysent = \"$sysent\"
- sysnames = \"$sysnames\"
- syshdr = \"$syshdr\"
- compat = \"$compat\"
- infile = \"$1\"
- "'
+# Does this awk have a "toupper" function? (i.e. is it GNU awk)
+isgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null`
- printf "/*\n * System call switch table.\n *\n" > sysdcl
- printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl
+# If this awk does not define "toupper" then define our own.
+if [ "$isgawk" = TRUE ] ; then
+ # GNU awk provides it.
+ toupper=
+else
+ # Provide our own toupper()
+ toupper='
+function toupper(str) {
+ _toupper_cmd = "echo "str" |tr a-z A-Z"
+ _toupper_cmd | getline _toupper_str;
+ close(_toupper_cmd);
+ return _toupper_str;
+}'
+fi
- printf "\n#ifdef %s\n", compat > syscompat
- printf "#define compat(n, name) n, __CONCAT(o,name)\n\n" > syscompat
+# before handing it off to awk, make a few adjustments:
+# (1) insert spaces around {, }, (, ), *, and commas.
+# (2) get rid of any and all dollar signs (so that rcs id use safe)
+#
+# The awk script will deal with blank lines and lines that
+# start with the comment character (';').
- printf "/*\n * System call names.\n *\n" > sysnames
- printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
+sed -e '
+s/\$//g
+:join
+ /\\$/{a\
- printf "/*\n * System call numbers.\n *\n" > syshdr
- printf " * DO NOT EDIT-- this file is automatically generated.\n" > syshdr
+ N
+ s/\\\n//
+ b join
}
- NR == 1 {
- printf " * created from%s\n */\n\n", $0 > sysdcl
- printf "#include <sys/param.h>\n" > sysdcl
- printf "#include <sys/systm.h>\n\n" > sysdcl
- printf "int\tnosys();\n\n" > sysdcl
+2,${
+ /^#/!s/\([{}()*,]\)/ \1 /g
+}
+' < $2 | $awk "
+$toupper
+BEGIN {
+ sysnames = \"$sysnames\"
+ sysnumhdr = \"$sysnumhdr\"
+ sysarghdr = \"$sysarghdr\"
+ switchname = \"$switchname\"
+ namesname = \"$namesname\"
+ constprefix = \"$constprefix\"
- printf "struct sysent sysent[] = {\n" > sysent
+ sysdcl = \"$sysdcl\"
+ syscompat_pref = \"$syscompat_pref\"
+ sysent = \"$sysent\"
+ infile = \"$2\"
- printf " * created from%s\n */\n\n", $0 > sysnames
- printf "char *syscallnames[] = {\n" > sysnames
+ compatopts = \"$compatopts\"
+ "'
- printf " * created from%s\n */\n\n", $0 > syshdr
- next
- }
- NF == 0 || $1 ~ /^;/ {
- next
- }
- $1 ~ /^#[ ]*if/ {
- print > sysent
- print > sysdcl
- print > syscompat
- print > sysnames
- savesyscall = syscall
- next
- }
- $1 ~ /^#[ ]*else/ {
- print > sysent
- print > sysdcl
- print > syscompat
- print > sysnames
- syscall = savesyscall
- next
- }
- $1 ~ /^#/ {
- print > sysent
- print > sysdcl
- print > syscompat
- print > sysnames
- next
- }
- syscall != $1 {
- printf "%s: line %d: syscall number out of sync at %d\n", \
- infile, NR, syscall
- printf "line is:\n"
- print
- exit 1
- }
- { comment = $4
- for (i = 5; i <= NF; i++)
- comment = comment " " $i
- if (NF < 5)
- $5 = $4
- }
- $2 == "STD" {
- printf("int\t%s();\n", $4) > sysdcl
- printf("\t{ %d, %s },\t\t\t/* %d = %s */\n", \
- $3, $4, syscall, $5) > sysent
- printf("\t\"%s\",\t\t\t/* %d = %s */\n", \
- $5, syscall, $5) > sysnames
- printf("#define\tSYS_%s\t%d\n", \
- $5, syscall) > syshdr
- syscall++
- next
+ printf "/*\n * System call switch table.\n *\n" > sysdcl
+ printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl
+
+ ncompat = split(compatopts,compat)
+ for (i = 1; i <= ncompat; i++) {
+ compat_upper[i] = toupper(compat[i])
+ compat_file[i] = sprintf("%s%s", syscompat_pref, compat[i])
+
+ printf "\n#ifdef %s\n", compat_upper[i] > compat_file[i]
+ printf "#define %s(func) __CONCAT(%s_,func)\n\n", \
+ compat[i], compat[i] > compat_file[i]
}
- $2 == "COMPAT" {
- printf("int\to%s();\n", $4) > syscompat
- printf("\t{ compat(%d,%s) },\t\t/* %d = old %s */\n", \
- $3, $4, syscall, $5) > sysent
- printf("\t\"old.%s\",\t\t/* %d = old %s */\n", \
- $5, syscall, $5) > sysnames
- printf("\t\t\t\t/* %d is old %s */\n", \
- syscall, comment) > syshdr
- syscall++
- next
+
+ printf "/*\n * System call names.\n *\n" > sysnames
+ printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
+
+ printf "/*\n * System call numbers.\n *\n" > sysnumhdr
+ printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnumhdr
+
+ printf "/*\n * System call argument lists.\n *\n" > sysarghdr
+ printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysarghdr
+}
+NR == 1 {
+ printf " * created from%s\n */\n\n", $0 > sysdcl
+
+ printf "#define\ts(type)\tsizeof(type)\n\n" > sysent
+ printf "struct sysent %s[] = {\n",switchname > sysent
+
+ printf " * created from%s\n */\n\n", $0 > sysnames
+ printf "char *%s[] = {\n",namesname > sysnames
+
+ printf " * created from%s\n */\n\n", $0 > sysnumhdr
+
+ printf " * created from%s\n */\n\n", $0 > sysarghdr
+ printf "#define\tsyscallarg(x)\tunion { x datum; register_t pad; }\n" \
+ > sysarghdr
+ next
+}
+NF == 0 || $1 ~ /^;/ {
+ next
+}
+$1 ~ /^#[ ]*include/ {
+ print > sysdcl
+ next
+}
+$1 ~ /^#[ ]*if/ {
+ print > sysent
+ print > sysdcl
+ for (i = 1; i <= ncompat; i++)
+ print > compat_file[i]
+ print > sysnames
+ savesyscall = syscall
+ next
+}
+$1 ~ /^#[ ]*else/ {
+ print > sysent
+ print > sysdcl
+ for (i = 1; i <= ncompat; i++)
+ print > compat_file[i]
+ print > sysnames
+ syscall = savesyscall
+ next
+}
+$1 ~ /^#/ {
+ print > sysent
+ print > sysdcl
+ for (i = 1; i <= ncompat; i++)
+ print > compat_file[i]
+ print > sysnames
+ next
+}
+syscall != $1 {
+ printf "%s: line %d: syscall number out of sync at %d\n", \
+ infile, NR, syscall
+ printf "line is:\n"
+ print
+ exit 1
+}
+function parserr(was, wanted) {
+ printf "%s: line %d: unexpected %s (expected %s)\n", \
+ infile, NR, was, wanted
+ exit 1
+}
+function parseline() {
+ f=3 # toss number and type
+ if ($NF != "}") {
+ funcalias=$NF
+ end=NF-1
+ } else {
+ funcalias=""
+ end=NF
}
- $2 == "LIBCOMPAT" {
- printf("int\to%s();\n", $4) > syscompat
- printf("\t{ compat(%d,%s) },\t\t/* %d = old %s */\n", \
- $3, $4, syscall, $5) > sysent
- printf("\t\"old.%s\",\t\t/* %d = old %s */\n", \
- $5, syscall, $5) > sysnames
- printf("#define\tSYS_%s\t%d\t/* compatibility; still used by libc */\n", \
- $5, syscall) > syshdr
- syscall++
- next
+ if ($f != "{")
+ parserr($f, "{")
+ f++
+ if ($end != "}")
+ parserr($end, "}")
+ end--
+ if ($end != ";")
+ parserr($end, ";")
+ end--
+ if ($end != ")")
+ parserr($end, ")")
+ end--
+
+ f++ # toss return type
+
+ funcname=$f
+ if (funcalias == "")
+ funcalias=funcname
+ f++
+
+ if ($f != "(")
+ parserr($f, ")")
+ f++
+
+ argc= 0;
+ if (f == end) {
+ if ($f != "void")
+ parserr($f, "argument definition")
+ return
}
- $2 == "OBSOL" {
- printf("\t{ 0, nosys },\t\t\t/* %d = obsolete %s */\n", \
- syscall, comment) > sysent
- printf("\t\"obs_%s\",\t\t\t/* %d = obsolete %s */\n", \
- $4, syscall, comment) > sysnames
- printf("\t\t\t\t/* %d is obsolete %s */\n", \
- syscall, comment) > syshdr
- syscall++
- next
+
+ while (f <= end) {
+ argc++
+ argtype[argc]=""
+ oldf=""
+ while (f < end && $(f+1) != ",") {
+ if (argtype[argc] != "" && oldf != "*")
+ argtype[argc] = argtype[argc]" ";
+ argtype[argc] = argtype[argc]$f;
+ oldf = $f;
+ f++
+ }
+ if (argtype[argc] == "")
+ parserr($f, "argument definition")
+ argname[argc]=$f;
+ f += 2; # skip name, and any comma
}
- $2 == "UNIMPL" {
- printf("\t{ 0, nosys },\t\t\t/* %d = %s */\n", \
- syscall, comment) > sysent
- printf("\t\"#%d\",\t\t\t/* %d = %s */\n", \
- syscall, syscall, comment) > sysnames
- syscall++
- next
+}
+function putent(nodefs, declfile, compatwrap) {
+ # output syscall declaration for switch table
+ if (compatwrap == "")
+ printf("int\t%s();\n", funcname) > declfile
+ else
+ printf("int\t%s(%s)();\n", compatwrap, funcname) > declfile
+
+ # output syscall switch entry
+# printf("\t{ { %d", argc) > sysent
+# for (i = 1; i <= argc; i++) {
+# if (i == 5) # wrap the line
+# printf(",\n\t ") > sysent
+# else
+# printf(", ") > sysent
+# printf("s(%s)", argtypenospc[i]) > sysent
+# }
+ printf("\t{ %d, ", argc) > sysent
+ if (argc == 0)
+ printf("0") > sysent
+ else if (compatwrap == "")
+ printf("s(struct %s_args)", funcname) > sysent
+ else
+ printf("s(struct %s_%s_args)", compatwrap, funcname) > sysent
+ if (compatwrap == "")
+ wfn = sprintf("%s", funcname);
+ else
+ wfn = sprintf("%s(%s)", compatwrap, funcname);
+ printf(",\n\t %s },", wfn) > sysent
+ for (i = 0; i < (33 - length(wfn)) / 8; i++)
+ printf("\t") > sysent
+ if (compatwrap == "")
+ printf("/* %d = %s */\n", syscall, funcalias) > sysent
+ else
+ printf("/* %d = %s %s */\n", syscall, compatwrap,
+ funcalias) > sysent
+
+ # output syscall name for names table
+ if (compatwrap == "")
+ printf("\t\"%s\",\t\t\t/* %d = %s */\n", funcalias, syscall,
+ funcalias) > sysnames
+ else
+ printf("\t\"%s_%s\",\t/* %d = %s %s */\n", compatwrap,
+ funcalias, syscall, compatwrap, funcalias) > sysnames
+
+ # output syscall number of header, if appropriate
+ if (nodefs == "" || nodefs == "NOARGS")
+ printf("#define\t%s%s\t%d\n", constprefix, funcalias,
+ syscall) > sysnumhdr
+ else if (nodefs != "NODEF")
+ printf("\t\t\t\t/* %d is %s %s */\n", syscall,
+ compatwrap, funcalias) > sysnumhdr
+
+ # output syscall argument structure, if it has arguments
+ if (argc != 0 && nodefs != "NOARGS") {
+ if (compatwrap == "")
+ printf("\nstruct %s_args {\n", funcname) > sysarghdr
+ else
+ printf("\nstruct %s_%s_args {\n", compatwrap,
+ funcname) > sysarghdr
+ for (i = 1; i <= argc; i++)
+ printf("\tsyscallarg(%s) %s;\n", argtype[i],
+ argname[i]) > sysarghdr
+ printf("};\n") > sysarghdr
}
- {
- printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2
- exit 1
+}
+$2 == "STD" {
+ parseline()
+ putent("", sysdcl, "")
+ syscall++
+ next
+}
+$2 == "NODEF" || $2 == "NOARGS" {
+ parseline()
+ putent($2, sysdcl, "")
+ syscall++
+ next
+}
+$2 == "OBSOL" || $2 == "UNIMPL" {
+ if ($2 == "OBSOL")
+ comment="obsolete"
+ else
+ comment="unimplemented"
+ for (i = 3; i <= NF; i++)
+ comment=comment " " $i
+
+ printf("\t{ 0, 0,\n\t nosys },\t\t\t\t/* %d = %s */\n", \
+ syscall, comment) > sysent
+ printf("\t\"#%d (%s)\",\t\t/* %d = %s */\n", \
+ syscall, comment, syscall, comment) > sysnames
+ if ($2 != "UNIMPL")
+ printf("\t\t\t\t/* %d is %s */\n", syscall, comment) > sysnumhdr
+ syscall++
+ next
+}
+{
+ for (i = 1; i <= ncompat; i++) {
+ if ($2 == compat_upper[i]) {
+ parseline();
+ putent("COMMENT", compat_file[i], compat[i])
+ syscall++
+ next
+ }
}
- END {
- printf("\n#else /* %s */\n", compat) > syscompat
- printf("#define compat(n, name) 0, nosys\n") > syscompat
- printf("#endif /* %s */\n\n", compat) > syscompat
+ printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2
+ exit 1
+}
+END {
+ printf "\n#undef\tsyscallarg\n" > sysarghdr
+
+ for (i = 1; i <= ncompat; i++) {
+ printf("\n#else /* %s */\n", compat_upper[i]) > compat_file[i]
+ printf("#define %s(func) nosys\n", compat[i]) > \
+ compat_file[i]
+ printf("#endif /* %s */\n\n", compat_upper[i]) > compat_file[i]
+ }
- printf("};\n\n") > sysent
- printf("int\tnsysent = sizeof(sysent) / sizeof(sysent[0]);\n") > sysent
+ printf("};\n\n") > sysent
+ printf("int\tn%s= sizeof(%s) / sizeof(%s[0]);\n", switchname,
+ switchname, switchname) > sysent
- printf("};\n") > sysnames
- } '
+ printf("};\n") > sysnames
+} '
-cat $sysdcl $syscompat $sysent >$syssw
+cat $sysdcl $syscompat_files $sysent > $syssw
-chmod 444 $sysnames $syshdr $syssw
+#chmod 444 $sysnames $syshdr $syssw
diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c
index af17988..7281339 100644
--- a/sys/kern/subr_autoconf.c
+++ b/sys/kern/subr_autoconf.c
@@ -39,7 +39,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)subr_autoconf.c 8.1 (Berkeley) 6/10/93
+ * @(#)subr_autoconf.c 8.3 (Berkeley) 5/17/94
*
* from: $Header: subr_autoconf.c,v 1.12 93/02/01 19:31:48 torek Exp $ (LBL)
*/
@@ -47,6 +47,7 @@
#include <sys/param.h>
#include <sys/device.h>
#include <sys/malloc.h>
+#include <libkern/libkern.h>
/*
* Autoconfiguration subroutines.
@@ -283,15 +284,16 @@ config_attach(parent, cf, aux, print)
void **nsp;
if (old == 0) {
- nsp = malloc(MINALLOCSIZE, M_DEVBUF, M_WAITOK); /*XXX*/
- bzero(nsp, MINALLOCSIZE);
- cd->cd_ndevs = MINALLOCSIZE / sizeof(void *);
+ new = max(MINALLOCSIZE / sizeof(void *),
+ dev->dv_unit + 1);
+ newbytes = new * sizeof(void *);
+ nsp = malloc(newbytes, M_DEVBUF, M_WAITOK); /*XXX*/
+ bzero(nsp, newbytes);
} else {
new = cd->cd_ndevs;
do {
new *= 2;
} while (new <= dev->dv_unit);
- cd->cd_ndevs = new;
oldbytes = old * sizeof(void *);
newbytes = new * sizeof(void *);
nsp = malloc(newbytes, M_DEVBUF, M_WAITOK); /*XXX*/
@@ -299,6 +301,7 @@ config_attach(parent, cf, aux, print)
bzero(&nsp[old], newbytes - oldbytes);
free(cd->cd_devs, M_DEVBUF);
}
+ cd->cd_ndevs = new;
cd->cd_devs = nsp;
}
if (cd->cd_devs[dev->dv_unit])
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c
index f065761..792a1ce 100644
--- a/sys/kern/subr_log.c
+++ b/sys/kern/subr_log.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)subr_log.c 8.1 (Berkeley) 6/10/93
+ * @(#)subr_log.c 8.3 (Berkeley) 2/14/95
*/
/*
@@ -59,6 +59,7 @@ struct logsoftc {
int log_open; /* also used in log() */
/*ARGSUSED*/
+int
logopen(dev, flags, mode, p)
dev_t dev;
int flags, mode;
@@ -87,6 +88,7 @@ logopen(dev, flags, mode, p)
}
/*ARGSUSED*/
+int
logclose(dev, flag, mode, p)
dev_t dev;
int flag, mode;
@@ -99,6 +101,7 @@ logclose(dev, flag, mode, p)
}
/*ARGSUSED*/
+int
logread(dev, uio, flag)
dev_t dev;
struct uio *uio;
@@ -144,6 +147,7 @@ logread(dev, uio, flag)
}
/*ARGSUSED*/
+int
logselect(dev, rw, p)
dev_t dev;
int rw;
@@ -165,6 +169,7 @@ logselect(dev, rw, p)
return (0);
}
+void
logwakeup()
{
struct proc *p;
@@ -185,9 +190,10 @@ logwakeup()
}
/*ARGSUSED*/
+int
logioctl(dev, com, data, flag, p)
dev_t dev;
- int com;
+ u_long com;
caddr_t data;
int flag;
struct proc *p;
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 2adb779..8a9a44e 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ * @(#)subr_prf.c 8.4 (Berkeley) 5/4/95
*/
#include <sys/param.h>
@@ -499,6 +499,11 @@ putchar(c, flags, tp)
mbp->msg_bufc[mbp->msg_bufx++] = c;
if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)
mbp->msg_bufx = 0;
+ /* If the buffer is full, keep the most recent data. */
+ if (mbp->msg_bufr == mbp->msg_bufx) {
+ if (++mbp->msg_bufr >= MSG_BSIZE)
+ mbp->msg_bufr = 0;
+ }
}
if ((flags & TOCONS) && constty == NULL && c != '\0')
(*v_putc)(c);
diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c
index 4fb81d8..237553d 100644
--- a/sys/kern/subr_prof.c
+++ b/sys/kern/subr_prof.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)subr_prof.c 8.3 (Berkeley) 9/23/93
+ * @(#)subr_prof.c 8.4 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -38,6 +38,10 @@
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/user.h>
+
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
#include <machine/cpu.h>
#ifdef GPROF
@@ -51,6 +55,7 @@ struct gmonparam _gmonparam = { GMON_PROF_OFF };
extern char etext[];
+void
kmstartup()
{
char *cp;
@@ -90,6 +95,7 @@ kmstartup()
/*
* Return kernel profiling information.
*/
+int
sysctl_doprof(name, namelen, oldp, oldlenp, newp, newlen, p)
int *name;
u_int namelen;
@@ -139,24 +145,24 @@ sysctl_doprof(name, namelen, oldp, oldlenp, newp, newlen, p)
* The scale factor is a fixed point number with 16 bits of fraction, so that
* 1.0 is represented as 0x10000. A scale factor of 0 turns off profiling.
*/
-struct profil_args {
- caddr_t samples;
- u_int size;
- u_int offset;
- u_int scale;
-};
/* ARGSUSED */
+int
profil(p, uap, retval)
struct proc *p;
- register struct profil_args *uap;
- int *retval;
+ register struct profil_args /* {
+ syscallarg(caddr_t) samples;
+ syscallarg(u_int) size;
+ syscallarg(u_int) offset;
+ syscallarg(u_int) scale;
+ } */ *uap;
+ register_t *retval;
{
register struct uprof *upp;
int s;
- if (uap->scale > (1 << 16))
+ if (SCARG(uap, scale) > (1 << 16))
return (EINVAL);
- if (uap->scale == 0) {
+ if (SCARG(uap, scale) == 0) {
stopprofclock(p);
return (0);
}
@@ -164,10 +170,10 @@ profil(p, uap, retval)
/* Block profile interrupts while changing state. */
s = splstatclock();
- upp->pr_off = uap->offset;
- upp->pr_scale = uap->scale;
- upp->pr_base = uap->samples;
- upp->pr_size = uap->size;
+ upp->pr_off = SCARG(uap, offset);
+ upp->pr_scale = SCARG(uap, scale);
+ upp->pr_base = SCARG(uap, samples);
+ upp->pr_size = SCARG(uap, size);
startprofclock(p);
splx(s);
diff --git a/sys/kern/subr_xxx.c b/sys/kern/subr_xxx.c
index c692ec1..45b2d64 100644
--- a/sys/kern/subr_xxx.c
+++ b/sys/kern/subr_xxx.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)subr_xxx.c 8.1 (Berkeley) 6/10/93
+ * @(#)subr_xxx.c 8.3 (Berkeley) 3/29/95
*/
/*
@@ -45,6 +45,7 @@
/*
* Unsupported device function (e.g. writing to read-only device).
*/
+int
enodev()
{
@@ -54,6 +55,7 @@ enodev()
/*
* Unconfigured device function; driver not configured.
*/
+int
enxio()
{
@@ -63,6 +65,7 @@ enxio()
/*
* Unsupported ioctl function.
*/
+int
enoioctl()
{
@@ -74,6 +77,7 @@ enoioctl()
* This is used for an otherwise-reasonable operation
* that is not supported by the current system binary.
*/
+int
enosys()
{
@@ -84,6 +88,7 @@ enosys()
* Return error for operation not supported
* on a specific object or file type.
*/
+int
eopnotsupp()
{
@@ -91,8 +96,20 @@ eopnotsupp()
}
/*
+ * Return error for an inval operation
+ * on a specific object or file type.
+ */
+int
+einval()
+{
+
+ return (EINVAL);
+}
+
+/*
* Generic null operation, always returns success.
*/
+int
nullop()
{
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index a121209..08385b3 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
+ * @(#)sys_generic.c 8.9 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -53,19 +53,22 @@
#include <sys/ktrace.h>
#endif
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
/*
* Read system call.
*/
-struct read_args {
- int fd;
- char *buf;
- u_int nbyte;
-};
/* ARGSUSED */
+int
read(p, uap, retval)
struct proc *p;
- register struct read_args *uap;
- int *retval;
+ register struct read_args /* {
+ syscallarg(int) fd;
+ syscallarg(char *) buf;
+ syscallarg(u_int) nbyte;
+ } */ *uap;
+ register_t *retval;
{
register struct file *fp;
register struct filedesc *fdp = p->p_fd;
@@ -76,15 +79,15 @@ read(p, uap, retval)
struct iovec ktriov;
#endif
- if (((u_int)uap->fd) >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
(fp->f_flag & FREAD) == 0)
return (EBADF);
- aiov.iov_base = (caddr_t)uap->buf;
- aiov.iov_len = uap->nbyte;
+ aiov.iov_base = (caddr_t)SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, nbyte);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
- auio.uio_resid = uap->nbyte;
+ auio.uio_resid = SCARG(uap, nbyte);
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
@@ -95,7 +98,7 @@ read(p, uap, retval)
if (KTRPOINT(p, KTR_GENIO))
ktriov = aiov;
#endif
- cnt = uap->nbyte;
+ cnt = SCARG(uap, nbyte);
if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@@ -103,7 +106,8 @@ read(p, uap, retval)
cnt -= auio.uio_resid;
#ifdef KTRACE
if (KTRPOINT(p, KTR_GENIO) && error == 0)
- ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktriov, cnt, error);
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, &ktriov,
+ cnt, error);
#endif
*retval = cnt;
return (error);
@@ -112,15 +116,15 @@ read(p, uap, retval)
/*
* Scatter read system call.
*/
-struct readv_args {
- int fdes;
- struct iovec *iovp;
- u_int iovcnt;
-};
+int
readv(p, uap, retval)
struct proc *p;
- register struct readv_args *uap;
- int *retval;
+ register struct readv_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(u_int) iovcnt;
+ } */ *uap;
+ register_t *retval;
{
register struct file *fp;
register struct filedesc *fdp = p->p_fd;
@@ -134,14 +138,14 @@ readv(p, uap, retval)
struct iovec *ktriov = NULL;
#endif
- if (((u_int)uap->fdes) >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
(fp->f_flag & FREAD) == 0)
return (EBADF);
/* note: can't use iovlen until iovcnt is validated */
- iovlen = uap->iovcnt * sizeof (struct iovec);
- if (uap->iovcnt > UIO_SMALLIOV) {
- if (uap->iovcnt > UIO_MAXIOV)
+ iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
+ if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
+ if (SCARG(uap, iovcnt) > UIO_MAXIOV)
return (EINVAL);
MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
needfree = iov;
@@ -150,23 +154,19 @@ readv(p, uap, retval)
needfree = NULL;
}
auio.uio_iov = iov;
- auio.uio_iovcnt = uap->iovcnt;
+ auio.uio_iovcnt = SCARG(uap, iovcnt);
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
- if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
+ if (error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen))
goto done;
auio.uio_resid = 0;
- for (i = 0; i < uap->iovcnt; i++) {
- if (iov->iov_len < 0) {
+ for (i = 0; i < SCARG(uap, iovcnt); i++) {
+ if (auio.uio_resid + iov->iov_len < auio.uio_resid) {
error = EINVAL;
goto done;
}
auio.uio_resid += iov->iov_len;
- if (auio.uio_resid < 0) {
- error = EINVAL;
- goto done;
- }
iov++;
}
#ifdef KTRACE
@@ -187,7 +187,7 @@ readv(p, uap, retval)
#ifdef KTRACE
if (ktriov != NULL) {
if (error == 0)
- ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov,
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov,
cnt, error);
FREE(ktriov, M_TEMP);
}
@@ -202,15 +202,15 @@ done:
/*
* Write system call
*/
-struct write_args {
- int fd;
- char *buf;
- u_int nbyte;
-};
+int
write(p, uap, retval)
struct proc *p;
- register struct write_args *uap;
- int *retval;
+ register struct write_args /* {
+ syscallarg(int) fd;
+ syscallarg(char *) buf;
+ syscallarg(u_int) nbyte;
+ } */ *uap;
+ register_t *retval;
{
register struct file *fp;
register struct filedesc *fdp = p->p_fd;
@@ -221,15 +221,15 @@ write(p, uap, retval)
struct iovec ktriov;
#endif
- if (((u_int)uap->fd) >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
(fp->f_flag & FWRITE) == 0)
return (EBADF);
- aiov.iov_base = (caddr_t)uap->buf;
- aiov.iov_len = uap->nbyte;
+ aiov.iov_base = (caddr_t)SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, nbyte);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
- auio.uio_resid = uap->nbyte;
+ auio.uio_resid = SCARG(uap, nbyte);
auio.uio_rw = UIO_WRITE;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
@@ -240,7 +240,7 @@ write(p, uap, retval)
if (KTRPOINT(p, KTR_GENIO))
ktriov = aiov;
#endif
- cnt = uap->nbyte;
+ cnt = SCARG(uap, nbyte);
if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@@ -251,7 +251,7 @@ write(p, uap, retval)
cnt -= auio.uio_resid;
#ifdef KTRACE
if (KTRPOINT(p, KTR_GENIO) && error == 0)
- ktrgenio(p->p_tracep, uap->fd, UIO_WRITE,
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
&ktriov, cnt, error);
#endif
*retval = cnt;
@@ -261,15 +261,15 @@ write(p, uap, retval)
/*
* Gather write system call
*/
-struct writev_args {
- int fd;
- struct iovec *iovp;
- u_int iovcnt;
-};
+int
writev(p, uap, retval)
struct proc *p;
- register struct writev_args *uap;
- int *retval;
+ register struct writev_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(u_int) iovcnt;
+ } */ *uap;
+ register_t *retval;
{
register struct file *fp;
register struct filedesc *fdp = p->p_fd;
@@ -283,14 +283,14 @@ writev(p, uap, retval)
struct iovec *ktriov = NULL;
#endif
- if (((u_int)uap->fd) >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
(fp->f_flag & FWRITE) == 0)
return (EBADF);
/* note: can't use iovlen until iovcnt is validated */
- iovlen = uap->iovcnt * sizeof (struct iovec);
- if (uap->iovcnt > UIO_SMALLIOV) {
- if (uap->iovcnt > UIO_MAXIOV)
+ iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
+ if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
+ if (SCARG(uap, iovcnt) > UIO_MAXIOV)
return (EINVAL);
MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
needfree = iov;
@@ -299,23 +299,19 @@ writev(p, uap, retval)
needfree = NULL;
}
auio.uio_iov = iov;
- auio.uio_iovcnt = uap->iovcnt;
+ auio.uio_iovcnt = SCARG(uap, iovcnt);
auio.uio_rw = UIO_WRITE;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
- if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
+ if (error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen))
goto done;
auio.uio_resid = 0;
- for (i = 0; i < uap->iovcnt; i++) {
- if (iov->iov_len < 0) {
+ for (i = 0; i < SCARG(uap, iovcnt); i++) {
+ if (auio.uio_resid + iov->iov_len < auio.uio_resid) {
error = EINVAL;
goto done;
}
auio.uio_resid += iov->iov_len;
- if (auio.uio_resid < 0) {
- error = EINVAL;
- goto done;
- }
iov++;
}
#ifdef KTRACE
@@ -339,7 +335,7 @@ writev(p, uap, retval)
#ifdef KTRACE
if (ktriov != NULL) {
if (error == 0)
- ktrgenio(p->p_tracep, uap->fd, UIO_WRITE,
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
ktriov, cnt, error);
FREE(ktriov, M_TEMP);
}
@@ -354,20 +350,21 @@ done:
/*
* Ioctl system call
*/
-struct ioctl_args {
- int fd;
- int com;
- caddr_t data;
-};
/* ARGSUSED */
+int
ioctl(p, uap, retval)
struct proc *p;
- register struct ioctl_args *uap;
- int *retval;
+ register struct ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ register_t *retval;
{
register struct file *fp;
register struct filedesc *fdp;
- register int com, error;
+ register u_long com;
+ register int error;
register u_int size;
caddr_t data, memp;
int tmp;
@@ -375,19 +372,19 @@ ioctl(p, uap, retval)
char stkbuf[STK_PARAMS];
fdp = p->p_fd;
- if ((u_int)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
return (EBADF);
if ((fp->f_flag & (FREAD | FWRITE)) == 0)
return (EBADF);
- switch (com = uap->com) {
+ switch (com = SCARG(uap, com)) {
case FIONCLEX:
- fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE;
+ fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
return (0);
case FIOCLEX:
- fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE;
+ fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
return (0);
}
@@ -406,14 +403,14 @@ ioctl(p, uap, retval)
data = stkbuf;
if (com&IOC_IN) {
if (size) {
- error = copyin(uap->data, data, (u_int)size);
+ error = copyin(SCARG(uap, data), data, (u_int)size);
if (error) {
if (memp)
free(memp, M_IOCTLOPS);
return (error);
}
} else
- *(caddr_t *)data = uap->data;
+ *(caddr_t *)data = SCARG(uap, data);
} else if ((com&IOC_OUT) && size)
/*
* Zero the buffer so the user always
@@ -421,7 +418,7 @@ ioctl(p, uap, retval)
*/
bzero(data, size);
else if (com&IOC_VOID)
- *(caddr_t *)data = uap->data;
+ *(caddr_t *)data = SCARG(uap, data);
switch (com) {
@@ -459,7 +456,7 @@ ioctl(p, uap, retval)
tmp = p1->p_pgrp->pg_id;
}
error = (*fp->f_ops->fo_ioctl)
- (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p);
+ (fp, TIOCSPGRP, (caddr_t)&tmp, p);
break;
case FIOGETOWN:
@@ -468,7 +465,7 @@ ioctl(p, uap, retval)
*(int *)data = ((struct socket *)fp->f_data)->so_pgid;
break;
}
- error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p);
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
*(int *)data = -*(int *)data;
break;
@@ -479,7 +476,7 @@ ioctl(p, uap, retval)
* already set and checked above.
*/
if (error == 0 && (com&IOC_OUT) && size)
- error = copyout(data, uap->data, (u_int)size);
+ error = copyout(data, SCARG(uap, data), (u_int)size);
break;
}
if (memp)
@@ -492,40 +489,44 @@ int selwait, nselcoll;
/*
* Select system call.
*/
-struct select_args {
- u_int nd;
- fd_set *in, *ou, *ex;
- struct timeval *tv;
-};
+int
select(p, uap, retval)
register struct proc *p;
- register struct select_args *uap;
- int *retval;
+ register struct select_args /* {
+ syscallarg(u_int) nd;
+ syscallarg(fd_set *) in;
+ syscallarg(fd_set *) ou;
+ syscallarg(fd_set *) ex;
+ syscallarg(struct timeval *) tv;
+ } */ *uap;
+ register_t *retval;
{
fd_set ibits[3], obits[3];
struct timeval atv;
- int s, ncoll, error = 0, timo;
+ int s, ncoll, error, timo = 0;
u_int ni;
bzero((caddr_t)ibits, sizeof(ibits));
bzero((caddr_t)obits, sizeof(obits));
- if (uap->nd > FD_SETSIZE)
+ if (SCARG(uap, nd) > FD_SETSIZE)
return (EINVAL);
- if (uap->nd > p->p_fd->fd_nfiles)
- uap->nd = p->p_fd->fd_nfiles; /* forgiving; slightly wrong */
- ni = howmany(uap->nd, NFDBITS) * sizeof(fd_mask);
+ if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
+ /* forgiving; slightly wrong */
+ SCARG(uap, nd) = p->p_fd->fd_nfiles;
+ }
+ ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
#define getbits(name, x) \
- if (uap->name && \
- (error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], ni))) \
+ if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, name), \
+ (caddr_t)&ibits[x], ni))) \
goto done;
getbits(in, 0);
getbits(ou, 1);
getbits(ex, 2);
#undef getbits
- if (uap->tv) {
- error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
+ if (SCARG(uap, tv)) {
+ error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv,
sizeof (atv));
if (error)
goto done;
@@ -535,27 +536,30 @@ select(p, uap, retval)
}
s = splclock();
timevaladd(&atv, (struct timeval *)&time);
- timo = hzto(&atv);
- /*
- * Avoid inadvertently sleeping forever.
- */
- if (timo == 0)
- timo = 1;
splx(s);
- } else
- timo = 0;
+ }
retry:
ncoll = nselcoll;
p->p_flag |= P_SELECT;
- error = selscan(p, ibits, obits, uap->nd, retval);
+ error = selscan(p, ibits, obits, SCARG(uap, nd), retval);
if (error || *retval)
goto done;
s = splhigh();
- /* this should be timercmp(&time, &atv, >=) */
- if (uap->tv && (time.tv_sec > atv.tv_sec ||
- time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) {
- splx(s);
- goto done;
+ if (SCARG(uap, tv)) {
+ if (timercmp(&time, &atv, >=)) {
+ splx(s);
+ goto done;
+ }
+ /*
+ * If poll wait was tiny, this could be zero; we will
+ * have to round it up to avoid sleeping forever. If
+ * we retry below, the timercmp above will get us out.
+ * Note that if wait was 0, the timercmp will prevent
+ * us from getting here the first time.
+ */
+ timo = hzto(&atv);
+ if (timo == 0)
+ timo = 1;
}
if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
splx(s);
@@ -574,8 +578,8 @@ done:
if (error == EWOULDBLOCK)
error = 0;
#define putbits(name, x) \
- if (uap->name && \
- (error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, ni))) \
+ if (SCARG(uap, name) && (error2 = copyout((caddr_t)&obits[x], \
+ (caddr_t)SCARG(uap, name), ni))) \
error = error2;
if (error == 0) {
int error2;
@@ -588,10 +592,12 @@ done:
return (error);
}
+int
selscan(p, ibits, obits, nfd, retval)
struct proc *p;
fd_set *ibits, *obits;
- int nfd, *retval;
+ int nfd;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
register int msk, i, j, fd;
@@ -620,6 +626,7 @@ selscan(p, ibits, obits, nfd, retval)
}
/*ARGSUSED*/
+int
seltrue(dev, flag, p)
dev_t dev;
int flag;
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index a93ae86..abc2dc7 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93
+ * @(#)sys_socket.c 8.3 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -51,6 +51,7 @@ struct fileops socketops =
{ soo_read, soo_write, soo_ioctl, soo_select, soo_close };
/* ARGSUSED */
+int
soo_read(fp, uio, cred)
struct file *fp;
struct uio *uio;
@@ -62,6 +63,7 @@ soo_read(fp, uio, cred)
}
/* ARGSUSED */
+int
soo_write(fp, uio, cred)
struct file *fp;
struct uio *uio;
@@ -72,9 +74,10 @@ soo_write(fp, uio, cred)
uio, (struct mbuf *)0, (struct mbuf *)0, 0));
}
+int
soo_ioctl(fp, cmd, data, p)
struct file *fp;
- int cmd;
+ u_long cmd;
register caddr_t data;
struct proc *p;
{
@@ -130,6 +133,7 @@ soo_ioctl(fp, cmd, data, p)
(struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
}
+int
soo_select(fp, which, p)
struct file *fp;
int which;
@@ -171,6 +175,7 @@ soo_select(fp, which, p)
return (0);
}
+int
soo_stat(so, ub)
register struct socket *so;
register struct stat *ub;
@@ -184,6 +189,7 @@ soo_stat(so, ub)
}
/* ARGSUSED */
+int
soo_close(fp, p)
struct file *fp;
struct proc *p;
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 1809905..91cbdc9 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -2,7 +2,7 @@
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from @(#)syscalls.master 8.2 (Berkeley) 1/13/94
+ * created from @(#)syscalls.master 8.6 (Berkeley) 3/30/95
*/
char *syscallnames[] = {
@@ -14,10 +14,10 @@ char *syscallnames[] = {
"open", /* 5 = open */
"close", /* 6 = close */
"wait4", /* 7 = wait4 */
- "old.creat", /* 8 = old creat */
+ "compat_43_creat", /* 8 = compat_43 creat */
"link", /* 9 = link */
"unlink", /* 10 = unlink */
- "obs_execv", /* 11 = obsolete execv */
+ "#11 (obsolete execv)", /* 11 = obsolete execv */
"chdir", /* 12 = chdir */
"fchdir", /* 13 = fchdir */
"mknod", /* 14 = mknod */
@@ -25,7 +25,7 @@ char *syscallnames[] = {
"chown", /* 16 = chown */
"break", /* 17 = break */
"getfsstat", /* 18 = getfsstat */
- "old.lseek", /* 19 = old lseek */
+ "compat_43_lseek", /* 19 = compat_43 lseek */
"getpid", /* 20 = getpid */
"mount", /* 21 = mount */
"unmount", /* 22 = unmount */
@@ -44,9 +44,9 @@ char *syscallnames[] = {
"fchflags", /* 35 = fchflags */
"sync", /* 36 = sync */
"kill", /* 37 = kill */
- "old.stat", /* 38 = old stat */
+ "compat_43_stat", /* 38 = compat_43 stat */
"getppid", /* 39 = getppid */
- "old.lstat", /* 40 = old lstat */
+ "compat_43_lstat", /* 40 = compat_43 lstat */
"dup", /* 41 = dup */
"pipe", /* 42 = pipe */
"getegid", /* 43 = getegid */
@@ -54,7 +54,7 @@ char *syscallnames[] = {
#ifdef KTRACE
"ktrace", /* 45 = ktrace */
#else
- "#45", /* 45 = ktrace */
+ "#45 (unimplemented ktrace)", /* 45 = unimplemented ktrace */
#endif
"sigaction", /* 46 = sigaction */
"getgid", /* 47 = getgid */
@@ -72,63 +72,63 @@ char *syscallnames[] = {
"execve", /* 59 = execve */
"umask", /* 60 = umask */
"chroot", /* 61 = chroot */
- "old.fstat", /* 62 = old fstat */
- "old.getkerninfo", /* 63 = old getkerninfo */
- "old.getpagesize", /* 64 = old getpagesize */
+ "compat_43_fstat", /* 62 = compat_43 fstat */
+ "compat_43_getkerninfo", /* 63 = compat_43 getkerninfo */
+ "compat_43_getpagesize", /* 64 = compat_43 getpagesize */
"msync", /* 65 = msync */
"vfork", /* 66 = vfork */
- "obs_vread", /* 67 = obsolete vread */
- "obs_vwrite", /* 68 = obsolete vwrite */
+ "#67 (obsolete vread)", /* 67 = obsolete vread */
+ "#68 (obsolete vwrite)", /* 68 = obsolete vwrite */
"sbrk", /* 69 = sbrk */
"sstk", /* 70 = sstk */
- "old.mmap", /* 71 = old mmap */
+ "compat_43_mmap", /* 71 = compat_43 mmap */
"vadvise", /* 72 = vadvise */
"munmap", /* 73 = munmap */
"mprotect", /* 74 = mprotect */
"madvise", /* 75 = madvise */
- "obs_vhangup", /* 76 = obsolete vhangup */
- "obs_vlimit", /* 77 = obsolete vlimit */
+ "#76 (obsolete vhangup)", /* 76 = obsolete vhangup */
+ "#77 (obsolete vlimit)", /* 77 = obsolete vlimit */
"mincore", /* 78 = mincore */
"getgroups", /* 79 = getgroups */
"setgroups", /* 80 = setgroups */
"getpgrp", /* 81 = getpgrp */
"setpgid", /* 82 = setpgid */
"setitimer", /* 83 = setitimer */
- "old.wait", /* 84 = old wait */
+ "compat_43_wait", /* 84 = compat_43 wait */
"swapon", /* 85 = swapon */
"getitimer", /* 86 = getitimer */
- "old.gethostname", /* 87 = old gethostname */
- "old.sethostname", /* 88 = old sethostname */
+ "compat_43_gethostname", /* 87 = compat_43 gethostname */
+ "compat_43_sethostname", /* 88 = compat_43 sethostname */
"getdtablesize", /* 89 = getdtablesize */
"dup2", /* 90 = dup2 */
- "#91", /* 91 = getdopt */
+ "#91 (unimplemented getdopt)", /* 91 = unimplemented getdopt */
"fcntl", /* 92 = fcntl */
"select", /* 93 = select */
- "#94", /* 94 = setdopt */
+ "#94 (unimplemented setdopt)", /* 94 = unimplemented setdopt */
"fsync", /* 95 = fsync */
"setpriority", /* 96 = setpriority */
"socket", /* 97 = socket */
"connect", /* 98 = connect */
- "old.accept", /* 99 = old accept */
+ "compat_43_accept", /* 99 = compat_43 accept */
"getpriority", /* 100 = getpriority */
- "old.send", /* 101 = old send */
- "old.recv", /* 102 = old recv */
+ "compat_43_send", /* 101 = compat_43 send */
+ "compat_43_recv", /* 102 = compat_43 recv */
"sigreturn", /* 103 = sigreturn */
"bind", /* 104 = bind */
"setsockopt", /* 105 = setsockopt */
"listen", /* 106 = listen */
- "obs_vtimes", /* 107 = obsolete vtimes */
- "old.sigvec", /* 108 = old sigvec */
- "old.sigblock", /* 109 = old sigblock */
- "old.sigsetmask", /* 110 = old sigsetmask */
+ "#107 (obsolete vtimes)", /* 107 = obsolete vtimes */
+ "compat_43_sigvec", /* 108 = compat_43 sigvec */
+ "compat_43_sigblock", /* 109 = compat_43 sigblock */
+ "compat_43_sigsetmask", /* 110 = compat_43 sigsetmask */
"sigsuspend", /* 111 = sigsuspend */
- "old.sigstack", /* 112 = old sigstack */
- "old.recvmsg", /* 113 = old recvmsg */
- "old.sendmsg", /* 114 = old sendmsg */
+ "compat_43_sigstack", /* 112 = compat_43 sigstack */
+ "compat_43_recvmsg", /* 113 = compat_43 recvmsg */
+ "compat_43_sendmsg", /* 114 = compat_43 sendmsg */
#ifdef TRACE
"vtrace", /* 115 = vtrace */
#else
- "obs_vtrace", /* 115 = obsolete vtrace */
+ "#115 (obsolete vtrace)", /* 115 = obsolete vtrace */
#endif
"gettimeofday", /* 116 = gettimeofday */
"getrusage", /* 117 = getrusage */
@@ -136,19 +136,19 @@ char *syscallnames[] = {
#ifdef vax
"resuba", /* 119 = resuba */
#else
- "#119", /* 119 = nosys */
+ "#119 (unimplemented resuba)", /* 119 = unimplemented resuba */
#endif
"readv", /* 120 = readv */
"writev", /* 121 = writev */
"settimeofday", /* 122 = settimeofday */
"fchown", /* 123 = fchown */
"fchmod", /* 124 = fchmod */
- "old.recvfrom", /* 125 = old recvfrom */
- "old.setreuid", /* 126 = old setreuid */
- "old.setregid", /* 127 = old setregid */
+ "compat_43_recvfrom", /* 125 = compat_43 recvfrom */
+ "compat_43_setreuid", /* 126 = compat_43 setreuid */
+ "compat_43_setregid", /* 127 = compat_43 setregid */
"rename", /* 128 = rename */
- "old.truncate", /* 129 = old truncate */
- "old.ftruncate", /* 130 = old ftruncate */
+ "compat_43_truncate", /* 129 = compat_43 truncate */
+ "compat_43_ftruncate", /* 130 = compat_43 ftruncate */
"flock", /* 131 = flock */
"mkfifo", /* 132 = mkfifo */
"sendto", /* 133 = sendto */
@@ -157,60 +157,60 @@ char *syscallnames[] = {
"mkdir", /* 136 = mkdir */
"rmdir", /* 137 = rmdir */
"utimes", /* 138 = utimes */
- "obs_4.2", /* 139 = obsolete 4.2 sigreturn */
+ "#139 (obsolete 4.2 sigreturn)", /* 139 = obsolete 4.2 sigreturn */
"adjtime", /* 140 = adjtime */
- "old.getpeername", /* 141 = old getpeername */
- "old.gethostid", /* 142 = old gethostid */
- "old.sethostid", /* 143 = old sethostid */
- "old.getrlimit", /* 144 = old getrlimit */
- "old.setrlimit", /* 145 = old setrlimit */
- "old.killpg", /* 146 = old killpg */
+ "compat_43_getpeername", /* 141 = compat_43 getpeername */
+ "compat_43_gethostid", /* 142 = compat_43 gethostid */
+ "compat_43_sethostid", /* 143 = compat_43 sethostid */
+ "compat_43_getrlimit", /* 144 = compat_43 getrlimit */
+ "compat_43_setrlimit", /* 145 = compat_43 setrlimit */
+ "compat_43_killpg", /* 146 = compat_43 killpg */
"setsid", /* 147 = setsid */
"quotactl", /* 148 = quotactl */
- "old.quota", /* 149 = old quota */
- "old.getsockname", /* 150 = old getsockname */
- "#151", /* 151 = nosys */
- "#152", /* 152 = nosys */
- "#153", /* 153 = nosys */
- "#154", /* 154 = nosys */
+ "compat_43_quota", /* 149 = compat_43 quota */
+ "compat_43_getsockname", /* 150 = compat_43 getsockname */
+ "#151 (unimplemented)", /* 151 = unimplemented */
+ "#152 (unimplemented)", /* 152 = unimplemented */
+ "#153 (unimplemented)", /* 153 = unimplemented */
+ "#154 (unimplemented)", /* 154 = unimplemented */
#ifdef NFS
"nfssvc", /* 155 = nfssvc */
#else
- "#155", /* 155 = nosys */
+ "#155 (unimplemented nfssvc)", /* 155 = unimplemented nfssvc */
#endif
- "old.getdirentries", /* 156 = old getdirentries */
+ "compat_43_getdirentries", /* 156 = compat_43 getdirentries */
"statfs", /* 157 = statfs */
"fstatfs", /* 158 = fstatfs */
- "#159", /* 159 = nosys */
- "#160", /* 160 = nosys */
+ "#159 (unimplemented)", /* 159 = unimplemented */
+ "#160 (unimplemented)", /* 160 = unimplemented */
#ifdef NFS
"getfh", /* 161 = getfh */
#else
- "#161", /* 161 = nosys */
+ "#161 (unimplemented getfh)", /* 161 = unimplemented getfh */
#endif
- "#162", /* 162 = nosys */
- "#163", /* 163 = nosys */
- "#164", /* 164 = nosys */
- "#165", /* 165 = nosys */
- "#166", /* 166 = nosys */
- "#167", /* 167 = nosys */
- "#168", /* 168 = nosys */
- "#169", /* 169 = nosys */
- "#170", /* 170 = nosys */
-#ifdef SYSVSHM
- "shmsys", /* 171 = shmsys */
+ "#162 (unimplemented getdomainname)", /* 162 = unimplemented getdomainname */
+ "#163 (unimplemented setdomainname)", /* 163 = unimplemented setdomainname */
+ "#164 (unimplemented)", /* 164 = unimplemented */
+ "#165 (unimplemented)", /* 165 = unimplemented */
+ "#166 (unimplemented)", /* 166 = unimplemented */
+ "#167 (unimplemented)", /* 167 = unimplemented */
+ "#168 (unimplemented)", /* 168 = unimplemented */
+ "#169 (unimplemented semsys)", /* 169 = unimplemented semsys */
+ "#170 (unimplemented msgsys)", /* 170 = unimplemented msgsys */
+#if defined(SYSVSHM) && !defined(alpha)
+ "compat_43_shmsys", /* 171 = compat_43 shmsys */
#else
- "#171", /* 171 = nosys */
+ "#171 (unimplemented shmsys)", /* 171 = unimplemented shmsys */
#endif
- "#172", /* 172 = nosys */
- "#173", /* 173 = nosys */
- "#174", /* 174 = nosys */
- "#175", /* 175 = nosys */
- "#176", /* 176 = nosys */
- "#177", /* 177 = nosys */
- "#178", /* 178 = nosys */
- "#179", /* 179 = nosys */
- "#180", /* 180 = nosys */
+ "#172 (unimplemented)", /* 172 = unimplemented */
+ "#173 (unimplemented)", /* 173 = unimplemented */
+ "#174 (unimplemented)", /* 174 = unimplemented */
+ "#175 (unimplemented)", /* 175 = unimplemented */
+ "#176 (unimplemented)", /* 176 = unimplemented */
+ "#177 (unimplemented)", /* 177 = unimplemented */
+ "#178 (unimplemented)", /* 178 = unimplemented */
+ "#179 (unimplemented)", /* 179 = unimplemented */
+ "#180 (unimplemented)", /* 180 = unimplemented */
"setgid", /* 181 = setgid */
"setegid", /* 182 = setegid */
"seteuid", /* 183 = seteuid */
@@ -220,17 +220,17 @@ char *syscallnames[] = {
"lfs_segclean", /* 186 = lfs_segclean */
"lfs_segwait", /* 187 = lfs_segwait */
#else
- "#184", /* 184 = nosys */
- "#185", /* 185 = nosys */
- "#186", /* 186 = nosys */
- "#187", /* 187 = nosys */
+ "#184 (unimplemented lfs_bmapv)", /* 184 = unimplemented lfs_bmapv */
+ "#185 (unimplemented lfs_markv)", /* 185 = unimplemented lfs_markv */
+ "#186 (unimplemented lfs_segclean)", /* 186 = unimplemented lfs_segclean */
+ "#187 (unimplemented lfs_segwait)", /* 187 = unimplemented lfs_segwait */
#endif
"stat", /* 188 = stat */
"fstat", /* 189 = fstat */
"lstat", /* 190 = lstat */
"pathconf", /* 191 = pathconf */
"fpathconf", /* 192 = fpathconf */
- "#193", /* 193 = nosys */
+ "#193 (unimplemented)", /* 193 = unimplemented */
"getrlimit", /* 194 = getrlimit */
"setrlimit", /* 195 = setrlimit */
"getdirentries", /* 196 = getdirentries */
@@ -242,10 +242,38 @@ char *syscallnames[] = {
"__sysctl", /* 202 = __sysctl */
"mlock", /* 203 = mlock */
"munlock", /* 204 = munlock */
- "#205", /* 205 = nosys */
- "#206", /* 206 = nosys */
- "#207", /* 207 = nosys */
- "#208", /* 208 = nosys */
- "#209", /* 209 = nosys */
- "#210", /* 210 = nosys */
+ "undelete", /* 205 = undelete */
+ "#206 (unimplemented)", /* 206 = unimplemented */
+ "#207 (unimplemented)", /* 207 = unimplemented */
+ "#208 (unimplemented)", /* 208 = unimplemented */
+ "#209 (unimplemented)", /* 209 = unimplemented */
+ "#210 (unimplemented)", /* 210 = unimplemented */
+ "#211 (unimplemented)", /* 211 = unimplemented */
+ "#212 (unimplemented)", /* 212 = unimplemented */
+ "#213 (unimplemented)", /* 213 = unimplemented */
+ "#214 (unimplemented)", /* 214 = unimplemented */
+ "#215 (unimplemented)", /* 215 = unimplemented */
+ "#216 (unimplemented)", /* 216 = unimplemented */
+ "#217 (unimplemented)", /* 217 = unimplemented */
+ "#218 (unimplemented)", /* 218 = unimplemented */
+ "#219 (unimplemented)", /* 219 = unimplemented */
+ "#220 (unimplemented semctl)", /* 220 = unimplemented semctl */
+ "#221 (unimplemented semget)", /* 221 = unimplemented semget */
+ "#222 (unimplemented semop)", /* 222 = unimplemented semop */
+ "#223 (unimplemented semconfig)", /* 223 = unimplemented semconfig */
+ "#224 (unimplemented msgctl)", /* 224 = unimplemented msgctl */
+ "#225 (unimplemented msgget)", /* 225 = unimplemented msgget */
+ "#226 (unimplemented msgsnd)", /* 226 = unimplemented msgsnd */
+ "#227 (unimplemented msgrcv)", /* 227 = unimplemented msgrcv */
+#if defined(SYSVSHM) && 0
+ "shmat", /* 228 = shmat */
+ "shmctl", /* 229 = shmctl */
+ "shmdt", /* 230 = shmdt */
+ "shmget", /* 231 = shmget */
+#else
+ "#228 (unimplemented shmat)", /* 228 = unimplemented shmat */
+ "#229 (unimplemented shmctl)", /* 229 = unimplemented shmctl */
+ "#230 (unimplemented shmdt)", /* 230 = unimplemented shmdt */
+ "#231 (unimplemented shmget)", /* 231 = unimplemented shmget */
+#endif
};
diff --git a/sys/kern/syscalls.conf b/sys/kern/syscalls.conf
new file mode 100644
index 0000000..71b82ce
--- /dev/null
+++ b/sys/kern/syscalls.conf
@@ -0,0 +1,12 @@
+# @(#)syscalls.conf 8.1 (Berkeley) 2/14/95
+
+sysnames="syscalls.c"
+sysnumhdr="../sys/syscall.h"
+syssw="init_sysent.c"
+sysarghdr="../sys/syscallargs.h"
+compatopts="compat_43"
+libcompatopts=""
+
+switchname="sysent"
+namesname="syscallnames"
+constprefix="SYS_"
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 1b8de14..b57cd73 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,23 +1,38 @@
- @(#)syscalls.master 8.2 (Berkeley) 1/13/94
-; System call name/number master file.
-; Processed to created init_sysent.c, syscalls.c and syscall.h.
-
-; Columns: number type nargs name altname/comments
+ @(#)syscalls.master 8.6 (Berkeley) 3/30/95
+; System call name/number "master" file.
+; (See syscalls.conf to see what it is processed into.)
+;
+; Fields: number type [type-dependent ...]
; number system call number, must be in order
-; type one of STD, OBSOL, UNIMPL, COMPAT
-; nargs number of arguments
-; name name of syscall routine
-; altname name of system call if different
-; for UNIMPL/OBSOL, name continues with comments
-
+; type one of STD, OBSOL, UNIMPL, NODEF, NOARGS, or one of
+; the compatibility options defined in syscalls.conf.
+;
; types:
; STD always included
-; COMPAT included on COMPAT #ifdef
-; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h
-; OBSOL obsolete, not included in system, only specifies name
-; UNIMPL not implemented, placeholder only
-
+; OBSOL obsolete, not included in system
+; UNIMPL unimplemented, not included in system
+; NODEF included, but don't define the syscall number
+; NOARGS included, but don't define the syscall args structure
+;
+; The compat options are defined in the syscalls.conf file, and the
+; compat option name is prefixed to the syscall name. Other than
+; that, they're like NODEF (for 'compat' options), or STD (for
+; 'libcompat' options).
+;
+; The type-dependent arguments are as follows:
+; For STD, NODEF, NOARGS, and compat syscalls:
+; { pseudo-proto } [alias]
+; For other syscalls:
+; [comment]
+;
; #ifdef's, etc. may be included, and are copied to the output files.
+; #include's are copied to the syscall switch definition file only.
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signal.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
; Reserved/unimplemented system calls in the range 0-150 inclusive
; are reserved for use in future Berkeley releases.
@@ -25,252 +40,316 @@
; redistributions should be placed in the reserved range at the end
; of the current calls.
-0 STD 0 nosys syscall
-1 STD 1 exit
-2 STD 0 fork
-3 STD 3 read
-4 STD 3 write
-5 STD 3 open
-6 STD 1 close
-7 STD 4 wait4
-8 COMPAT 2 creat
-9 STD 2 link
-10 STD 1 unlink
-11 OBSOL 2 execv
-12 STD 1 chdir
-13 STD 1 fchdir
-14 STD 3 mknod
-15 STD 2 chmod
-16 STD 3 chown
-17 STD 1 obreak break
-18 STD 3 getfsstat
-19 COMPAT 3 lseek
-20 STD 0 getpid
-21 STD 4 mount
-22 STD 2 unmount
-23 STD 1 setuid
-24 STD 0 getuid
-25 STD 0 geteuid
-26 STD 4 ptrace
-27 STD 3 recvmsg
-28 STD 3 sendmsg
-29 STD 6 recvfrom
-30 STD 3 accept
-31 STD 3 getpeername
-32 STD 3 getsockname
-33 STD 2 access
-34 STD 2 chflags
-35 STD 2 fchflags
-36 STD 0 sync
-37 STD 2 kill
-38 COMPAT 2 stat
-39 STD 0 getppid
-40 COMPAT 2 lstat
-41 STD 2 dup
-42 STD 0 pipe
-43 STD 0 getegid
-44 STD 4 profil
+0 STD { int nosys(void); } syscall
+1 STD { int exit(int rval); }
+2 STD { int fork(void); }
+3 STD { int read(int fd, char *buf, u_int nbyte); }
+4 STD { int write(int fd, char *buf, u_int nbyte); }
+5 STD { int open(char *path, int flags, int mode); }
+6 STD { int close(int fd); }
+7 STD { int wait4(int pid, int *status, int options, \
+ struct rusage *rusage); }
+8 COMPAT_43 { int creat(char *path, int mode); }
+9 STD { int link(char *path, char *link); }
+10 STD { int unlink(char *path); }
+11 OBSOL execv
+12 STD { int chdir(char *path); }
+13 STD { int fchdir(int fd); }
+14 STD { int mknod(char *path, int mode, int dev); }
+15 STD { int chmod(char *path, int mode); }
+16 STD { int chown(char *path, int uid, int gid); }
+17 STD { int obreak(char *nsize); } break
+18 STD { int getfsstat(struct statfs *buf, long bufsize, \
+ int flags); }
+19 COMPAT_43 { long lseek(int fd, long offset, int whence); }
+20 STD { pid_t getpid(void); }
+21 STD { int mount(char *type, char *path, int flags, \
+ caddr_t data); }
+22 STD { int unmount(char *path, int flags); }
+23 STD { int setuid(uid_t uid); }
+24 STD { uid_t getuid(void); }
+25 STD { uid_t geteuid(void); }
+26 STD { int ptrace(int req, pid_t pid, caddr_t addr, \
+ int data); }
+27 STD { int recvmsg(int s, struct msghdr *msg, int flags); }
+28 STD { int sendmsg(int s, caddr_t msg, int flags); }
+29 STD { int recvfrom(int s, caddr_t buf, size_t len, \
+ int flags, caddr_t from, int *fromlenaddr); }
+30 STD { int accept(int s, caddr_t name, int *anamelen); }
+31 STD { int getpeername(int fdes, caddr_t asa, int *alen); }
+32 STD { int getsockname(int fdes, caddr_t asa, int *alen); }
+33 STD { int access(char *path, int flags); }
+34 STD { int chflags(char *path, int flags); }
+35 STD { int fchflags(int fd, int flags); }
+36 STD { int sync(void); }
+37 STD { int kill(int pid, int signum); }
+38 COMPAT_43 { int stat(char *path, struct ostat *ub); }
+39 STD { pid_t getppid(void); }
+40 COMPAT_43 { int lstat(char *path, struct ostat *ub); }
+41 STD { int dup(u_int fd); }
+42 STD { int pipe(void); }
+43 STD { gid_t getegid(void); }
+44 STD { int profil(caddr_t samples, u_int size, \
+ u_int offset, u_int scale); }
#ifdef KTRACE
-45 STD 4 ktrace
+45 STD { int ktrace(char *fname, int ops, int facs, \
+ int pid); }
#else
-45 UNIMPL 0 ktrace
+45 UNIMPL ktrace
#endif
-46 STD 3 sigaction
-47 STD 0 getgid
-48 STD 2 sigprocmask
-49 STD 2 getlogin
-50 STD 1 setlogin
-51 STD 1 acct
-52 STD 0 sigpending
-53 STD 2 sigaltstack
-54 STD 3 ioctl
-55 STD 1 reboot
-56 STD 1 revoke
-57 STD 2 symlink
-58 STD 3 readlink
-59 STD 3 execve
-60 STD 1 umask
-61 STD 1 chroot
-62 COMPAT 2 fstat
-63 COMPAT 4 getkerninfo
-64 COMPAT 0 getpagesize
-65 STD 2 msync
-66 STD 0 vfork
-67 OBSOL 0 vread
-68 OBSOL 0 vwrite
-69 STD 1 sbrk
-70 STD 1 sstk
-71 COMPAT 7 mmap
-72 STD 1 ovadvise vadvise
-73 STD 2 munmap
-74 STD 3 mprotect
-75 STD 3 madvise
-76 OBSOL 0 vhangup
-77 OBSOL 0 vlimit
-78 STD 3 mincore
-79 STD 2 getgroups
-80 STD 2 setgroups
-81 STD 0 getpgrp
-82 STD 2 setpgid
-83 STD 3 setitimer
-84 COMPAT 0 wait
-85 STD 1 swapon
-86 STD 2 getitimer
-87 COMPAT 2 gethostname
-88 COMPAT 2 sethostname
-89 STD 0 getdtablesize
-90 STD 2 dup2
-91 UNIMPL 2 getdopt
-92 STD 3 fcntl
-93 STD 5 select
-94 UNIMPL 2 setdopt
-95 STD 1 fsync
-96 STD 3 setpriority
-97 STD 3 socket
-98 STD 3 connect
-99 COMPAT 3 accept
-100 STD 2 getpriority
-101 COMPAT 4 send
-102 COMPAT 4 recv
-103 STD 1 sigreturn
-104 STD 3 bind
-105 STD 5 setsockopt
-106 STD 2 listen
-107 OBSOL 0 vtimes
-108 COMPAT 3 sigvec
-109 COMPAT 1 sigblock
-110 COMPAT 1 sigsetmask
-111 STD 1 sigsuspend
-112 COMPAT 2 sigstack
-113 COMPAT 3 recvmsg
-114 COMPAT 3 sendmsg
+46 STD { int sigaction(int signum, struct sigaction *nsa, \
+ struct sigaction *osa); }
+47 STD { gid_t getgid(void); }
+48 STD { int sigprocmask(int how, sigset_t mask); }
+49 STD { int getlogin(char *namebuf, u_int namelen); }
+50 STD { int setlogin(char *namebuf); }
+51 STD { int acct(char *path); }
+52 STD { int sigpending(void); }
+53 STD { int sigaltstack(struct sigaltstack *nss, \
+ struct sigaltstack *oss); }
+54 STD { int ioctl(int fd, u_long com, caddr_t data); }
+55 STD { int reboot(int opt); }
+56 STD { int revoke(char *path); }
+57 STD { int symlink(char *path, char *link); }
+58 STD { int readlink(char *path, char *buf, int count); }
+59 STD { int execve(char *path, char **argp, char **envp); }
+60 STD { int umask(int newmask); }
+61 STD { int chroot(char *path); }
+62 COMPAT_43 { int fstat(int fd, struct ostat *sb); }
+63 COMPAT_43 { int getkerninfo(int op, char *where, int *size, \
+ int arg); }
+64 COMPAT_43 { int getpagesize(void); }
+65 STD { int msync(caddr_t addr, int len); }
+66 STD { int vfork(void); }
+67 OBSOL vread
+68 OBSOL vwrite
+69 STD { int sbrk(int incr); }
+70 STD { int sstk(int incr); }
+71 COMPAT_43 { int mmap(caddr_t addr, int len, int prot, \
+ int flags, int fd, long pos); }
+72 STD { int ovadvise(int anom); } vadvise
+73 STD { int munmap(caddr_t addr, int len); }
+74 STD { int mprotect(caddr_t addr, int len, int prot); }
+75 STD { int madvise(caddr_t addr, int len, int behav); }
+76 OBSOL vhangup
+77 OBSOL vlimit
+78 STD { int mincore(caddr_t addr, int len, char *vec); }
+79 STD { int getgroups(u_int gidsetsize, gid_t *gidset); }
+80 STD { int setgroups(u_int gidsetsize, gid_t *gidset); }
+81 STD { int getpgrp(void); }
+82 STD { int setpgid(int pid, int pgid); }
+83 STD { int setitimer(u_int which, struct itimerval *itv, \
+ struct itimerval *oitv); }
+84 COMPAT_43 { int wait(void); }
+85 STD { int swapon(char *name); }
+86 STD { int getitimer(u_int which, struct itimerval *itv); }
+87 COMPAT_43 { int gethostname(char *hostname, u_int len); }
+88 COMPAT_43 { int sethostname(char *hostname, u_int len); }
+89 STD { int getdtablesize(void); }
+90 STD { int dup2(u_int from, u_int to); }
+91 UNIMPL getdopt
+92 STD { int fcntl(int fd, int cmd, void *arg); }
+93 STD { int select(u_int nd, fd_set *in, fd_set *ou, \
+ fd_set *ex, struct timeval *tv); }
+94 UNIMPL setdopt
+95 STD { int fsync(int fd); }
+96 STD { int setpriority(int which, int who, int prio); }
+97 STD { int socket(int domain, int type, int protocol); }
+98 STD { int connect(int s, caddr_t name, int namelen); }
+99 COMPAT_43 { int accept(int s, caddr_t name, int *anamelen); }
+100 STD { int getpriority(int which, int who); }
+101 COMPAT_43 { int send(int s, caddr_t buf, int len, int flags); }
+102 COMPAT_43 { int recv(int s, caddr_t buf, int len, int flags); }
+103 STD { int sigreturn(struct sigcontext *sigcntxp); }
+104 STD { int bind(int s, caddr_t name, int namelen); }
+105 STD { int setsockopt(int s, int level, int name, \
+ caddr_t val, int valsize); }
+106 STD { int listen(int s, int backlog); }
+107 OBSOL vtimes
+108 COMPAT_43 { int sigvec(int signum, struct sigvec *nsv, \
+ struct sigvec *osv); }
+109 COMPAT_43 { int sigblock(int mask); }
+110 COMPAT_43 { int sigsetmask(int mask); }
+111 STD { int sigsuspend(int mask); }
+112 COMPAT_43 { int sigstack(struct sigstack *nss, \
+ struct sigstack *oss); }
+113 COMPAT_43 { int recvmsg(int s, struct omsghdr *msg, int flags); }
+114 COMPAT_43 { int sendmsg(int s, caddr_t msg, int flags); }
#ifdef TRACE
-115 STD 2 vtrace
+115 STD { int vtrace(int request, int value); }
#else
-115 OBSOL 2 vtrace
+115 OBSOL vtrace
#endif
-116 STD 2 gettimeofday
-117 STD 2 getrusage
-118 STD 5 getsockopt
+116 STD { int gettimeofday(struct timeval *tp, \
+ struct timezone *tzp); }
+117 STD { int getrusage(int who, struct rusage *rusage); }
+118 STD { int getsockopt(int s, int level, int name, \
+ caddr_t val, int *avalsize); }
#ifdef vax
-119 STD 1 resuba
+119 STD { int resuba(int value); }
#else
-119 UNIMPL 0 nosys
+119 UNIMPL resuba
#endif
-120 STD 3 readv
-121 STD 3 writev
-122 STD 2 settimeofday
-123 STD 3 fchown
-124 STD 2 fchmod
-125 COMPAT 6 recvfrom
-126 COMPAT 2 setreuid
-127 COMPAT 2 setregid
-128 STD 2 rename
-129 COMPAT 2 truncate
-130 COMPAT 2 ftruncate
-131 STD 2 flock
-132 STD 2 mkfifo
-133 STD 6 sendto
-134 STD 2 shutdown
-135 STD 5 socketpair
-136 STD 2 mkdir
-137 STD 1 rmdir
-138 STD 2 utimes
-139 OBSOL 0 4.2 sigreturn
-140 STD 2 adjtime
-141 COMPAT 3 getpeername
-142 COMPAT 0 gethostid
-143 COMPAT 1 sethostid
-144 COMPAT 2 getrlimit
-145 COMPAT 2 setrlimit
-146 COMPAT 2 killpg
-147 STD 0 setsid
-148 STD 4 quotactl
-149 COMPAT 4 quota
-150 COMPAT 3 getsockname
+120 STD { int readv(int fd, struct iovec *iovp, u_int iovcnt); }
+121 STD { int writev(int fd, struct iovec *iovp, \
+ u_int iovcnt); }
+122 STD { int settimeofday(struct timeval *tv, \
+ struct timezone *tzp); }
+123 STD { int fchown(int fd, int uid, int gid); }
+124 STD { int fchmod(int fd, int mode); }
+125 COMPAT_43 { int recvfrom(int s, caddr_t buf, size_t len, \
+ int flags, caddr_t from, int *fromlenaddr); }
+126 COMPAT_43 { int setreuid(int ruid, int euid); }
+127 COMPAT_43 { int setregid(int rgid, int egid); }
+128 STD { int rename(char *from, char *to); }
+129 COMPAT_43 { int truncate(char *path, long length); }
+130 COMPAT_43 { int ftruncate(int fd, long length); }
+131 STD { int flock(int fd, int how); }
+132 STD { int mkfifo(char *path, int mode); }
+133 STD { int sendto(int s, caddr_t buf, size_t len, \
+ int flags, caddr_t to, int tolen); }
+134 STD { int shutdown(int s, int how); }
+135 STD { int socketpair(int domain, int type, int protocol, \
+ int *rsv); }
+136 STD { int mkdir(char *path, int mode); }
+137 STD { int rmdir(char *path); }
+138 STD { int utimes(char *path, struct timeval *tptr); }
+139 OBSOL 4.2 sigreturn
+140 STD { int adjtime(struct timeval *delta, \
+ struct timeval *olddelta); }
+141 COMPAT_43 { int getpeername(int fdes, caddr_t asa, int *alen); }
+142 COMPAT_43 { int32_t gethostid(void); }
+143 COMPAT_43 { int sethostid(int32_t hostid); }
+144 COMPAT_43 { int getrlimit(u_int which, struct ogetrlimit *rlp); }
+145 COMPAT_43 { int setrlimit(u_int which, struct ogetrlimit *rlp); }
+146 COMPAT_43 { int killpg(int pgid, int signum); }
+147 STD { int setsid(void); }
+148 STD { int quotactl(char *path, int cmd, int uid, \
+ caddr_t arg); }
+149 COMPAT_43 { int quota(void); }
+150 COMPAT_43 { int getsockname(int fdec, caddr_t asa, int *alen); }
; Syscalls 151-180 inclusive are reserved for vendor-specific
; system calls. (This includes various calls added for compatibity
; with other Unix variants.)
; Some of these calls are now supported by BSD...
-151 UNIMPL 0 nosys
-152 UNIMPL 0 nosys
-153 UNIMPL 0 nosys
-154 UNIMPL 0 nosys
+151 UNIMPL
+152 UNIMPL
+153 UNIMPL
+154 UNIMPL
#ifdef NFS
-155 STD 2 nfssvc
+155 STD { int nfssvc(int flag, caddr_t argp); }
#else
-155 UNIMPL 0 nosys
+155 UNIMPL nfssvc
#endif
-156 COMPAT 4 getdirentries
-157 STD 2 statfs
-158 STD 2 fstatfs
-159 UNIMPL 0 nosys
-160 UNIMPL 0 nosys
+156 COMPAT_43 { int getdirentries(int fd, char *buf, u_int count, \
+ long *basep); }
+157 STD { int statfs(char *path, struct statfs *buf); }
+158 STD { int fstatfs(int fd, struct statfs *buf); }
+159 UNIMPL
+160 UNIMPL
#ifdef NFS
-161 STD 2 getfh
+161 STD { int getfh(char *fname, fhandle_t *fhp); }
#else
-161 UNIMPL 0 nosys
+161 UNIMPL getfh
#endif
-162 UNIMPL 0 nosys
-163 UNIMPL 0 nosys
-164 UNIMPL 0 nosys
-165 UNIMPL 0 nosys
-166 UNIMPL 0 nosys
-167 UNIMPL 0 nosys
-168 UNIMPL 0 nosys
-169 UNIMPL 0 nosys
-170 UNIMPL 0 nosys
-#ifdef SYSVSHM
-171 STD 4 shmsys
+162 UNIMPL getdomainname
+163 UNIMPL setdomainname
+164 UNIMPL
+165 UNIMPL
+166 UNIMPL
+167 UNIMPL
+168 UNIMPL
+169 UNIMPL semsys
+170 UNIMPL msgsys
+; XXX more generally, never on machines where sizeof(void *) != sizeof(int)
+#if defined(SYSVSHM) && !defined(alpha)
+171 COMPAT_43 { int shmsys(int which, int a2, int a3, int a4); }
#else
-171 UNIMPL 0 nosys
+171 UNIMPL shmsys
#endif
-172 UNIMPL 0 nosys
-173 UNIMPL 0 nosys
-174 UNIMPL 0 nosys
-175 UNIMPL 0 nosys
-176 UNIMPL 0 nosys
-177 UNIMPL 0 nosys
-178 UNIMPL 0 nosys
-179 UNIMPL 0 nosys
-180 UNIMPL 0 nosys
+172 UNIMPL
+173 UNIMPL
+174 UNIMPL
+175 UNIMPL
+176 UNIMPL
+177 UNIMPL
+178 UNIMPL
+179 UNIMPL
+180 UNIMPL
-; Syscalls 180-199 are used by/reserved for BSD
-181 STD 1 setgid
-182 STD 1 setegid
-183 STD 1 seteuid
+; Syscalls 180-209 are used by/reserved for BSD
+181 STD { int setgid(gid_t gid); }
+182 STD { int setegid(gid_t egid); }
+183 STD { int seteuid(uid_t euid); }
#ifdef LFS
-184 STD 3 lfs_bmapv
-185 STD 3 lfs_markv
-186 STD 2 lfs_segclean
-187 STD 2 lfs_segwait
+184 STD { int lfs_bmapv(fsid_t *fsidp, \
+ struct block_info *blkiov, int blkcnt); }
+185 STD { int lfs_markv(fsid_t *fsidp, \
+ struct block_info *blkiov, int blkcnt); }
+186 STD { int lfs_segclean(fsid_t *fsidp, u_long segment); }
+187 STD { int lfs_segwait(fsid_t *fsidp, struct timeval *tv); }
+#else
+184 UNIMPL lfs_bmapv
+185 UNIMPL lfs_markv
+186 UNIMPL lfs_segclean
+187 UNIMPL lfs_segwait
+#endif
+188 STD { int stat(char *path, struct stat *ub); }
+189 STD { int fstat(int fd, struct stat *sb); }
+190 STD { int lstat(char *path, struct stat *ub); }
+191 STD { int pathconf(char *path, int name); }
+192 STD { int fpathconf(int fd, int name); }
+193 UNIMPL
+194 STD { int getrlimit(u_int which, struct rlimit *rlp); }
+195 STD { int setrlimit(u_int which, struct rlimit *rlp); }
+196 STD { int getdirentries(int fd, char *buf, u_int count, \
+ long *basep); }
+197 STD { caddr_t mmap(caddr_t addr, size_t len, int prot, \
+ int flags, int fd, long pad, off_t pos); }
+198 STD { int nosys(void); } __syscall
+199 STD { off_t lseek(int fd, int pad, off_t offset, \
+ int whence); }
+200 STD { int truncate(char *path, int pad, off_t length); }
+201 STD { int ftruncate(int fd, int pad, off_t length); }
+202 STD { int __sysctl(int *name, u_int namelen, void *old, \
+ size_t *oldlenp, void *new, size_t newlen); }
+203 STD { int mlock(caddr_t addr, size_t len); }
+204 STD { int munlock(caddr_t addr, size_t len); }
+205 STD { int undelete(char *path); }
+206 UNIMPL
+207 UNIMPL
+208 UNIMPL
+209 UNIMPL
+; Syscalls 210-219 are used by/reserved for vendor-specific system calls
+210 UNIMPL
+211 UNIMPL
+212 UNIMPL
+213 UNIMPL
+214 UNIMPL
+215 UNIMPL
+216 UNIMPL
+217 UNIMPL
+218 UNIMPL
+219 UNIMPL
+; System calls 220-240 are reserved for use by BSD
+220 UNIMPL semctl
+221 UNIMPL semget
+222 UNIMPL semop
+223 UNIMPL semconfig
+224 UNIMPL msgctl
+225 UNIMPL msgget
+226 UNIMPL msgsnd
+227 UNIMPL msgrcv
+#if defined(SYSVSHM) && 0
+228 STD { int shmat(int shmid, void *shmaddr, int shmflg); }
+229 STD { int shmctl(int shmid, int cmd, \
+ struct shmid_ds *buf); }
+230 STD { int shmdt(void *shmaddr); }
+231 STD { int shmget(key_t key, int size, int shmflg); }
#else
-184 UNIMPL 0 nosys
-185 UNIMPL 0 nosys
-186 UNIMPL 0 nosys
-187 UNIMPL 0 nosys
+228 UNIMPL shmat
+229 UNIMPL shmctl
+230 UNIMPL shmdt
+231 UNIMPL shmget
#endif
-188 STD 2 stat
-189 STD 2 fstat
-190 STD 2 lstat
-191 STD 2 pathconf
-192 STD 2 fpathconf
-193 UNIMPL 0 nosys
-194 STD 2 getrlimit
-195 STD 2 setrlimit
-196 STD 4 getdirentries
-197 STD 8 mmap
-198 STD 0 nosys __syscall
-199 STD 5 lseek
-200 STD 4 truncate
-201 STD 4 ftruncate
-202 STD 6 __sysctl
-203 STD 2 mlock
-204 STD 2 munlock
-205 UNIMPL 0 nosys
-206 UNIMPL 0 nosys
-207 UNIMPL 0 nosys
-208 UNIMPL 0 nosys
-209 UNIMPL 0 nosys
-210 UNIMPL 0 nosys
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 6cc7be2..5d698b1 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)tty.c 8.8 (Berkeley) 1/21/94
+ * @(#)tty.c 8.13 (Berkeley) 1/9/95
*/
#include <sys/param.h>
@@ -531,7 +531,7 @@ ttyoutput(c, tp)
register struct tty *tp;
{
register long oflag;
- register int col, s;
+ register int notout, col, s;
oflag = tp->t_oflag;
if (!ISSET(oflag, OPOST)) {
@@ -553,15 +553,18 @@ ttyoutput(c, tp)
if (c == '\t' &&
ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
c = 8 - (tp->t_column & 7);
- if (!ISSET(tp->t_lflag, FLUSHO)) {
+ if (ISSET(tp->t_lflag, FLUSHO)) {
+ notout = 0;
+ } else {
s = spltty(); /* Don't interrupt tabs. */
- c -= b_to_q(" ", c, &tp->t_outq);
+ notout = b_to_q(" ", c, &tp->t_outq);
+ c -= notout;
tk_nout += c;
tp->t_outcc += c;
splx(s);
}
tp->t_column += c;
- return (c ? -1 : '\t');
+ return (notout ? '\t' : -1);
}
if (c == CEOT && ISSET(oflag, ONOEOT))
return (-1);
@@ -613,8 +616,9 @@ ttyoutput(c, tp)
int
ttioctl(tp, cmd, data, flag)
register struct tty *tp;
- int cmd, flag;
+ u_long cmd;
void *data;
+ int flag;
{
extern struct tty *constty; /* Temporary virtual console. */
extern int nlinesw;
@@ -1766,11 +1770,11 @@ ttyinfo(tp)
ttyprintf(tp, "not a controlling terminal\n");
else if (tp->t_pgrp == NULL)
ttyprintf(tp, "no foreground process group\n");
- else if ((p = tp->t_pgrp->pg_mem) == NULL)
+ else if ((p = tp->t_pgrp->pg_members.lh_first) == 0)
ttyprintf(tp, "empty foreground process group\n");
else {
/* Pick interesting process. */
- for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
+ for (pick = NULL; p != 0; p = p->p_pglist.le_next)
if (proc_compare(pick, p))
pick = p;
diff --git a/sys/kern/tty_compat.c b/sys/kern/tty_compat.c
index a6a39d9..ce95853 100644
--- a/sys/kern/tty_compat.c
+++ b/sys/kern/tty_compat.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93
+ * @(#)tty_compat.c 8.2 (Berkeley) 1/9/95
*/
/*
@@ -78,7 +78,7 @@ static int compatspcodes[16] = {
/*ARGSUSED*/
ttcompat(tp, com, data, flag)
register struct tty *tp;
- int com;
+ u_long com;
caddr_t data;
int flag;
{
diff --git a/sys/kern/tty_conf.c b/sys/kern/tty_conf.c
index b53edb42..1453675 100644
--- a/sys/kern/tty_conf.c
+++ b/sys/kern/tty_conf.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)tty_conf.c 8.4 (Berkeley) 1/21/94
+ * @(#)tty_conf.c 8.5 (Berkeley) 1/9/95
*/
#include <sys/param.h>
@@ -52,7 +52,7 @@
#define ttyerrinput ((int (*) __P((int c, struct tty *)))enodev)
#define ttyerrstart ((int (*) __P((struct tty *)))enodev)
-int nullioctl __P((struct tty *tp, int cmd, caddr_t data,
+int nullioctl __P((struct tty *tp, u_long cmd, caddr_t data,
int flag, struct proc *p));
#include "tb.h"
@@ -60,7 +60,7 @@ int nullioctl __P((struct tty *tp, int cmd, caddr_t data,
int tbopen __P((dev_t dev, struct tty *tp));
int tbclose __P((struct tty *tp, int flags));
int tbread __P((struct tty *, struct uio *, int flags));
-int tbioctl __P((struct tty *tp, int cmd, caddr_t data,
+int tbioctl __P((struct tty *tp, u_long cmd, caddr_t data,
int flag, struct proc *p));
int tbinput __P((int c, struct tty *tp));
#endif
@@ -69,7 +69,7 @@ int tbinput __P((int c, struct tty *tp));
#if NSL > 0
int slopen __P((dev_t dev, struct tty *tp));
int slclose __P((struct tty *tp, int flags));
-int sltioctl __P((struct tty *tp, int cmd, caddr_t data,
+int sltioctl __P((struct tty *tp, u_long cmd, caddr_t data,
int flag, struct proc *p));
int slinput __P((int c, struct tty *tp));
int slstart __P((struct tty *tp));
@@ -113,7 +113,7 @@ int nlinesw = sizeof (linesw) / sizeof (linesw[0]);
/*ARGSUSED*/
nullioctl(tp, cmd, data, flags, p)
struct tty *tp;
- int cmd;
+ u_long cmd;
char *data;
int flags;
struct proc *p;
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 0e6911b..2c37984 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)tty_pty.c 8.2 (Berkeley) 9/23/93
+ * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95
*/
/*
@@ -536,7 +536,7 @@ block:
/*ARGSUSED*/
ptyioctl(dev, cmd, data, flag, p)
dev_t dev;
- int cmd;
+ u_long cmd;
caddr_t data;
int flag;
struct proc *p;
@@ -563,7 +563,7 @@ ptyioctl(dev, cmd, data, flag, p)
}
tp->t_lflag |= EXTPROC;
} else {
- if ((tp->t_state & EXTPROC) &&
+ if ((tp->t_lflag & EXTPROC) &&
(pti->pt_flags & PF_PKT)) {
pti->pt_send |= TIOCPKT_IOCTL;
ptcwakeup(tp, FREAD);
diff --git a/sys/kern/tty_tb.c b/sys/kern/tty_tb.c
index 242301a..05a46ba 100644
--- a/sys/kern/tty_tb.c
+++ b/sys/kern/tty_tb.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)tty_tb.c 8.1 (Berkeley) 6/10/93
+ * @(#)tty_tb.c 8.2 (Berkeley) 1/9/95
*/
#include "tb.h"
@@ -310,7 +310,9 @@ poldecode(tc, cp, polpos)
/*ARGSUSED*/
tbioctl(tp, cmd, data, flag)
struct tty *tp;
+ u_long cmd;
caddr_t data;
+ int flag;
{
register struct tb *tbp = (struct tb *)tp->T_LINEP;
diff --git a/sys/kern/tty_tty.c b/sys/kern/tty_tty.c
index 964fc6f..d9dd1b4 100644
--- a/sys/kern/tty_tty.c
+++ b/sys/kern/tty_tty.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1982, 1986, 1991, 1993
+ * Copyright (c) 1982, 1986, 1991, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)tty_tty.c 8.2 (Berkeley) 9/23/93
+ * @(#)tty_tty.c 8.4 (Berkeley) 5/14/95
*/
/*
@@ -58,7 +58,7 @@ cttyopen(dev, flag, mode, p)
if (ttyvp == NULL)
return (ENXIO);
- VOP_LOCK(ttyvp);
+ vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
#ifdef PARANOID
/*
* Since group is tty and mode is 620 on most terminal lines
@@ -73,7 +73,7 @@ cttyopen(dev, flag, mode, p)
if (!error)
#endif /* PARANOID */
error = VOP_OPEN(ttyvp, flag, NOCRED, p);
- VOP_UNLOCK(ttyvp);
+ VOP_UNLOCK(ttyvp, 0, p);
return (error);
}
@@ -83,14 +83,15 @@ cttyread(dev, uio, flag)
struct uio *uio;
int flag;
{
- register struct vnode *ttyvp = cttyvp(uio->uio_procp);
+ struct proc *p = uio->uio_procp;
+ register struct vnode *ttyvp = cttyvp(p);
int error;
if (ttyvp == NULL)
return (EIO);
- VOP_LOCK(ttyvp);
+ vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_READ(ttyvp, uio, flag, NOCRED);
- VOP_UNLOCK(ttyvp);
+ VOP_UNLOCK(ttyvp, 0, p);
return (error);
}
@@ -100,21 +101,22 @@ cttywrite(dev, uio, flag)
struct uio *uio;
int flag;
{
- register struct vnode *ttyvp = cttyvp(uio->uio_procp);
+ struct proc *p = uio->uio_procp;
+ struct vnode *ttyvp = cttyvp(uio->uio_procp);
int error;
if (ttyvp == NULL)
return (EIO);
- VOP_LOCK(ttyvp);
+ vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_WRITE(ttyvp, uio, flag, NOCRED);
- VOP_UNLOCK(ttyvp);
+ VOP_UNLOCK(ttyvp, 0, p);
return (error);
}
/*ARGSUSED*/
cttyioctl(dev, cmd, addr, flag, p)
dev_t dev;
- int cmd;
+ u_long cmd;
caddr_t addr;
int flag;
struct proc *p;
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index 8834dbf..1c91f2a 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
+ * @(#)uipc_domain.c 8.3 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -54,6 +54,7 @@ void pfslowtimo __P((void *));
domains = &__CONCAT(x,domain); \
}
+void
domaininit()
{
register struct domain *dp;
@@ -93,8 +94,8 @@ if (max_linkhdr < 16) /* XXX */
max_linkhdr = 16;
max_hdr = max_linkhdr + max_protohdr;
max_datalen = MHLEN - max_hdr;
- timeout(pffasttimo, (void *)0, 1);
- timeout(pfslowtimo, (void *)0, 1);
+ timeout(pffasttimo, NULL, 1);
+ timeout(pfslowtimo, NULL, 1);
}
struct protosw *
@@ -141,6 +142,7 @@ found:
return (maybe);
}
+int
net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
int *name;
u_int namelen;
@@ -178,6 +180,7 @@ found:
return (ENOPROTOOPT);
}
+void
pfctlinput(cmd, sa)
int cmd;
struct sockaddr *sa;
@@ -202,7 +205,7 @@ pfslowtimo(arg)
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
if (pr->pr_slowtimo)
(*pr->pr_slowtimo)();
- timeout(pfslowtimo, (void *)0, hz/2);
+ timeout(pfslowtimo, NULL, hz/2);
}
void
@@ -216,5 +219,5 @@ pffasttimo(arg)
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
if (pr->pr_fasttimo)
(*pr->pr_fasttimo)();
- timeout(pffasttimo, (void *)0, hz/5);
+ timeout(pffasttimo, NULL, hz/5);
}
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index b71c634..62abfd5 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
+ * @(#)uipc_mbuf.c 8.4 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -51,17 +51,13 @@ extern vm_map_t mb_map;
struct mbuf *mbutl;
char *mclrefcnt;
+void
mbinit()
{
int s;
-#if CLBYTES < 4096
-#define NCL_INIT (4096/CLBYTES)
-#else
-#define NCL_INIT 1
-#endif
s = splimp();
- if (m_clalloc(NCL_INIT, M_DONTWAIT) == 0)
+ if (m_clalloc(max(4096/CLBYTES, 1), M_DONTWAIT) == 0)
goto bad;
splx(s);
return;
@@ -75,6 +71,7 @@ bad:
* Must be called at splimp.
*/
/* ARGSUSED */
+int
m_clalloc(ncl, nowait)
register int ncl;
int nowait;
@@ -137,6 +134,7 @@ m_retryhdr(i, t)
return (m);
}
+void
m_reclaim()
{
register struct domain *dp;
@@ -323,6 +321,7 @@ nospace:
* Copy data from an mbuf chain starting "off" bytes from the beginning,
* continuing for "len" bytes, into the indicated buffer.
*/
+void
m_copydata(m, off, len, cp)
register struct mbuf *m;
register int off;
@@ -358,6 +357,7 @@ m_copydata(m, off, len, cp)
* Both chains must be of the same type (e.g. MT_DATA).
* Any m_pkthdr is not updated.
*/
+void
m_cat(m, n)
register struct mbuf *m, *n;
{
@@ -378,6 +378,7 @@ m_cat(m, n)
}
}
+void
m_adj(mp, req_len)
struct mbuf *mp;
int req_len;
@@ -603,8 +604,12 @@ m_devget(buf, totlen, off0, ifp, copy)
cp = buf;
epkt = cp + totlen;
if (off) {
- cp += off + 2 * sizeof(u_short);
- totlen -= 2 * sizeof(u_short);
+ /*
+ * If 'off' is non-zero, packet is trailer-encapsulated,
+ * so we have to skip the type and length fields.
+ */
+ cp += off + 2 * sizeof(u_int16_t);
+ totlen -= 2 * sizeof(u_int16_t);
}
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == 0)
diff --git a/sys/kern/uipc_proto.c b/sys/kern/uipc_proto.c
index da9828a..e89a84c 100644
--- a/sys/kern/uipc_proto.c
+++ b/sys/kern/uipc_proto.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)uipc_proto.c 8.1 (Berkeley) 6/10/93
+ * @(#)uipc_proto.c 8.2 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -44,7 +44,7 @@
*/
int uipc_usrreq(), raw_usrreq();
-void raw_init(),raw_input(),raw_ctlinput();
+void raw_init(), raw_input(), raw_ctlinput();
extern struct domain unixdomain; /* or at least forward */
struct protosw unixsw[] = {
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index ed09ee6..a9c5453 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
+ * @(#)uipc_socket.c 8.6 (Berkeley) 5/2/95
*/
#include <sys/param.h>
@@ -54,6 +54,7 @@
* switching out to the protocol specific routines.
*/
/*ARGSUSED*/
+int
socreate(dom, aso, type, proto)
int dom;
struct socket **aso;
@@ -79,9 +80,8 @@ socreate(dom, aso, type, proto)
if (p->p_ucred->cr_uid == 0)
so->so_state = SS_PRIV;
so->so_proto = prp;
- error =
- (*prp->pr_usrreq)(so, PRU_ATTACH,
- (struct mbuf *)0, (struct mbuf *)proto, (struct mbuf *)0);
+ error = (*prp->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0,
+ (struct mbuf *)(long)proto, (struct mbuf *)0);
if (error) {
so->so_state |= SS_NOFDREF;
sofree(so);
@@ -91,6 +91,7 @@ socreate(dom, aso, type, proto)
return (0);
}
+int
sobind(so, nam)
struct socket *so;
struct mbuf *nam;
@@ -105,6 +106,7 @@ sobind(so, nam)
return (error);
}
+int
solisten(so, backlog)
register struct socket *so;
int backlog;
@@ -127,6 +129,7 @@ solisten(so, backlog)
return (0);
}
+int
sofree(so)
register struct socket *so;
{
@@ -148,6 +151,7 @@ sofree(so)
* Initiate disconnect if connected.
* Free socket when disconnect complete.
*/
+int
soclose(so)
register struct socket *so;
{
@@ -174,7 +178,7 @@ soclose(so)
goto drop;
while (so->so_state & SS_ISCONNECTED)
if (error = tsleep((caddr_t)&so->so_timeo,
- PSOCK | PCATCH, netcls, so->so_linger))
+ PSOCK | PCATCH, netcls, so->so_linger * hz))
break;
}
}
@@ -198,6 +202,7 @@ discard:
/*
* Must be called at splnet...
*/
+int
soabort(so)
struct socket *so;
{
@@ -207,6 +212,7 @@ soabort(so)
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
}
+int
soaccept(so, nam)
register struct socket *so;
struct mbuf *nam;
@@ -223,6 +229,7 @@ soaccept(so, nam)
return (error);
}
+int
soconnect(so, nam)
register struct socket *so;
struct mbuf *nam;
@@ -250,6 +257,7 @@ soconnect(so, nam)
return (error);
}
+int
soconnect2(so1, so2)
register struct socket *so1;
struct socket *so2;
@@ -263,6 +271,7 @@ soconnect2(so1, so2)
return (error);
}
+int
sodisconnect(so)
register struct socket *so;
{
@@ -302,6 +311,7 @@ bad:
* must check for short counts if EINTR/ERESTART are returned.
* Data and control buffers are freed on return.
*/
+int
sosend(so, addr, uio, top, control, flags)
register struct socket *so;
struct mbuf *addr;
@@ -477,6 +487,7 @@ out:
* an mbuf **mp0 for use in returning the chain. The uio is then used
* only for the count in uio_resid.
*/
+int
soreceive(so, paddr, uio, mp0, controlp, flagsp)
register struct socket *so;
struct mbuf **paddr;
@@ -503,8 +514,8 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp)
flags = 0;
if (flags & MSG_OOB) {
m = m_get(M_WAIT, MT_DATA);
- error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
- m, (struct mbuf *)(flags & MSG_PEEK), (struct mbuf *)0);
+ error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
+ (struct mbuf *)(long)(flags & MSG_PEEK), (struct mbuf *)0);
if (error)
goto bad;
do {
@@ -534,8 +545,8 @@ restart:
* (subject to any timeout) if:
* 1. the current count is less than the low water mark, or
* 2. MSG_WAITALL is set, and it is possible to do the entire
- * receive operation at once if we block (resid <= hiwat).
- * 3. MSG_DONTWAIT is not set
+ * receive operation at once if we block (resid <= hiwat), or
+ * 3. MSG_DONTWAIT is not set.
* If MSG_WAITALL is set but resid is larger than the receive buffer,
* we have to do the receive in sections, and thus risk returning
* a short count if a timeout or signal occurs after we start.
@@ -757,7 +768,7 @@ dontblock:
so->so_rcv.sb_mb = nextrecord;
if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
- (struct mbuf *)flags, (struct mbuf *)0,
+ (struct mbuf *)(long)flags, (struct mbuf *)0,
(struct mbuf *)0);
}
if (orig_resid == uio->uio_resid && orig_resid &&
@@ -775,6 +786,7 @@ release:
return (error);
}
+int
soshutdown(so, how)
register struct socket *so;
register int how;
@@ -790,6 +802,7 @@ soshutdown(so, how)
return (0);
}
+void
sorflush(so)
register struct socket *so;
{
@@ -811,6 +824,7 @@ sorflush(so)
sbrelease(&asb);
}
+int
sosetopt(so, level, optname, m0)
register struct socket *so;
int level, optname;
@@ -893,7 +907,7 @@ sosetopt(so, level, optname, m0)
goto bad;
}
tv = mtod(m, struct timeval *);
- if (tv->tv_sec > SHRT_MAX / hz - hz) {
+ if (tv->tv_sec * hz + tv->tv_usec / tick > SHRT_MAX) {
error = EDOM;
goto bad;
}
@@ -927,6 +941,7 @@ bad:
return (error);
}
+int
sogetopt(so, level, optname, mp)
register struct socket *so;
int level, optname;
@@ -998,7 +1013,7 @@ sogetopt(so, level, optname, mp)
m->m_len = sizeof(struct timeval);
mtod(m, struct timeval *)->tv_sec = val / hz;
mtod(m, struct timeval *)->tv_usec =
- (val % hz) / tick;
+ (val % hz) * tick;
break;
}
@@ -1011,6 +1026,7 @@ sogetopt(so, level, optname, mp)
}
}
+void
sohasoutofband(so)
register struct socket *so;
{
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index d4af592..865108a 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
+ * @(#)uipc_socket2.c 8.2 (Berkeley) 2/14/95
*/
#include <sys/param.h>
@@ -85,6 +85,7 @@ u_long sb_max = SB_MAX; /* patchable */
* cause software-interrupt process scheduling.
*/
+void
soisconnecting(so)
register struct socket *so;
{
@@ -93,6 +94,7 @@ soisconnecting(so)
so->so_state |= SS_ISCONNECTING;
}
+void
soisconnected(so)
register struct socket *so;
{
@@ -111,6 +113,7 @@ soisconnected(so)
}
}
+void
soisdisconnecting(so)
register struct socket *so;
{
@@ -122,6 +125,7 @@ soisdisconnecting(so)
sorwakeup(so);
}
+void
soisdisconnected(so)
register struct socket *so;
{
@@ -181,6 +185,7 @@ sonewconn1(head, connstatus)
return (so);
}
+void
soqinsque(head, so, q)
register struct socket *head, *so;
int q;
@@ -202,6 +207,7 @@ soqinsque(head, so, q)
*prev = so;
}
+int
soqremque(so, q)
register struct socket *so;
int q;
@@ -240,6 +246,7 @@ soqremque(so, q)
* Data queued for reading in the socket may yet be read.
*/
+void
socantsendmore(so)
struct socket *so;
{
@@ -248,6 +255,7 @@ socantsendmore(so)
sowwakeup(so);
}
+void
socantrcvmore(so)
struct socket *so;
{
@@ -259,6 +267,7 @@ socantrcvmore(so)
/*
* Wait for data to arrive at/drain from a socket buffer.
*/
+int
sbwait(sb)
struct sockbuf *sb;
{
@@ -273,6 +282,7 @@ sbwait(sb)
* Lock a sockbuf already known to be locked;
* return any error returned from sleep (EINTR).
*/
+int
sb_lock(sb)
register struct sockbuf *sb;
{
@@ -294,6 +304,7 @@ sb_lock(sb)
* Do asynchronous notification via SIGIO
* if the socket has the SS_ASYNC flag set.
*/
+void
sowakeup(so, sb)
register struct socket *so;
register struct sockbuf *sb;
@@ -346,6 +357,7 @@ sowakeup(so, sb)
* should be released by calling sbrelease() when the socket is destroyed.
*/
+int
soreserve(so, sndcc, rcvcc)
register struct socket *so;
u_long sndcc, rcvcc;
@@ -373,6 +385,7 @@ bad:
* Attempt to scale mbmax so that mbcnt doesn't become limiting
* if buffering efficiency is near the normal case.
*/
+int
sbreserve(sb, cc)
struct sockbuf *sb;
u_long cc;
@@ -390,6 +403,7 @@ sbreserve(sb, cc)
/*
* Free mbufs held by a socket, and reserved mbuf space.
*/
+void
sbrelease(sb)
struct sockbuf *sb;
{
@@ -429,6 +443,7 @@ sbrelease(sb)
* the mbuf chain is recorded in sb. Empty mbufs are
* discarded and mbufs are compacted where possible.
*/
+void
sbappend(sb, m)
struct sockbuf *sb;
struct mbuf *m;
@@ -451,6 +466,7 @@ sbappend(sb, m)
}
#ifdef SOCKBUF_DEBUG
+void
sbcheck(sb)
register struct sockbuf *sb;
{
@@ -477,6 +493,7 @@ sbcheck(sb)
* As above, except the mbuf chain
* begins a new record.
*/
+void
sbappendrecord(sb, m0)
register struct sockbuf *sb;
register struct mbuf *m0;
@@ -511,6 +528,7 @@ sbappendrecord(sb, m0)
* is inserted at the beginning of the sockbuf,
* but after any other OOB data.
*/
+void
sbinsertoob(sb, m0)
register struct sockbuf *sb;
register struct mbuf *m0;
@@ -555,6 +573,7 @@ sbinsertoob(sb, m0)
* m0 must include a packet header with total length.
* Returns 0 if no space in sockbuf or insufficient mbufs.
*/
+int
sbappendaddr(sb, asa, m0, control)
register struct sockbuf *sb;
struct sockaddr *asa;
@@ -597,9 +616,10 @@ panic("sbappendaddr");
return (1);
}
+int
sbappendcontrol(sb, m0, control)
struct sockbuf *sb;
- struct mbuf *control, *m0;
+ struct mbuf *m0, *control;
{
register struct mbuf *m, *n;
int space = 0;
@@ -633,6 +653,7 @@ sbappendcontrol(sb, m0, control)
* buffer sb following mbuf n. If n
* is null, the buffer is presumed empty.
*/
+void
sbcompress(sb, m, n)
register struct sockbuf *sb;
register struct mbuf *m, *n;
@@ -681,6 +702,7 @@ sbcompress(sb, m, n)
* Free all mbufs in a sockbuf.
* Check that all resources are reclaimed.
*/
+void
sbflush(sb)
register struct sockbuf *sb;
{
@@ -696,6 +718,7 @@ sbflush(sb)
/*
* Drop data from (the front of) a sockbuf.
*/
+void
sbdrop(sb, len)
register struct sockbuf *sb;
register int len;
@@ -739,6 +762,7 @@ sbdrop(sb, len)
* Drop a record off the front of a sockbuf
* and move the next record to the front.
*/
+void
sbdroprecord(sb)
register struct sockbuf *sb;
{
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 89b7ffd..800434c 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -30,10 +30,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
+ * @(#)uipc_syscalls.c 8.6 (Berkeley) 2/14/95
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/file.h>
@@ -47,6 +48,9 @@
#include <sys/ktrace.h>
#endif
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
/*
* System call interface to the socket abstraction.
*/
@@ -56,15 +60,15 @@
extern struct fileops socketops;
-struct socket_args {
- int domain;
- int type;
- int protocol;
-};
+int
socket(p, uap, retval)
struct proc *p;
- register struct socket_args *uap;
- int *retval;
+ register struct socket_args /* {
+ syscallarg(int) domain;
+ syscallarg(int) type;
+ syscallarg(int) protocol;
+ } */ *uap;
+ register_t *retval;
{
struct filedesc *fdp = p->p_fd;
struct socket *so;
@@ -76,7 +80,8 @@ socket(p, uap, retval)
fp->f_flag = FREAD|FWRITE;
fp->f_type = DTYPE_SOCKET;
fp->f_ops = &socketops;
- if (error = socreate(uap->domain, &so, uap->type, uap->protocol)) {
+ if (error = socreate(SCARG(uap, domain), &so, SCARG(uap, type),
+ SCARG(uap, protocol))) {
fdp->fd_ofiles[fd] = 0;
ffree(fp);
} else {
@@ -86,96 +91,102 @@ socket(p, uap, retval)
return (error);
}
-struct bind_args {
- int s;
- caddr_t name;
- int namelen;
-};
/* ARGSUSED */
+int
bind(p, uap, retval)
struct proc *p;
- register struct bind_args *uap;
- int *retval;
+ register struct bind_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) name;
+ syscallarg(int) namelen;
+ } */ *uap;
+ register_t *retval;
{
struct file *fp;
struct mbuf *nam;
int error;
- if (error = getsock(p->p_fd, uap->s, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, s), &fp))
return (error);
- if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
+ if (error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
+ MT_SONAME))
return (error);
error = sobind((struct socket *)fp->f_data, nam);
m_freem(nam);
return (error);
}
-struct listen_args {
- int s;
- int backlog;
-};
/* ARGSUSED */
+int
listen(p, uap, retval)
struct proc *p;
- register struct listen_args *uap;
- int *retval;
+ register struct listen_args /* {
+ syscallarg(int) s;
+ syscallarg(int) backlog;
+ } */ *uap;
+ register_t *retval;
{
struct file *fp;
int error;
- if (error = getsock(p->p_fd, uap->s, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, s), &fp))
return (error);
- return (solisten((struct socket *)fp->f_data, uap->backlog));
+ return (solisten((struct socket *)fp->f_data, SCARG(uap, backlog)));
}
-struct accept_args {
- int s;
- caddr_t name;
- int *anamelen;
-#ifdef COMPAT_OLDSOCK
- int compat_43; /* pseudo */
-#endif
-};
-
#ifdef COMPAT_OLDSOCK
+int
accept(p, uap, retval)
struct proc *p;
- struct accept_args *uap;
- int *retval;
+ struct accept_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) name;
+ syscallarg(int *) anamelen;
+ } */ *uap;
+ register_t *retval;
{
- uap->compat_43 = 0;
- return (accept1(p, uap, retval));
+ return (accept1(p, uap, retval, 0));
}
-oaccept(p, uap, retval)
+int
+compat_43_accept(p, uap, retval)
struct proc *p;
- struct accept_args *uap;
- int *retval;
+ struct accept_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) name;
+ syscallarg(int *) anamelen;
+ } */ *uap;
+ register_t *retval;
{
- uap->compat_43 = 1;
- return (accept1(p, uap, retval));
+ return (accept1(p, uap, retval, 1));
}
#else /* COMPAT_OLDSOCK */
#define accept1 accept
#endif
-accept1(p, uap, retval)
+int
+accept1(p, uap, retval, compat_43)
struct proc *p;
- register struct accept_args *uap;
- int *retval;
+ register struct accept_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) name;
+ syscallarg(int *) anamelen;
+ } */ *uap;
+ register_t *retval;
+ int compat_43;
{
struct file *fp;
struct mbuf *nam;
- int namelen, error, s;
+ int namelen, error, s, tmpfd;
register struct socket *so;
- if (uap->name && (error = copyin((caddr_t)uap->anamelen,
+ if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, anamelen),
(caddr_t)&namelen, sizeof (namelen))))
return (error);
- if (error = getsock(p->p_fd, uap->s, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, s), &fp))
return (error);
s = splnet();
so = (struct socket *)fp->f_data;
@@ -204,10 +215,11 @@ accept1(p, uap, retval)
splx(s);
return (error);
}
- if (error = falloc(p, &fp, retval)) {
+ if (error = falloc(p, &fp, &tmpfd)) {
splx(s);
return (error);
}
+ *retval = tmpfd;
{ struct socket *aso = so->so_q;
if (soqremque(aso, 1) == 0)
panic("accept");
@@ -219,47 +231,49 @@ accept1(p, uap, retval)
fp->f_data = (caddr_t)so;
nam = m_get(M_WAIT, MT_SONAME);
(void) soaccept(so, nam);
- if (uap->name) {
+ if (SCARG(uap, name)) {
#ifdef COMPAT_OLDSOCK
- if (uap->compat_43)
+ if (compat_43)
mtod(nam, struct osockaddr *)->sa_family =
mtod(nam, struct sockaddr *)->sa_family;
#endif
if (namelen > nam->m_len)
namelen = nam->m_len;
/* SHOULD COPY OUT A CHAIN HERE */
- if ((error = copyout(mtod(nam, caddr_t), (caddr_t)uap->name,
- (u_int)namelen)) == 0)
+ if ((error = copyout(mtod(nam, caddr_t),
+ (caddr_t)SCARG(uap, name), (u_int)namelen)) == 0)
error = copyout((caddr_t)&namelen,
- (caddr_t)uap->anamelen, sizeof (*uap->anamelen));
+ (caddr_t)SCARG(uap, anamelen),
+ sizeof (*SCARG(uap, anamelen)));
}
m_freem(nam);
splx(s);
return (error);
}
-struct connect_args {
- int s;
- caddr_t name;
- int namelen;
-};
/* ARGSUSED */
+int
connect(p, uap, retval)
struct proc *p;
- register struct connect_args *uap;
- int *retval;
+ register struct connect_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) name;
+ syscallarg(int) namelen;
+ } */ *uap;
+ register_t *retval;
{
struct file *fp;
register struct socket *so;
struct mbuf *nam;
int error, s;
- if (error = getsock(p->p_fd, uap->s, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, s), &fp))
return (error);
so = (struct socket *)fp->f_data;
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
return (EALREADY);
- if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
+ if (error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
+ MT_SONAME))
return (error);
error = soconnect(so, nam);
if (error)
@@ -286,25 +300,27 @@ bad:
return (error);
}
-struct socketpair_args {
- int domain;
- int type;
- int protocol;
- int *rsv;
-};
+int
socketpair(p, uap, retval)
struct proc *p;
- register struct socketpair_args *uap;
- int retval[];
+ register struct socketpair_args /* {
+ syscallarg(int) domain;
+ syscallarg(int) type;
+ syscallarg(int) protocol;
+ syscallarg(int *) rsv;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
struct file *fp1, *fp2;
struct socket *so1, *so2;
int fd, error, sv[2];
- if (error = socreate(uap->domain, &so1, uap->type, uap->protocol))
+ if (error = socreate(SCARG(uap, domain), &so1, SCARG(uap, type),
+ SCARG(uap, protocol)))
return (error);
- if (error = socreate(uap->domain, &so2, uap->type, uap->protocol))
+ if (error = socreate(SCARG(uap, domain), &so2, SCARG(uap, type),
+ SCARG(uap, protocol)))
goto free1;
if (error = falloc(p, &fp1, &fd))
goto free2;
@@ -322,14 +338,15 @@ socketpair(p, uap, retval)
sv[1] = fd;
if (error = soconnect2(so1, so2))
goto free4;
- if (uap->type == SOCK_DGRAM) {
+ if (SCARG(uap, type) == SOCK_DGRAM) {
/*
* Datagram socket connection is asymmetric.
*/
if (error = soconnect2(so2, so1))
goto free4;
}
- error = copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));
+ error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, rsv),
+ 2 * sizeof (int));
retval[0] = sv[0]; /* XXX ??? */
retval[1] = sv[1]; /* XXX ??? */
return (error);
@@ -346,46 +363,46 @@ free1:
return (error);
}
-struct sendto_args {
- int s;
- caddr_t buf;
- size_t len;
- int flags;
- caddr_t to;
- int tolen;
-};
+int
sendto(p, uap, retval)
struct proc *p;
- register struct sendto_args *uap;
- int *retval;
+ register struct sendto_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(caddr_t) to;
+ syscallarg(int) tolen;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov;
- msg.msg_name = uap->to;
- msg.msg_namelen = uap->tolen;
+ msg.msg_name = SCARG(uap, to);
+ msg.msg_namelen = SCARG(uap, tolen);
msg.msg_iov = &aiov;
msg.msg_iovlen = 1;
msg.msg_control = 0;
#ifdef COMPAT_OLDSOCK
msg.msg_flags = 0;
#endif
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->len;
- return (sendit(p, uap->s, &msg, uap->flags, retval));
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, len);
+ return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
}
#ifdef COMPAT_OLDSOCK
-struct osend_args {
- int s;
- caddr_t buf;
- int len;
- int flags;
-};
-osend(p, uap, retval)
+int
+compat_43_send(p, uap, retval)
struct proc *p;
- register struct osend_args *uap;
- int *retval;
+ register struct compat_43_send_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(int) len;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov;
@@ -394,29 +411,30 @@ osend(p, uap, retval)
msg.msg_namelen = 0;
msg.msg_iov = &aiov;
msg.msg_iovlen = 1;
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->len;
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, len);
msg.msg_control = 0;
msg.msg_flags = 0;
- return (sendit(p, uap->s, &msg, uap->flags, retval));
+ return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
}
#define MSG_COMPAT 0x8000
-struct osendmsg_args {
- int s;
- caddr_t msg;
- int flags;
-};
-osendmsg(p, uap, retval)
+int
+compat_43_sendmsg(p, uap, retval)
struct proc *p;
- register struct osendmsg_args *uap;
- int *retval;
+ register struct compat_43_sendmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) msg;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov[UIO_SMALLIOV], *iov;
int error;
- if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (struct omsghdr)))
+ if (error = copyin(SCARG(uap, msg), (caddr_t)&msg,
+ sizeof (struct omsghdr)))
return (error);
if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
@@ -431,7 +449,7 @@ osendmsg(p, uap, retval)
goto done;
msg.msg_flags = MSG_COMPAT;
msg.msg_iov = iov;
- error = sendit(p, uap->s, &msg, uap->flags, retval);
+ error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
done:
if (iov != aiov)
FREE(iov, M_IOV);
@@ -439,21 +457,21 @@ done:
}
#endif
-struct sendmsg_args {
- int s;
- caddr_t msg;
- int flags;
-};
+int
sendmsg(p, uap, retval)
struct proc *p;
- register struct sendmsg_args *uap;
- int *retval;
+ register struct sendmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) msg;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov[UIO_SMALLIOV], *iov;
int error;
- if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg)))
+ if (error = copyin(SCARG(uap, msg), (caddr_t)&msg, sizeof (msg)))
return (error);
if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
@@ -471,18 +489,20 @@ sendmsg(p, uap, retval)
#ifdef COMPAT_OLDSOCK
msg.msg_flags = 0;
#endif
- error = sendit(p, uap->s, &msg, uap->flags, retval);
+ error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
done:
if (iov != aiov)
FREE(iov, M_IOV);
return (error);
}
+int
sendit(p, s, mp, flags, retsize)
register struct proc *p;
int s;
register struct msghdr *mp;
- int flags, *retsize;
+ int flags;
+ register_t *retsize;
{
struct file *fp;
struct uio auio;
@@ -505,10 +525,9 @@ sendit(p, s, mp, flags, retsize)
auio.uio_resid = 0;
iov = mp->msg_iov;
for (i = 0; i < mp->msg_iovlen; i++, iov++) {
- if (iov->iov_len < 0)
- return (EINVAL);
- if ((auio.uio_resid += iov->iov_len) < 0)
+ if (auio.uio_resid + iov->iov_len < auio.uio_resid)
return (EINVAL);
+ auio.uio_resid += iov->iov_len;
}
if (mp->msg_name) {
if (error = sockargs(&to, mp->msg_name, mp->msg_namelen,
@@ -579,63 +598,71 @@ bad:
return (error);
}
-struct recvfrom_args {
- int s;
- caddr_t buf;
- size_t len;
- int flags;
- caddr_t from;
- int *fromlenaddr;
-};
-
#ifdef COMPAT_OLDSOCK
-orecvfrom(p, uap, retval)
+int
+compat_43_recvfrom(p, uap, retval)
struct proc *p;
- struct recvfrom_args *uap;
- int *retval;
+ struct recvfrom_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(caddr_t) from;
+ syscallarg(int *) fromlenaddr;
+ } */ *uap;
+ register_t *retval;
{
- uap->flags |= MSG_COMPAT;
+ SCARG(uap, flags) |= MSG_COMPAT;
return (recvfrom(p, uap, retval));
}
#endif
+int
recvfrom(p, uap, retval)
struct proc *p;
- register struct recvfrom_args *uap;
- int *retval;
+ register struct recvfrom_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(caddr_t) from;
+ syscallarg(int *) fromlenaddr;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov;
int error;
- if (uap->fromlenaddr) {
- if (error = copyin((caddr_t)uap->fromlenaddr,
+ if (SCARG(uap, fromlenaddr)) {
+ if (error = copyin((caddr_t)SCARG(uap, fromlenaddr),
(caddr_t)&msg.msg_namelen, sizeof (msg.msg_namelen)))
return (error);
} else
msg.msg_namelen = 0;
- msg.msg_name = uap->from;
+ msg.msg_name = SCARG(uap, from);
msg.msg_iov = &aiov;
msg.msg_iovlen = 1;
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->len;
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, len);
msg.msg_control = 0;
- msg.msg_flags = uap->flags;
- return (recvit(p, uap->s, &msg, (caddr_t)uap->fromlenaddr, retval));
+ msg.msg_flags = SCARG(uap, flags);
+ return (recvit(p, SCARG(uap, s), &msg,
+ (caddr_t)SCARG(uap, fromlenaddr), retval));
}
#ifdef COMPAT_OLDSOCK
-struct orecv_args {
- int s;
- caddr_t buf;
- int len;
- int flags;
-};
-orecv(p, uap, retval)
+int
+compat_43_recv(p, uap, retval)
struct proc *p;
- register struct orecv_args *uap;
- int *retval;
+ register struct compat_43_recv_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(int) len;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov;
@@ -644,11 +671,11 @@ orecv(p, uap, retval)
msg.msg_namelen = 0;
msg.msg_iov = &aiov;
msg.msg_iovlen = 1;
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->len;
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, len);
msg.msg_control = 0;
- msg.msg_flags = uap->flags;
- return (recvit(p, uap->s, &msg, (caddr_t)0, retval));
+ msg.msg_flags = SCARG(uap, flags);
+ return (recvit(p, SCARG(uap, s), &msg, (caddr_t)0, retval));
}
/*
@@ -656,21 +683,21 @@ orecv(p, uap, retval)
* overlays the new one, missing only the flags, and with the (old) access
* rights where the control fields are now.
*/
-struct orecvmsg_args {
- int s;
- struct omsghdr *msg;
- int flags;
-};
-orecvmsg(p, uap, retval)
+int
+compat_43_recvmsg(p, uap, retval)
struct proc *p;
- register struct orecvmsg_args *uap;
- int *retval;
+ register struct compat_43_recvmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(struct omsghdr *) msg;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov[UIO_SMALLIOV], *iov;
int error;
- if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg,
+ if (error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg,
sizeof (struct omsghdr)))
return (error);
if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
@@ -681,16 +708,17 @@ orecvmsg(p, uap, retval)
M_WAITOK);
} else
iov = aiov;
- msg.msg_flags = uap->flags | MSG_COMPAT;
+ msg.msg_flags = SCARG(uap, flags) | MSG_COMPAT;
if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
(unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
goto done;
msg.msg_iov = iov;
- error = recvit(p, uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);
+ error = recvit(p, SCARG(uap, s), &msg,
+ (caddr_t)&SCARG(uap, msg)->msg_namelen, retval);
if (msg.msg_controllen && error == 0)
error = copyout((caddr_t)&msg.msg_controllen,
- (caddr_t)&uap->msg->msg_accrightslen, sizeof (int));
+ (caddr_t)&SCARG(uap, msg)->msg_accrightslen, sizeof (int));
done:
if (iov != aiov)
FREE(iov, M_IOV);
@@ -698,21 +726,22 @@ done:
}
#endif
-struct recvmsg_args {
- int s;
- struct msghdr *msg;
- int flags;
-};
+int
recvmsg(p, uap, retval)
struct proc *p;
- register struct recvmsg_args *uap;
- int *retval;
+ register struct recvmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(struct msghdr *) msg;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
struct msghdr msg;
struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
register int error;
- if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg)))
+ if (error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg,
+ sizeof (msg)))
return (error);
if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
@@ -723,18 +752,19 @@ recvmsg(p, uap, retval)
} else
iov = aiov;
#ifdef COMPAT_OLDSOCK
- msg.msg_flags = uap->flags &~ MSG_COMPAT;
+ msg.msg_flags = SCARG(uap, flags) &~ MSG_COMPAT;
#else
- msg.msg_flags = uap->flags;
+ msg.msg_flags = SCARG(uap, flags);
#endif
uiov = msg.msg_iov;
msg.msg_iov = iov;
if (error = copyin((caddr_t)uiov, (caddr_t)iov,
(unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
goto done;
- if ((error = recvit(p, uap->s, &msg, (caddr_t)0, retval)) == 0) {
+ if ((error = recvit(p, SCARG(uap, s), &msg, (caddr_t)0, retval)) == 0) {
msg.msg_iov = uiov;
- error = copyout((caddr_t)&msg, (caddr_t)uap->msg, sizeof(msg));
+ error = copyout((caddr_t)&msg, (caddr_t)SCARG(uap, msg),
+ sizeof(msg));
}
done:
if (iov != aiov)
@@ -742,12 +772,13 @@ done:
return (error);
}
+int
recvit(p, s, mp, namelenp, retsize)
register struct proc *p;
int s;
register struct msghdr *mp;
caddr_t namelenp;
- int *retsize;
+ register_t *retsize;
{
struct file *fp;
struct uio auio;
@@ -770,10 +801,9 @@ recvit(p, s, mp, namelenp, retsize)
auio.uio_resid = 0;
iov = mp->msg_iov;
for (i = 0; i < mp->msg_iovlen; i++, iov++) {
- if (iov->iov_len < 0)
- return (EINVAL);
- if ((auio.uio_resid += iov->iov_len) < 0)
+ if (auio.uio_resid + iov->iov_len < auio.uio_resid)
return (EINVAL);
+ auio.uio_resid += iov->iov_len;
}
#ifdef KTRACE
if (KTRPOINT(p, KTR_GENIO)) {
@@ -872,107 +902,107 @@ out:
return (error);
}
-struct shutdown_args {
- int s;
- int how;
-};
/* ARGSUSED */
+int
shutdown(p, uap, retval)
struct proc *p;
- register struct shutdown_args *uap;
- int *retval;
+ register struct shutdown_args /* {
+ syscallarg(int) s;
+ syscallarg(int) how;
+ } */ *uap;
+ register_t *retval;
{
struct file *fp;
int error;
- if (error = getsock(p->p_fd, uap->s, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, s), &fp))
return (error);
- return (soshutdown((struct socket *)fp->f_data, uap->how));
+ return (soshutdown((struct socket *)fp->f_data, SCARG(uap, how)));
}
-struct setsockopt_args {
- int s;
- int level;
- int name;
- caddr_t val;
- int valsize;
-};
/* ARGSUSED */
+int
setsockopt(p, uap, retval)
struct proc *p;
- register struct setsockopt_args *uap;
- int *retval;
+ register struct setsockopt_args /* {
+ syscallarg(int) s;
+ syscallarg(int) level;
+ syscallarg(int) name;
+ syscallarg(caddr_t) val;
+ syscallarg(int) valsize;
+ } */ *uap;
+ register_t *retval;
{
struct file *fp;
struct mbuf *m = NULL;
int error;
- if (error = getsock(p->p_fd, uap->s, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, s), &fp))
return (error);
- if (uap->valsize > MLEN)
+ if (SCARG(uap, valsize) > MLEN)
return (EINVAL);
- if (uap->val) {
+ if (SCARG(uap, val)) {
m = m_get(M_WAIT, MT_SOOPTS);
if (m == NULL)
return (ENOBUFS);
- if (error = copyin(uap->val, mtod(m, caddr_t),
- (u_int)uap->valsize)) {
+ if (error = copyin(SCARG(uap, val), mtod(m, caddr_t),
+ (u_int)SCARG(uap, valsize))) {
(void) m_free(m);
return (error);
}
- m->m_len = uap->valsize;
+ m->m_len = SCARG(uap, valsize);
}
- return (sosetopt((struct socket *)fp->f_data, uap->level,
- uap->name, m));
+ return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
+ SCARG(uap, name), m));
}
-struct getsockopt_args {
- int s;
- int level;
- int name;
- caddr_t val;
- int *avalsize;
-};
/* ARGSUSED */
+int
getsockopt(p, uap, retval)
struct proc *p;
- register struct getsockopt_args *uap;
- int *retval;
+ register struct getsockopt_args /* {
+ syscallarg(int) s;
+ syscallarg(int) level;
+ syscallarg(int) name;
+ syscallarg(caddr_t) val;
+ syscallarg(int *) avalsize;
+ } */ *uap;
+ register_t *retval;
{
struct file *fp;
struct mbuf *m = NULL;
int valsize, error;
- if (error = getsock(p->p_fd, uap->s, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, s), &fp))
return (error);
- if (uap->val) {
- if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
- sizeof (valsize)))
+ if (SCARG(uap, val)) {
+ if (error = copyin((caddr_t)SCARG(uap, avalsize),
+ (caddr_t)&valsize, sizeof (valsize)))
return (error);
} else
valsize = 0;
- if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
- uap->name, &m)) == 0 && uap->val && valsize && m != NULL) {
+ if ((error = sogetopt((struct socket *)fp->f_data, SCARG(uap, level),
+ SCARG(uap, name), &m)) == 0 && SCARG(uap, val) && valsize &&
+ m != NULL) {
if (valsize > m->m_len)
valsize = m->m_len;
- error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
+ error = copyout(mtod(m, caddr_t), SCARG(uap, val),
+ (u_int)valsize);
if (error == 0)
error = copyout((caddr_t)&valsize,
- (caddr_t)uap->avalsize, sizeof (valsize));
+ (caddr_t)SCARG(uap, avalsize), sizeof (valsize));
}
if (m != NULL)
(void) m_free(m);
return (error);
}
-struct pipe_args {
- int dummy;
-};
/* ARGSUSED */
+int
pipe(p, uap, retval)
struct proc *p;
- struct pipe_args *uap;
- int retval[];
+ void *uap;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
struct file *rf, *wf;
@@ -1016,33 +1046,33 @@ free1:
/*
* Get socket name.
*/
-struct getsockname_args {
- int fdes;
- caddr_t asa;
- int *alen;
-#ifdef COMPAT_OLDSOCK
- int compat_43; /* pseudo */
-#endif
-};
#ifdef COMPAT_OLDSOCK
+int
getsockname(p, uap, retval)
struct proc *p;
- struct getsockname_args *uap;
- int *retval;
+ struct getsockname_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(int *) alen;
+ } */ *uap;
+ register_t *retval;
{
- uap->compat_43 = 0;
- return (getsockname1(p, uap, retval));
+ return (getsockname1(p, uap, retval, 0));
}
-ogetsockname(p, uap, retval)
+int
+compat_43_getsockname(p, uap, retval)
struct proc *p;
- struct getsockname_args *uap;
- int *retval;
+ struct getsockname_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(int *) alen;
+ } */ *uap;
+ register_t *retval;
{
- uap->compat_43 = 1;
- return (getsockname1(p, uap, retval));
+ return (getsockname1(p, uap, retval, 1));
}
#else /* COMPAT_OLDSOCK */
@@ -1050,19 +1080,26 @@ ogetsockname(p, uap, retval)
#endif
/* ARGSUSED */
-getsockname1(p, uap, retval)
+int
+getsockname1(p, uap, retval, compat_43)
struct proc *p;
- register struct getsockname_args *uap;
- int *retval;
+ register struct getsockname_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(int *) alen;
+ } */ *uap;
+ register_t *retval;
+ int compat_43;
{
struct file *fp;
register struct socket *so;
struct mbuf *m;
int len, error;
- if (error = getsock(p->p_fd, uap->fdes, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, fdes), &fp))
return (error);
- if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
+ if (error = copyin((caddr_t)SCARG(uap, alen), (caddr_t)&len,
+ sizeof (len)))
return (error);
so = (struct socket *)fp->f_data;
m = m_getclr(M_WAIT, MT_SONAME);
@@ -1073,13 +1110,13 @@ getsockname1(p, uap, retval)
if (len > m->m_len)
len = m->m_len;
#ifdef COMPAT_OLDSOCK
- if (uap->compat_43)
+ if (compat_43)
mtod(m, struct osockaddr *)->sa_family =
mtod(m, struct sockaddr *)->sa_family;
#endif
- error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
+ error = copyout(mtod(m, caddr_t), (caddr_t)SCARG(uap, asa), (u_int)len);
if (error == 0)
- error = copyout((caddr_t)&len, (caddr_t)uap->alen,
+ error = copyout((caddr_t)&len, (caddr_t)SCARG(uap, alen),
sizeof (len));
bad:
m_freem(m);
@@ -1089,34 +1126,33 @@ bad:
/*
* Get name of peer for connected socket.
*/
-struct getpeername_args {
- int fdes;
- caddr_t asa;
- int *alen;
-#ifdef COMPAT_OLDSOCK
- int compat_43; /* pseudo */
-#endif
-};
-
#ifdef COMPAT_OLDSOCK
+int
getpeername(p, uap, retval)
struct proc *p;
- struct getpeername_args *uap;
- int *retval;
+ struct getpeername_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(int *) alen;
+ } */ *uap;
+ register_t *retval;
{
- uap->compat_43 = 0;
- return (getpeername1(p, uap, retval));
+ return (getpeername1(p, uap, retval, 0));
}
-ogetpeername(p, uap, retval)
+int
+compat_43_getpeername(p, uap, retval)
struct proc *p;
- struct getpeername_args *uap;
- int *retval;
+ struct getpeername_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(int *) alen;
+ } */ *uap;
+ register_t *retval;
{
- uap->compat_43 = 1;
- return (getpeername1(p, uap, retval));
+ return (getpeername1(p, uap, retval, 1));
}
#else /* COMPAT_OLDSOCK */
@@ -1124,22 +1160,29 @@ ogetpeername(p, uap, retval)
#endif
/* ARGSUSED */
-getpeername1(p, uap, retval)
+int
+getpeername1(p, uap, retval, compat_43)
struct proc *p;
- register struct getpeername_args *uap;
- int *retval;
+ register struct getpeername_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(int *) alen;
+ } */ *uap;
+ register_t *retval;
+ int compat_43;
{
struct file *fp;
register struct socket *so;
struct mbuf *m;
int len, error;
- if (error = getsock(p->p_fd, uap->fdes, &fp))
+ if (error = getsock(p->p_fd, SCARG(uap, fdes), &fp))
return (error);
so = (struct socket *)fp->f_data;
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
return (ENOTCONN);
- if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
+ if (error =
+ copyin((caddr_t)SCARG(uap, alen), (caddr_t)&len, sizeof (len)))
return (error);
m = m_getclr(M_WAIT, MT_SONAME);
if (m == NULL)
@@ -1149,18 +1192,20 @@ getpeername1(p, uap, retval)
if (len > m->m_len)
len = m->m_len;
#ifdef COMPAT_OLDSOCK
- if (uap->compat_43)
+ if (compat_43)
mtod(m, struct osockaddr *)->sa_family =
mtod(m, struct sockaddr *)->sa_family;
#endif
- if (error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len))
+ if (error =
+ copyout(mtod(m, caddr_t), (caddr_t)SCARG(uap, asa), (u_int)len))
goto bad;
- error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
+ error = copyout((caddr_t)&len, (caddr_t)SCARG(uap, alen), sizeof (len));
bad:
m_freem(m);
return (error);
}
+int
sockargs(mp, buf, buflen, type)
struct mbuf **mp;
caddr_t buf;
@@ -1183,23 +1228,24 @@ sockargs(mp, buf, buflen, type)
return (ENOBUFS);
m->m_len = buflen;
error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);
- if (error)
+ if (error) {
(void) m_free(m);
- else {
- *mp = m;
- if (type == MT_SONAME) {
- sa = mtod(m, struct sockaddr *);
+ return (error);
+ }
+ *mp = m;
+ if (type == MT_SONAME) {
+ sa = mtod(m, struct sockaddr *);
#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
- if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
- sa->sa_family = sa->sa_len;
+ if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
+ sa->sa_family = sa->sa_len;
#endif
- sa->sa_len = buflen;
- }
+ sa->sa_len = buflen;
}
- return (error);
+ return (0);
}
+int
getsock(fdp, fdes, fpp)
struct filedesc *fdp;
int fdes;
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 94bf8f7..c6bcbfd 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94
+ * @(#)uipc_usrreq.c 8.9 (Berkeley) 5/14/95
*/
#include <sys/param.h>
@@ -61,6 +61,7 @@ struct sockaddr sun_noname = { sizeof(sun_noname), AF_UNIX };
ino_t unp_ino; /* prototype for fake inode numbers */
/*ARGSUSED*/
+int
uipc_usrreq(so, req, m, nam, control)
struct socket *so;
int req;
@@ -313,6 +314,7 @@ u_long unpdg_recvspace = 4*1024;
int unp_rights; /* file descriptors in flight */
+int
unp_attach(so)
struct socket *so;
{
@@ -346,6 +348,7 @@ unp_attach(so)
return (0);
}
+void
unp_detach(unp)
register struct unpcb *unp;
{
@@ -376,6 +379,7 @@ unp_detach(unp)
}
}
+int
unp_bind(unp, nam, p)
struct unpcb *unp;
struct mbuf *nam;
@@ -388,7 +392,7 @@ unp_bind(unp, nam, p)
struct nameidata nd;
NDINIT(&nd, CREATE, FOLLOW | LOCKPARENT, UIO_SYSSPACE,
- soun->sun_path, p);
+ soun->sun_path, p);
if (unp->unp_vnode != NULL)
return (EINVAL);
if (nam->m_len == MLEN) {
@@ -412,17 +416,18 @@ unp_bind(unp, nam, p)
VATTR_NULL(&vattr);
vattr.va_type = VSOCK;
vattr.va_mode = ACCESSPERMS;
- LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
if (error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr))
return (error);
vp = nd.ni_vp;
vp->v_socket = unp->unp_socket;
unp->unp_vnode = vp;
unp->unp_addr = m_copy(nam, 0, (int)M_COPYALL);
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (0);
}
+int
unp_connect(so, nam, p)
struct socket *so;
struct mbuf *nam;
@@ -478,6 +483,7 @@ bad:
return (error);
}
+int
unp_connect2(so, so2)
register struct socket *so;
register struct socket *so2;
@@ -509,6 +515,7 @@ unp_connect2(so, so2)
return (0);
}
+void
unp_disconnect(unp)
struct unpcb *unp;
{
@@ -546,6 +553,7 @@ unp_disconnect(unp)
}
#ifdef notdef
+void
unp_abort(unp)
struct unpcb *unp;
{
@@ -554,6 +562,7 @@ unp_abort(unp)
}
#endif
+void
unp_shutdown(unp)
struct unpcb *unp;
{
@@ -564,6 +573,7 @@ unp_shutdown(unp)
socantrcvmore(so);
}
+void
unp_drop(unp, errno)
struct unpcb *unp;
int errno;
@@ -587,6 +597,7 @@ unp_drain()
}
#endif
+int
unp_externalize(rights)
struct mbuf *rights;
{
@@ -618,6 +629,7 @@ unp_externalize(rights)
return (0);
}
+int
unp_internalize(control, p)
struct mbuf *control;
struct proc *p;
@@ -652,9 +664,9 @@ unp_internalize(control, p)
}
int unp_defer, unp_gcing;
-int unp_mark();
extern struct domain unixdomain;
+void
unp_gc()
{
register struct file *fp, *nextfp;
@@ -666,10 +678,10 @@ unp_gc()
return;
unp_gcing = 1;
unp_defer = 0;
- for (fp = filehead; fp; fp = fp->f_filef)
+ for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next)
fp->f_flag &= ~(FMARK|FDEFER);
do {
- for (fp = filehead; fp; fp = fp->f_filef) {
+ for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) {
if (fp->f_count == 0)
continue;
if (fp->f_flag & FDEFER) {
@@ -747,8 +759,9 @@ unp_gc()
* 91/09/19, bsy@cs.cmu.edu
*/
extra_ref = malloc(nfiles * sizeof(struct file *), M_FILE, M_WAITOK);
- for (nunref = 0, fp = filehead, fpp = extra_ref; fp; fp = nextfp) {
- nextfp = fp->f_filef;
+ for (nunref = 0, fp = filehead.lh_first, fpp = extra_ref; fp != 0;
+ fp = nextfp) {
+ nextfp = fp->f_list.le_next;
if (fp->f_count == 0)
continue;
if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
@@ -760,23 +773,24 @@ unp_gc()
for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
sorflush((struct socket *)(*fpp)->f_data);
for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
- closef(*fpp);
+ closef(*fpp, (struct proc *)NULL);
free((caddr_t)extra_ref, M_FILE);
unp_gcing = 0;
}
+void
unp_dispose(m)
struct mbuf *m;
{
- int unp_discard();
if (m)
unp_scan(m, unp_discard);
}
+void
unp_scan(m0, op)
register struct mbuf *m0;
- int (*op)();
+ void (*op) __P((struct file *));
{
register struct mbuf *m;
register struct file **rp;
@@ -803,6 +817,7 @@ unp_scan(m0, op)
}
}
+void
unp_mark(fp)
struct file *fp;
{
@@ -813,6 +828,7 @@ unp_mark(fp)
fp->f_flag |= (FMARK|FDEFER);
}
+void
unp_discard(fp)
struct file *fp;
{
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 4ccfd72..c20966b 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -1,7 +1,10 @@
/*
- * Copyright (c) 1989, 1993
+ * Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
+ * This code is derived from software contributed to Berkeley by
+ * Poul-Henning Kamp of the FreeBSD Project.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,7 +33,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_cache.c 8.1 (Berkeley) 6/10/93
+ * from: vfs_cache.c,v 1.11 1995/03/12 02:01:20 phk Exp $
+ *
+ * @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95
*/
#include <sys/param.h>
@@ -51,6 +56,9 @@
* obtained from (vp, name) where vp refers to the directory
* containing name.
*
+ * If it is a "negative" entry, (i.e. for a name that is known NOT to
+ * exist) the vnode pointer will be NULL.
+ *
* For simplicity (and economy of storage), names longer than
* a maximum length of NCHNAMLEN are not cached; they occur
* infrequently in any case, and are almost never of interest.
@@ -63,266 +71,250 @@
/*
* Structures associated with name cacheing.
*/
-struct namecache **nchashtbl;
+#define NCHHASH(dvp, cnp) \
+ (&nchashtbl[((dvp)->v_id + (cnp)->cn_hash) & nchash])
+LIST_HEAD(nchashhead, namecache) *nchashtbl; /* Hash Table */
u_long nchash; /* size of hash table - 1 */
long numcache; /* number of cache entries allocated */
-struct namecache *nchhead, **nchtail; /* LRU chain pointers */
+TAILQ_HEAD(, namecache) nclruhead; /* LRU chain */
struct nchstats nchstats; /* cache effectiveness statistics */
int doingcache = 1; /* 1 => enable the cache */
/*
- * Look for a the name in the cache. We don't do this
- * if the segment name is long, simply so the cache can avoid
- * holding long names (which would either waste space, or
+ * Delete an entry from its hash list and move it to the front
+ * of the LRU list for immediate reuse.
+ */
+#define PURGE(ncp) { \
+ LIST_REMOVE(ncp, nc_hash); \
+ ncp->nc_hash.le_prev = 0; \
+ TAILQ_REMOVE(&nclruhead, ncp, nc_lru); \
+ TAILQ_INSERT_HEAD(&nclruhead, ncp, nc_lru); \
+}
+
+/*
+ * Move an entry that has been used to the tail of the LRU list
+ * so that it will be preserved for future use.
+ */
+#define TOUCH(ncp) { \
+ if (ncp->nc_lru.tqe_next != 0) { \
+ TAILQ_REMOVE(&nclruhead, ncp, nc_lru); \
+ TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); \
+ } \
+}
+
+/*
+ * Lookup an entry in the cache
+ *
+ * We don't do this if the segment name is long, simply so the cache
+ * can avoid holding long names (which would either waste space, or
* add greatly to the complexity).
*
- * Lookup is called with ni_dvp pointing to the directory to search,
- * ni_ptr pointing to the name of the entry being sought, ni_namelen
- * tells the length of the name, and ni_hash contains a hash of
- * the name. If the lookup succeeds, the vnode is returned in ni_vp
- * and a status of -1 is returned. If the lookup determines that
- * the name does not exist (negative cacheing), a status of ENOENT
- * is returned. If the lookup fails, a status of zero is returned.
+ * Lookup is called with dvp pointing to the directory to search,
+ * cnp pointing to the name of the entry being sought. If the lookup
+ * succeeds, the vnode is returned in *vpp, and a status of -1 is
+ * returned. If the lookup determines that the name does not exist
+ * (negative cacheing), a status of ENOENT is returned. If the lookup
+ * fails, a status of zero is returned.
*/
+
int
cache_lookup(dvp, vpp, cnp)
struct vnode *dvp;
struct vnode **vpp;
struct componentname *cnp;
{
- register struct namecache *ncp, *ncq, **ncpp;
+ register struct namecache *ncp, *nnp;
+ register struct nchashhead *ncpp;
- if (!doingcache)
+ if (!doingcache) {
+ cnp->cn_flags &= ~MAKEENTRY;
return (0);
+ }
if (cnp->cn_namelen > NCHNAMLEN) {
nchstats.ncs_long++;
cnp->cn_flags &= ~MAKEENTRY;
return (0);
}
- ncpp = &nchashtbl[cnp->cn_hash & nchash];
- for (ncp = *ncpp; ncp; ncp = ncp->nc_forw) {
+
+ ncpp = NCHHASH(dvp, cnp);
+ for (ncp = ncpp->lh_first; ncp != 0; ncp = nnp) {
+ nnp = ncp->nc_hash.le_next;
+ /* If one of the vp's went stale, don't bother anymore. */
+ if ((ncp->nc_dvpid != ncp->nc_dvp->v_id) ||
+ (ncp->nc_vp && ncp->nc_vpid != ncp->nc_vp->v_id)) {
+ nchstats.ncs_falsehits++;
+ PURGE(ncp);
+ continue;
+ }
+ /* Now that we know the vp's to be valid, is it ours ? */
if (ncp->nc_dvp == dvp &&
- ncp->nc_dvpid == dvp->v_id &&
ncp->nc_nlen == cnp->cn_namelen &&
!bcmp(ncp->nc_name, cnp->cn_nameptr, (u_int)ncp->nc_nlen))
break;
}
- if (ncp == NULL) {
+
+ /* We failed to find an entry */
+ if (ncp == 0) {
nchstats.ncs_miss++;
return (0);
}
- if (!(cnp->cn_flags & MAKEENTRY)) {
+
+ /* We don't want to have an entry, so dump it */
+ if ((cnp->cn_flags & MAKEENTRY) == 0) {
nchstats.ncs_badhits++;
- } else if (ncp->nc_vp == NULL) {
- if (cnp->cn_nameiop != CREATE) {
- nchstats.ncs_neghits++;
- /*
- * Move this slot to end of LRU chain,
- * if not already there.
- */
- if (ncp->nc_nxt) {
- /* remove from LRU chain */
- *ncp->nc_prev = ncp->nc_nxt;
- ncp->nc_nxt->nc_prev = ncp->nc_prev;
- /* and replace at end of it */
- ncp->nc_nxt = NULL;
- ncp->nc_prev = nchtail;
- *nchtail = ncp;
- nchtail = &ncp->nc_nxt;
- }
- return (ENOENT);
- }
- } else if (ncp->nc_vpid != ncp->nc_vp->v_id) {
- nchstats.ncs_falsehits++;
- } else {
+ PURGE(ncp);
+ return (0);
+ }
+
+ /* We found a "positive" match, return the vnode */
+ if (ncp->nc_vp) {
nchstats.ncs_goodhits++;
- /*
- * move this slot to end of LRU chain, if not already there
- */
- if (ncp->nc_nxt) {
- /* remove from LRU chain */
- *ncp->nc_prev = ncp->nc_nxt;
- ncp->nc_nxt->nc_prev = ncp->nc_prev;
- /* and replace at end of it */
- ncp->nc_nxt = NULL;
- ncp->nc_prev = nchtail;
- *nchtail = ncp;
- nchtail = &ncp->nc_nxt;
- }
+ TOUCH(ncp);
*vpp = ncp->nc_vp;
return (-1);
}
+ /* We found a negative match, and want to create it, so purge */
+ if (cnp->cn_nameiop == CREATE) {
+ nchstats.ncs_badhits++;
+ PURGE(ncp);
+ return (0);
+ }
+
/*
- * Last component and we are renaming or deleting,
- * the cache entry is invalid, or otherwise don't
- * want cache entry to exist.
+ * We found a "negative" match, ENOENT notifies client of this match.
+ * The nc_vpid field records whether this is a whiteout.
*/
- /* remove from LRU chain */
- if (ncq = ncp->nc_nxt)
- ncq->nc_prev = ncp->nc_prev;
- else
- nchtail = ncp->nc_prev;
- *ncp->nc_prev = ncq;
- /* remove from hash chain */
- if (ncq = ncp->nc_forw)
- ncq->nc_back = ncp->nc_back;
- *ncp->nc_back = ncq;
- /* and make a dummy hash chain */
- ncp->nc_forw = NULL;
- ncp->nc_back = NULL;
- /* insert at head of LRU list (first to grab) */
- if (ncq = nchhead)
- ncq->nc_prev = &ncp->nc_nxt;
- else
- nchtail = &ncp->nc_nxt;
- nchhead = ncp;
- ncp->nc_nxt = ncq;
- ncp->nc_prev = &nchhead;
- return (0);
+ nchstats.ncs_neghits++;
+ TOUCH(ncp);
+ cnp->cn_flags |= ncp->nc_vpid;
+ return (ENOENT);
}
/*
- * Add an entry to the cache
+ * Add an entry to the cache.
*/
+void
cache_enter(dvp, vp, cnp)
struct vnode *dvp;
struct vnode *vp;
struct componentname *cnp;
{
- register struct namecache *ncp, *ncq, **ncpp;
+ register struct namecache *ncp;
+ register struct nchashhead *ncpp;
+
+ if (!doingcache)
+ return;
#ifdef DIAGNOSTIC
if (cnp->cn_namelen > NCHNAMLEN)
panic("cache_enter: name too long");
#endif
- if (!doingcache)
- return;
+
/*
- * Free the cache slot at head of lru chain.
+ * We allocate a new entry if we are less than the maximum
+ * allowed and the one at the front of the LRU list is in use.
+ * Otherwise we use the one at the front of the LRU list.
*/
- if (numcache < desiredvnodes) {
+ if (numcache < desiredvnodes &&
+ ((ncp = nclruhead.tqh_first) == NULL ||
+ ncp->nc_hash.le_prev != 0)) {
+ /* Add one more entry */
ncp = (struct namecache *)
malloc((u_long)sizeof *ncp, M_CACHE, M_WAITOK);
bzero((char *)ncp, sizeof *ncp);
numcache++;
- } else if (ncp = nchhead) {
- /* remove from lru chain */
- if (ncq = ncp->nc_nxt)
- ncq->nc_prev = ncp->nc_prev;
- else
- nchtail = ncp->nc_prev;
- *ncp->nc_prev = ncq;
- /* remove from old hash chain, if on one */
- if (ncp->nc_back) {
- if (ncq = ncp->nc_forw)
- ncq->nc_back = ncp->nc_back;
- *ncp->nc_back = ncq;
- ncp->nc_forw = NULL;
- ncp->nc_back = NULL;
+ } else if (ncp = nclruhead.tqh_first) {
+ /* reuse an old entry */
+ TAILQ_REMOVE(&nclruhead, ncp, nc_lru);
+ if (ncp->nc_hash.le_prev != 0) {
+ LIST_REMOVE(ncp, nc_hash);
+ ncp->nc_hash.le_prev = 0;
}
- } else
+ } else {
+ /* give up */
return;
- /* grab the vnode we just found */
+ }
+
+ /*
+ * Fill in cache info, if vp is NULL this is a "negative" cache entry.
+ * For negative entries, we have to record whether it is a whiteout.
+ * the whiteout flag is stored in the nc_vpid field which is
+ * otherwise unused.
+ */
ncp->nc_vp = vp;
if (vp)
ncp->nc_vpid = vp->v_id;
else
- ncp->nc_vpid = 0;
- /* fill in cache info */
+ ncp->nc_vpid = cnp->cn_flags & ISWHITEOUT;
ncp->nc_dvp = dvp;
ncp->nc_dvpid = dvp->v_id;
ncp->nc_nlen = cnp->cn_namelen;
bcopy(cnp->cn_nameptr, ncp->nc_name, (unsigned)ncp->nc_nlen);
- /* link at end of lru chain */
- ncp->nc_nxt = NULL;
- ncp->nc_prev = nchtail;
- *nchtail = ncp;
- nchtail = &ncp->nc_nxt;
- /* and insert on hash chain */
- ncpp = &nchashtbl[cnp->cn_hash & nchash];
- if (ncq = *ncpp)
- ncq->nc_back = &ncp->nc_forw;
- ncp->nc_forw = ncq;
- ncp->nc_back = ncpp;
- *ncpp = ncp;
+ TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru);
+ ncpp = NCHHASH(dvp, cnp);
+ LIST_INSERT_HEAD(ncpp, ncp, nc_hash);
}
/*
* Name cache initialization, from vfs_init() when we are booting
*/
+void
nchinit()
{
- nchtail = &nchhead;
+ TAILQ_INIT(&nclruhead);
nchashtbl = hashinit(desiredvnodes, M_CACHE, &nchash);
}
/*
- * Cache flush, a particular vnode; called when a vnode is renamed to
- * hide entries that would now be invalid
+ * Invalidate a all entries to particular vnode.
+ *
+ * We actually just increment the v_id, that will do it. The entries will
+ * be purged by lookup as they get found. If the v_id wraps around, we
+ * need to ditch the entire cache, to avoid confusion. No valid vnode will
+ * ever have (v_id == 0).
*/
+void
cache_purge(vp)
struct vnode *vp;
{
- struct namecache *ncp, **ncpp;
+ struct namecache *ncp;
+ struct nchashhead *ncpp;
vp->v_id = ++nextvnodeid;
if (nextvnodeid != 0)
return;
for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) {
- for (ncp = *ncpp; ncp; ncp = ncp->nc_forw) {
- ncp->nc_vpid = 0;
- ncp->nc_dvpid = 0;
- }
+ while (ncp = ncpp->lh_first)
+ PURGE(ncp);
}
vp->v_id = ++nextvnodeid;
}
/*
- * Cache flush, a whole filesystem; called when filesys is umounted to
- * remove entries that would now be invalid
+ * Flush all entries referencing a particular filesystem.
*
- * The line "nxtcp = nchhead" near the end is to avoid potential problems
- * if the cache lru chain is modified while we are dumping the
- * inode. This makes the algorithm O(n^2), but do you think I care?
+ * Since we need to check it anyway, we will flush all the invalid
+ * entriess at the same time.
*/
+void
cache_purgevfs(mp)
struct mount *mp;
{
- register struct namecache *ncp, *nxtcp;
+ struct nchashhead *ncpp;
+ struct namecache *ncp, *nnp;
- for (ncp = nchhead; ncp; ncp = nxtcp) {
- if (ncp->nc_dvp == NULL || ncp->nc_dvp->v_mount != mp) {
- nxtcp = ncp->nc_nxt;
- continue;
- }
- /* free the resources we had */
- ncp->nc_vp = NULL;
- ncp->nc_dvp = NULL;
- /* remove from old hash chain, if on one */
- if (ncp->nc_back) {
- if (nxtcp = ncp->nc_forw)
- nxtcp->nc_back = ncp->nc_back;
- *ncp->nc_back = nxtcp;
- ncp->nc_forw = NULL;
- ncp->nc_back = NULL;
+ /* Scan hash tables for applicable entries */
+ for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) {
+ for (ncp = ncpp->lh_first; ncp != 0; ncp = nnp) {
+ nnp = ncp->nc_hash.le_next;
+ if (ncp->nc_dvpid != ncp->nc_dvp->v_id ||
+ (ncp->nc_vp && ncp->nc_vpid != ncp->nc_vp->v_id) ||
+ ncp->nc_dvp->v_mount == mp) {
+ PURGE(ncp);
+ }
}
- /* delete this entry from LRU chain */
- if (nxtcp = ncp->nc_nxt)
- nxtcp->nc_prev = ncp->nc_prev;
- else
- nchtail = ncp->nc_prev;
- *ncp->nc_prev = nxtcp;
- /* cause rescan of list, it may have altered */
- /* also put the now-free entry at head of LRU */
- if (nxtcp = nchhead)
- nxtcp->nc_prev = &ncp->nc_nxt;
- else
- nchtail = &ncp->nc_nxt;
- nchhead = ncp;
- ncp->nc_nxt = nxtcp;
- ncp->nc_prev = &nchhead;
}
}
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index c34fbc3..e01d24f 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94
+ * @(#)vfs_cluster.c 8.10 (Berkeley) 3/28/95
*/
#include <sys/param.h>
@@ -43,16 +43,6 @@
#include <sys/resourcevar.h>
#include <libkern/libkern.h>
-#ifdef DEBUG
-#include <vm/vm.h>
-#include <sys/sysctl.h>
-int doreallocblks = 1;
-struct ctldebug debug13 = { "doreallocblks", &doreallocblks };
-#else
-/* XXX for cluster_write */
-#define doreallocblks 1
-#endif
-
/*
* Local declarations
*/
@@ -135,7 +125,7 @@ cluster_read(vp, filesize, lblkno, size, cred, bpp)
trace(TR_BREADHIT, pack(vp, size), lblkno);
flags |= B_ASYNC;
ioblkno = lblkno + (vp->v_ralen ? vp->v_ralen : 1);
- alreadyincore = (int)incore(vp, ioblkno);
+ alreadyincore = incore(vp, ioblkno) != NULL;
bp = NULL;
} else {
/* Block wasn't in cache, case 3, 4, 5. */
@@ -202,10 +192,12 @@ cluster_read(vp, filesize, lblkno, size, cred, bpp)
ioblkno, NULL, &blkno, &num_ra)) || blkno == -1)
goto skip_readahead;
/*
- * Adjust readahead as above
+ * Adjust readahead as above.
+ * Don't check alreadyincore, we know it is 0 from
+ * the previous conditional.
*/
if (num_ra) {
- if (!alreadyincore && ioblkno <= vp->v_maxra)
+ if (ioblkno <= vp->v_maxra)
vp->v_ralen = max(vp->v_ralen >> 1, 1);
else if (num_ra > vp->v_ralen &&
lblkno != vp->v_lastr)
@@ -318,17 +310,12 @@ cluster_rbuild(vp, filesize, bp, lbn, blkno, size, run, flags)
inc = btodb(size);
for (bn = blkno + inc, i = 1; i <= run; ++i, bn += inc) {
- if (incore(vp, lbn + i)) {
- if (i == 1) {
- bp->b_saveaddr = b_save->bs_saveaddr;
- bp->b_flags &= ~B_CALL;
- bp->b_iodone = NULL;
- allocbuf(bp, size);
- free(b_save, M_SEGMENT);
- } else
- allocbuf(bp, size * i);
+ /*
+ * A component of the cluster is already in core,
+ * terminate the cluster early.
+ */
+ if (incore(vp, lbn + i))
break;
- }
tbp = getblk(vp, lbn + i, 0, 0, 0);
/*
* getblk may return some memory in the buffer if there were
@@ -341,8 +328,18 @@ cluster_rbuild(vp, filesize, bp, lbn, blkno, size, run, flags)
if (tbp->b_bufsize != 0) {
caddr_t bdata = (char *)tbp->b_data;
- if (tbp->b_bufsize + size > MAXBSIZE)
- panic("cluster_rbuild: too much memory");
+ /*
+ * No room in the buffer to add another page,
+ * terminate the cluster early.
+ */
+ if (tbp->b_bufsize + size > MAXBSIZE) {
+#ifdef DIAGNOSTIC
+ if (tbp->b_bufsize != MAXBSIZE)
+ panic("cluster_rbuild: too much memory");
+#endif
+ brelse(tbp);
+ break;
+ }
if (tbp->b_bufsize > size) {
/*
* XXX if the source and destination regions
@@ -364,6 +361,20 @@ cluster_rbuild(vp, filesize, bp, lbn, blkno, size, run, flags)
++b_save->bs_nchildren;
b_save->bs_children[i - 1] = tbp;
}
+ /*
+ * The cluster may have been terminated early, adjust the cluster
+ * buffer size accordingly. If no cluster could be formed,
+ * deallocate the cluster save info.
+ */
+ if (i <= run) {
+ if (i == 1) {
+ bp->b_saveaddr = b_save->bs_saveaddr;
+ bp->b_flags &= ~B_CALL;
+ bp->b_iodone = NULL;
+ free(b_save, M_SEGMENT);
+ }
+ allocbuf(bp, size * i);
+ }
return(bp);
}
@@ -498,8 +509,7 @@ cluster_write(bp, filesize)
* Otherwise try reallocating to make it sequential.
*/
cursize = vp->v_lastw - vp->v_cstart + 1;
- if (!doreallocblks ||
- (lbn + 1) * bp->b_bcount != filesize ||
+ if ((lbn + 1) * bp->b_bcount != filesize ||
lbn != vp->v_lastw + 1 || vp->v_clen <= cursize) {
cluster_wbuild(vp, NULL, bp->b_bcount,
vp->v_cstart, cursize, lbn);
diff --git a/sys/kern/vfs_conf.c b/sys/kern/vfs_conf.c
index 2fe39eb..9b57797 100644
--- a/sys/kern/vfs_conf.c
+++ b/sys/kern/vfs_conf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1989, 1993
+ * Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,144 +30,132 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_conf.c 8.8 (Berkeley) 3/31/94
+ * @(#)vfs_conf.c 8.11 (Berkeley) 5/10/95
*/
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/vnode.h>
-#ifdef FFS
-#include <ufs/ffs/ffs_extern.h>
-
/*
- * This specifies the filesystem used to mount the root.
- * This specification should be done by /etc/config.
+ * These define the root filesystem, device, and root filesystem type.
*/
-int (*mountroot)() = ffs_mountroot;
-#endif
+struct mount *rootfs;
+struct vnode *rootvnode;
+int (*mountroot)() = NULL;
/*
- * These define the root filesystem and device.
+ * Set up the initial array of known filesystem types.
*/
-struct mount *rootfs;
-struct vnode *rootvnode;
+extern struct vfsops ufs_vfsops;
+extern int ffs_mountroot();
+extern struct vfsops lfs_vfsops;
+extern int lfs_mountroot();
+extern struct vfsops mfs_vfsops;
+extern int mfs_mountroot();
+extern struct vfsops cd9660_vfsops;
+extern int cd9660_mountroot();
+extern struct vfsops msdos_vfsops;
+extern struct vfsops adosfs_vfsops;
+extern struct vfsops nfs_vfsops;
+extern int nfs_mountroot();
+extern struct vfsops afs_vfsops;
+extern struct vfsops procfs_vfsops;
+extern struct vfsops null_vfsops;
+extern struct vfsops union_vfsops;
+extern struct vfsops umap_vfsops;
+extern struct vfsops portal_vfsops;
+extern struct vfsops fdesc_vfsops;
+extern struct vfsops kernfs_vfsops;
/*
* Set up the filesystem operations for vnodes.
- * The types are defined in mount.h.
*/
+static struct vfsconf vfsconflist[] = {
+
+ /* Fast Filesystem */
#ifdef FFS
-extern struct vfsops ufs_vfsops;
-#define UFS_VFSOPS &ufs_vfsops
-#else
-#define UFS_VFSOPS NULL
+ { &ufs_vfsops, "ufs", 1, 0, MNT_LOCAL, ffs_mountroot, NULL },
#endif
+ /* Log-based Filesystem */
#ifdef LFS
-extern struct vfsops lfs_vfsops;
-#define LFS_VFSOPS &lfs_vfsops
-#else
-#define LFS_VFSOPS NULL
+ { &lfs_vfsops, "lfs", 5, 0, MNT_LOCAL, lfs_mountroot, NULL },
#endif
+ /* Memory-based Filesystem */
#ifdef MFS
-extern struct vfsops mfs_vfsops;
-#define MFS_VFSOPS &mfs_vfsops
-#else
-#define MFS_VFSOPS NULL
+ { &mfs_vfsops, "mfs", 3, 0, MNT_LOCAL, mfs_mountroot, NULL },
#endif
-#ifdef NFS
-extern struct vfsops nfs_vfsops;
-#define NFS_VFSOPS &nfs_vfsops
-#else
-#define NFS_VFSOPS NULL
+ /* ISO9660 (aka CDROM) Filesystem */
+#ifdef CD9660
+ { &cd9660_vfsops, "cd9660", 14, 0, MNT_LOCAL, cd9660_mountroot, NULL },
#endif
-#ifdef FDESC
-extern struct vfsops fdesc_vfsops;
-#define FDESC_VFSOPS &fdesc_vfsops
-#else
-#define FDESC_VFSOPS NULL
+ /* MSDOS Filesystem */
+#ifdef MSDOS
+ { &msdos_vfsops, "msdos", 4, 0, MNT_LOCAL, NULL, NULL },
#endif
-#ifdef PORTAL
-extern struct vfsops portal_vfsops;
-#define PORTAL_VFSOPS &portal_vfsops
-#else
-#define PORTAL_VFSOPS NULL
+ /* AmigaDOS Filesystem */
+#ifdef ADOSFS
+ { &adosfs_vfsops, "adosfs", 16, 0, MNT_LOCAL, NULL, NULL },
#endif
-#ifdef NULLFS
-extern struct vfsops null_vfsops;
-#define NULL_VFSOPS &null_vfsops
-#else
-#define NULL_VFSOPS NULL
+ /* Sun-compatible Network Filesystem */
+#ifdef NFS
+ { &nfs_vfsops, "nfs", 2, 0, 0, nfs_mountroot, NULL },
#endif
-#ifdef UMAPFS
-extern struct vfsops umap_vfsops;
-#define UMAP_VFSOPS &umap_vfsops
-#else
-#define UMAP_VFSOPS NULL
+ /* Andrew Filesystem */
+#ifdef AFS
+ { &afs_vfsops, "andrewfs", 13, 0, 0, afs_mountroot, NULL },
#endif
-#ifdef KERNFS
-extern struct vfsops kernfs_vfsops;
-#define KERNFS_VFSOPS &kernfs_vfsops
-#else
-#define KERNFS_VFSOPS NULL
+ /* /proc Filesystem */
+#ifdef PROCFS
+ { &procfs_vfsops, "procfs", 12, 0, 0, NULL, NULL },
#endif
-#ifdef PROCFS
-extern struct vfsops procfs_vfsops;
-#define PROCFS_VFSOPS &procfs_vfsops
-#else
-#define PROCFS_VFSOPS NULL
+ /* Loopback (Minimal) Filesystem Layer */
+#ifdef NULLFS
+ { &null_vfsops, "loopback", 9, 0, 0, NULL, NULL },
#endif
-#ifdef AFS
-extern struct vfsops afs_vfsops;
-#define AFS_VFSOPS &afs_vfsops
-#else
-#define AFS_VFSOPS NULL
+ /* Union (translucent) Filesystem */
+#ifdef UNION
+ { &union_vfsops, "union", 15, 0, 0, NULL, NULL },
#endif
-#ifdef CD9660
-extern struct vfsops cd9660_vfsops;
-#define CD9660_VFSOPS &cd9660_vfsops
-#else
-#define CD9660_VFSOPS NULL
+ /* User/Group Identifer Remapping Filesystem */
+#ifdef UMAPFS
+ { &umap_vfsops, "umap", 10, 0, 0, NULL, NULL },
#endif
-#ifdef UNION
-extern struct vfsops union_vfsops;
-#define UNION_VFSOPS &union_vfsops
-#else
-#define UNION_VFSOPS NULL
+ /* Portal Filesystem */
+#ifdef PORTAL
+ { &portal_vfsops, "portal", 8, 0, 0, NULL, NULL },
+#endif
+
+ /* File Descriptor Filesystem */
+#ifdef FDESC
+ { &fdesc_vfsops, "fdesc", 7, 0, 0, NULL, NULL },
+#endif
+
+ /* Kernel Information Filesystem */
+#ifdef KERNFS
+ { &kernfs_vfsops, "kernfs", 11, 0, 0, NULL, NULL },
#endif
-struct vfsops *vfssw[] = {
- NULL, /* 0 = MOUNT_NONE */
- UFS_VFSOPS, /* 1 = MOUNT_UFS */
- NFS_VFSOPS, /* 2 = MOUNT_NFS */
- MFS_VFSOPS, /* 3 = MOUNT_MFS */
- NULL, /* 4 = MOUNT_PC */
- LFS_VFSOPS, /* 5 = MOUNT_LFS */
- NULL, /* 6 = MOUNT_LOFS */
- FDESC_VFSOPS, /* 7 = MOUNT_FDESC */
- PORTAL_VFSOPS, /* 8 = MOUNT_PORTAL */
- NULL_VFSOPS, /* 9 = MOUNT_NULL */
- UMAP_VFSOPS, /* 10 = MOUNT_UMAP */
- KERNFS_VFSOPS, /* 11 = MOUNT_KERNFS */
- PROCFS_VFSOPS, /* 12 = MOUNT_PROCFS */
- AFS_VFSOPS, /* 13 = MOUNT_AFS */
- CD9660_VFSOPS, /* 14 = MOUNT_CD9660 */
- UNION_VFSOPS, /* 15 = MOUNT_UNION */
- 0
};
+/*
+ * Initially the size of the list, vfs_init will set maxvfsconf
+ * to the highest defined type number.
+ */
+int maxvfsconf = sizeof(vfsconflist) / sizeof (struct vfsconf);
+struct vfsconf *vfsconf = vfsconflist;
/*
*
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index 1ce7347..b5abe58 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94
+ * @(#)vfs_init.c 8.5 (Berkeley) 5/11/95
*/
@@ -211,7 +211,6 @@ vfs_op_init()
*/
extern struct vnodeops dead_vnodeops;
extern struct vnodeops spec_vnodeops;
-extern void vclean();
struct vattr va_null;
/*
@@ -219,7 +218,8 @@ struct vattr va_null;
*/
vfsinit()
{
- struct vfsops **vfsp;
+ struct vfsconf *vfsp;
+ int i, maxtypenum;
/*
* Initialize the vnode table
@@ -238,9 +238,14 @@ vfsinit()
* Initialize each file system type.
*/
vattr_null(&va_null);
- for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) {
- if (*vfsp == NULL)
- continue;
- (*(*vfsp)->vfs_init)();
+ maxtypenum = 0;
+ for (vfsp = vfsconf, i = 1; i <= maxvfsconf; i++, vfsp++) {
+ if (i < maxvfsconf)
+ vfsp->vfc_next = vfsp + 1;
+ if (maxtypenum <= vfsp->vfc_typenum)
+ maxtypenum = vfsp->vfc_typenum + 1;
+ (*vfsp->vfc_vfsops->vfs_init)(vfsp);
}
+ /* next vfc_typenum to be used */
+ maxvfsconf = maxtypenum;
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 0fa5aa1..826fbfe 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_lookup.c 8.4 (Berkeley) 2/16/94
+ * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95
*/
#include <sys/param.h>
@@ -84,6 +84,7 @@ namei(ndp)
struct uio auio;
int error, linklen;
struct componentname *cnp = &ndp->ni_cnd;
+ struct proc *p = cnp->cn_proc;
ndp->ni_cnd.cn_cred = ndp->ni_cnd.cn_proc->p_ucred;
#ifdef DIAGNOSTIC
@@ -157,7 +158,7 @@ namei(ndp)
return (0);
}
if ((cnp->cn_flags & LOCKPARENT) && ndp->ni_pathlen == 1)
- VOP_UNLOCK(ndp->ni_dvp);
+ VOP_UNLOCK(ndp->ni_dvp, 0, p);
if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
error = ELOOP;
break;
@@ -255,6 +256,7 @@ lookup(ndp)
int rdonly; /* lookup read-only flag bit */
int error = 0;
struct componentname *cnp = &ndp->ni_cnd;
+ struct proc *p = cnp->cn_proc;
/*
* Setup: break out flag bits into variables.
@@ -269,7 +271,7 @@ lookup(ndp)
cnp->cn_flags &= ~ISSYMLINK;
dp = ndp->ni_startdir;
ndp->ni_startdir = NULLVP;
- VOP_LOCK(dp);
+ vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
dirloop:
/*
@@ -318,21 +320,21 @@ dirloop:
* e.g. like "/." or ".".
*/
if (cnp->cn_nameptr[0] == '\0') {
- if (cnp->cn_nameiop != LOOKUP) {
- error = EISDIR;
- goto bad;
- }
if (dp->v_type != VDIR) {
error = ENOTDIR;
goto bad;
}
+ if (cnp->cn_nameiop != LOOKUP) {
+ error = EISDIR;
+ goto bad;
+ }
if (wantparent) {
ndp->ni_dvp = dp;
VREF(dp);
}
ndp->ni_vp = dp;
if (!(cnp->cn_flags & (LOCKPARENT | LOCKLEAF)))
- VOP_UNLOCK(dp);
+ VOP_UNLOCK(dp, 0, p);
if (cnp->cn_flags & SAVESTART)
panic("lookup: SAVESTART");
return (0);
@@ -363,7 +365,7 @@ dirloop:
dp = dp->v_mount->mnt_vnodecovered;
vput(tdp);
VREF(dp);
- VOP_LOCK(dp);
+ vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
}
}
@@ -372,6 +374,7 @@ dirloop:
*/
unionlookup:
ndp->ni_dvp = dp;
+ ndp->ni_vp = NULL;
if (error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) {
#ifdef DIAGNOSTIC
if (ndp->ni_vp != NULL)
@@ -387,7 +390,7 @@ unionlookup:
dp = dp->v_mount->mnt_vnodecovered;
vput(tdp);
VREF(dp);
- VOP_LOCK(dp);
+ vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
goto unionlookup;
}
@@ -397,7 +400,7 @@ unionlookup:
* If creating and at end of pathname, then can consider
* allowing file to be created.
*/
- if (rdonly || (ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY)) {
+ if (rdonly) {
error = EROFS;
goto bad;
}
@@ -429,31 +432,30 @@ unionlookup:
dp = ndp->ni_vp;
/*
- * Check for symbolic link
- */
- if ((dp->v_type == VLNK) &&
- ((cnp->cn_flags & FOLLOW) || *ndp->ni_next == '/')) {
- cnp->cn_flags |= ISSYMLINK;
- return (0);
- }
-
- /*
* Check to see if the vnode has been mounted on;
* if so find the root of the mounted file system.
*/
while (dp->v_type == VDIR && (mp = dp->v_mountedhere) &&
(cnp->cn_flags & NOCROSSMOUNT) == 0) {
- if (mp->mnt_flag & MNT_MLOCK) {
- mp->mnt_flag |= MNT_MWAIT;
- sleep((caddr_t)mp, PVFS);
+ if (vfs_busy(mp, 0, 0, p))
continue;
- }
- if (error = VFS_ROOT(dp->v_mountedhere, &tdp))
+ error = VFS_ROOT(mp, &tdp);
+ vfs_unbusy(mp, p);
+ if (error)
goto bad2;
vput(dp);
ndp->ni_vp = dp = tdp;
}
+ /*
+ * Check for symbolic link
+ */
+ if ((dp->v_type == VLNK) &&
+ ((cnp->cn_flags & FOLLOW) || *ndp->ni_next == '/')) {
+ cnp->cn_flags |= ISSYMLINK;
+ return (0);
+ }
+
nextname:
/*
* Not a symbolic link. If more pathname,
@@ -469,19 +471,12 @@ nextname:
goto dirloop;
}
/*
- * Check for read-only file systems.
+ * Disallow directory write attempts on read-only file systems.
*/
- if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {
- /*
- * Disallow directory write attempts on read-only
- * file systems.
- */
- if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||
- (wantparent &&
- (ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY))) {
- error = EROFS;
- goto bad2;
- }
+ if (rdonly &&
+ (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
+ error = EROFS;
+ goto bad2;
}
if (cnp->cn_flags & SAVESTART) {
ndp->ni_startdir = ndp->ni_dvp;
@@ -490,12 +485,12 @@ nextname:
if (!wantparent)
vrele(ndp->ni_dvp);
if ((cnp->cn_flags & LOCKLEAF) == 0)
- VOP_UNLOCK(dp);
+ VOP_UNLOCK(dp, 0, p);
return (0);
bad2:
if ((cnp->cn_flags & LOCKPARENT) && *ndp->ni_next == '\0')
- VOP_UNLOCK(ndp->ni_dvp);
+ VOP_UNLOCK(ndp->ni_dvp, 0, p);
vrele(ndp->ni_dvp);
bad:
vput(dp);
@@ -503,4 +498,148 @@ bad:
return (error);
}
+/*
+ * relookup - lookup a path name component
+ * Used by lookup to re-aquire things.
+ */
+int
+relookup(dvp, vpp, cnp)
+ struct vnode *dvp, **vpp;
+ struct componentname *cnp;
+{
+ struct proc *p = cnp->cn_proc;
+ struct vnode *dp = 0; /* the directory we are searching */
+ int docache; /* == 0 do not cache last component */
+ int wantparent; /* 1 => wantparent or lockparent flag */
+ int rdonly; /* lookup read-only flag bit */
+ int error = 0;
+#ifdef NAMEI_DIAGNOSTIC
+ int newhash; /* DEBUG: check name hash */
+ char *cp; /* DEBUG: check name ptr/len */
+#endif
+
+ /*
+ * Setup: break out flag bits into variables.
+ */
+ wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
+ docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
+ if (cnp->cn_nameiop == DELETE ||
+ (wantparent && cnp->cn_nameiop != CREATE))
+ docache = 0;
+ rdonly = cnp->cn_flags & RDONLY;
+ cnp->cn_flags &= ~ISSYMLINK;
+ dp = dvp;
+ vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
+/* dirloop: */
+ /*
+ * Search a new directory.
+ *
+ * The cn_hash value is for use by vfs_cache.
+ * The last component of the filename is left accessible via
+ * cnp->cn_nameptr for callers that need the name. Callers needing
+ * the name set the SAVENAME flag. When done, they assume
+ * responsibility for freeing the pathname buffer.
+ */
+#ifdef NAMEI_DIAGNOSTIC
+ for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
+ newhash += (unsigned char)*cp;
+ if (newhash != cnp->cn_hash)
+ panic("relookup: bad hash");
+ if (cnp->cn_namelen != cp - cnp->cn_nameptr)
+ panic ("relookup: bad len");
+ if (*cp != 0)
+ panic("relookup: not last component");
+ printf("{%s}: ", cnp->cn_nameptr);
+#endif
+
+ /*
+ * Check for degenerate name (e.g. / or "")
+ * which is a way of talking about a directory,
+ * e.g. like "/." or ".".
+ */
+ if (cnp->cn_nameptr[0] == '\0') {
+ if (cnp->cn_nameiop != LOOKUP || wantparent) {
+ error = EISDIR;
+ goto bad;
+ }
+ if (dp->v_type != VDIR) {
+ error = ENOTDIR;
+ goto bad;
+ }
+ if (!(cnp->cn_flags & LOCKLEAF))
+ VOP_UNLOCK(dp, 0, p);
+ *vpp = dp;
+ if (cnp->cn_flags & SAVESTART)
+ panic("lookup: SAVESTART");
+ return (0);
+ }
+
+ if (cnp->cn_flags & ISDOTDOT)
+ panic ("relookup: lookup on dot-dot");
+
+ /*
+ * We now have a segment name to search for, and a directory to search.
+ */
+ if (error = VOP_LOOKUP(dp, vpp, cnp)) {
+#ifdef DIAGNOSTIC
+ if (*vpp != NULL)
+ panic("leaf should be empty");
+#endif
+ if (error != EJUSTRETURN)
+ goto bad;
+ /*
+ * If creating and at end of pathname, then can consider
+ * allowing file to be created.
+ */
+ if (rdonly) {
+ error = EROFS;
+ goto bad;
+ }
+ /* ASSERT(dvp == ndp->ni_startdir) */
+ if (cnp->cn_flags & SAVESTART)
+ VREF(dvp);
+ /*
+ * We return with ni_vp NULL to indicate that the entry
+ * doesn't currently exist, leaving a pointer to the
+ * (possibly locked) directory inode in ndp->ni_dvp.
+ */
+ return (0);
+ }
+ dp = *vpp;
+
+#ifdef DIAGNOSTIC
+ /*
+ * Check for symbolic link
+ */
+ if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW))
+ panic ("relookup: symlink found.\n");
+#endif
+
+ /*
+ * Disallow directory write attempts on read-only file systems.
+ */
+ if (rdonly &&
+ (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
+ error = EROFS;
+ goto bad2;
+ }
+ /* ASSERT(dvp == ndp->ni_startdir) */
+ if (cnp->cn_flags & SAVESTART)
+ VREF(dvp);
+
+ if (!wantparent)
+ vrele(dvp);
+ if ((cnp->cn_flags & LOCKLEAF) == 0)
+ VOP_UNLOCK(dp, 0, p);
+ return (0);
+
+bad2:
+ if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))
+ VOP_UNLOCK(dvp, 0, p);
+ vrele(dvp);
+bad:
+ vput(dp);
+ *vpp = NULL;
+ return (error);
+}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 9891fe6..f891e02 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94
+ * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
*/
/*
@@ -75,107 +75,167 @@ int vttoif_tab[9] = {
* Insq/Remq for the vnode usage lists.
*/
#define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs)
-#define bufremvn(bp) { \
- LIST_REMOVE(bp, b_vnbufs); \
- (bp)->b_vnbufs.le_next = NOLIST; \
+#define bufremvn(bp) { \
+ LIST_REMOVE(bp, b_vnbufs); \
+ (bp)->b_vnbufs.le_next = NOLIST; \
}
-
TAILQ_HEAD(freelst, vnode) vnode_free_list; /* vnode free list */
struct mntlist mountlist; /* mounted filesystem list */
+struct simplelock mountlist_slock;
+static struct simplelock mntid_slock;
+struct simplelock mntvnode_slock;
+struct simplelock vnode_free_list_slock;
+static struct simplelock spechash_slock;
/*
* Initialize the vnode management data structures.
*/
+void
vntblinit()
{
+ simple_lock_init(&mntvnode_slock);
+ simple_lock_init(&mntid_slock);
+ simple_lock_init(&spechash_slock);
TAILQ_INIT(&vnode_free_list);
- TAILQ_INIT(&mountlist);
+ simple_lock_init(&vnode_free_list_slock);
+ CIRCLEQ_INIT(&mountlist);
}
/*
- * Lock a filesystem.
- * Used to prevent access to it while mounting and unmounting.
+ * Mark a mount point as busy. Used to synchronize access and to delay
+ * unmounting. Interlock is not released on failure.
*/
-vfs_lock(mp)
- register struct mount *mp;
+int
+vfs_busy(mp, flags, interlkp, p)
+ struct mount *mp;
+ int flags;
+ struct simplelock *interlkp;
+ struct proc *p;
{
+ int lkflags;
- while(mp->mnt_flag & MNT_MLOCK) {
+ if (mp->mnt_flag & MNT_UNMOUNT) {
+ if (flags & LK_NOWAIT)
+ return (ENOENT);
mp->mnt_flag |= MNT_MWAIT;
+ if (interlkp)
+ simple_unlock(interlkp);
+ /*
+ * Since all busy locks are shared except the exclusive
+ * lock granted when unmounting, the only place that a
+ * wakeup needs to be done is at the release of the
+ * exclusive lock at the end of dounmount.
+ */
sleep((caddr_t)mp, PVFS);
+ if (interlkp)
+ simple_lock(interlkp);
+ return (ENOENT);
}
- mp->mnt_flag |= MNT_MLOCK;
+ lkflags = LK_SHARED;
+ if (interlkp)
+ lkflags |= LK_INTERLOCK;
+ if (lockmgr(&mp->mnt_lock, lkflags, interlkp, p))
+ panic("vfs_busy: unexpected lock failure");
return (0);
}
/*
- * Unlock a locked filesystem.
- * Panic if filesystem is not locked.
+ * Free a busy filesystem.
*/
void
-vfs_unlock(mp)
- register struct mount *mp;
+vfs_unbusy(mp, p)
+ struct mount *mp;
+ struct proc *p;
{
- if ((mp->mnt_flag & MNT_MLOCK) == 0)
- panic("vfs_unlock: not locked");
- mp->mnt_flag &= ~MNT_MLOCK;
- if (mp->mnt_flag & MNT_MWAIT) {
- mp->mnt_flag &= ~MNT_MWAIT;
- wakeup((caddr_t)mp);
- }
+ lockmgr(&mp->mnt_lock, LK_RELEASE, NULL, p);
}
/*
- * Mark a mount point as busy.
- * Used to synchronize access and to delay unmounting.
+ * Lookup a filesystem type, and if found allocate and initialize
+ * a mount structure for it.
+ *
+ * Devname is usually updated by mount(8) after booting.
*/
-vfs_busy(mp)
- register struct mount *mp;
+int
+vfs_rootmountalloc(fstypename, devname, mpp)
+ char *fstypename;
+ char *devname;
+ struct mount **mpp;
{
+ struct proc *p = curproc; /* XXX */
+ struct vfsconf *vfsp;
+ struct mount *mp;
- while(mp->mnt_flag & MNT_MPBUSY) {
- mp->mnt_flag |= MNT_MPWANT;
- sleep((caddr_t)&mp->mnt_flag, PVFS);
- }
- if (mp->mnt_flag & MNT_UNMOUNT)
- return (1);
- mp->mnt_flag |= MNT_MPBUSY;
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+ if (!strcmp(vfsp->vfc_name, fstypename))
+ break;
+ if (vfsp == NULL)
+ return (ENODEV);
+ mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
+ bzero((char *)mp, (u_long)sizeof(struct mount));
+ lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
+ (void)vfs_busy(mp, LK_NOWAIT, 0, p);
+ LIST_INIT(&mp->mnt_vnodelist);
+ mp->mnt_vfc = vfsp;
+ mp->mnt_op = vfsp->vfc_vfsops;
+ mp->mnt_flag = MNT_RDONLY;
+ mp->mnt_vnodecovered = NULLVP;
+ vfsp->vfc_refcount++;
+ mp->mnt_stat.f_type = vfsp->vfc_typenum;
+ mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
+ strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
+ mp->mnt_stat.f_mntonname[0] = '/';
+ (void) copystr(devname, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 0);
+ *mpp = mp;
return (0);
}
/*
- * Free a busy filesystem.
- * Panic if filesystem is not busy.
+ * Find an appropriate filesystem to use for the root. If a filesystem
+ * has not been preselected, walk through the list of known filesystems
+ * trying those that have mountroot routines, and try them until one
+ * works or we have tried them all.
*/
-vfs_unbusy(mp)
- register struct mount *mp;
+int
+vfs_mountroot()
{
+ struct vfsconf *vfsp;
+ extern int (*mountroot)(void);
+ int error;
- if ((mp->mnt_flag & MNT_MPBUSY) == 0)
- panic("vfs_unbusy: not busy");
- mp->mnt_flag &= ~MNT_MPBUSY;
- if (mp->mnt_flag & MNT_MPWANT) {
- mp->mnt_flag &= ~MNT_MPWANT;
- wakeup((caddr_t)&mp->mnt_flag);
+ if (mountroot != NULL)
+ return ((*mountroot)());
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
+ if (vfsp->vfc_mountroot == NULL)
+ continue;
+ if ((error = (*vfsp->vfc_mountroot)()) == 0)
+ return (0);
+ printf("%s_mountroot failed: %d\n", vfsp->vfc_name, error);
}
+ return (ENODEV);
}
/*
* Lookup a mount point by filesystem identifier.
*/
struct mount *
-getvfs(fsid)
+vfs_getvfs(fsid)
fsid_t *fsid;
{
register struct mount *mp;
- for (mp = mountlist.tqh_first; mp != NULL; mp = mp->mnt_list.tqe_next) {
+ simple_lock(&mountlist_slock);
+ for (mp = mountlist.cqh_first; mp != (void *)&mountlist;
+ mp = mp->mnt_list.cqe_next) {
if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] &&
- mp->mnt_stat.f_fsid.val[1] == fsid->val[1])
+ mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) {
+ simple_unlock(&mountlist_slock);
return (mp);
+ }
}
+ simple_unlock(&mountlist_slock);
return ((struct mount *)0);
}
@@ -183,33 +243,37 @@ getvfs(fsid)
* Get a new unique fsid
*/
void
-getnewfsid(mp, mtype)
+vfs_getnewfsid(mp)
struct mount *mp;
- int mtype;
{
static u_short xxxfs_mntid;
fsid_t tfsid;
+ int mtype;
+ simple_lock(&mntid_slock);
+ mtype = mp->mnt_vfc->vfc_typenum;
mp->mnt_stat.f_fsid.val[0] = makedev(nblkdev + mtype, 0);
mp->mnt_stat.f_fsid.val[1] = mtype;
if (xxxfs_mntid == 0)
++xxxfs_mntid;
tfsid.val[0] = makedev(nblkdev + mtype, xxxfs_mntid);
tfsid.val[1] = mtype;
- if (mountlist.tqh_first != NULL) {
- while (getvfs(&tfsid)) {
+ if (mountlist.cqh_first != (void *)&mountlist) {
+ while (vfs_getvfs(&tfsid)) {
tfsid.val[0]++;
xxxfs_mntid++;
}
}
mp->mnt_stat.f_fsid.val[0] = tfsid.val[0];
+ simple_unlock(&mntid_slock);
}
/*
* Set vnode attributes to VNOVAL
*/
-void vattr_null(vap)
+void
+vattr_null(vap)
register struct vattr *vap;
{
@@ -229,31 +293,49 @@ void vattr_null(vap)
* Routines having to do with the management of the vnode table.
*/
extern int (**dead_vnodeop_p)();
-extern void vclean();
+static void vclean __P((struct vnode *vp, int flag, struct proc *p));
+extern void vgonel __P((struct vnode *vp, struct proc *p));
long numvnodes;
extern struct vattr va_null;
/*
* Return the next vnode from the free list.
*/
+int
getnewvnode(tag, mp, vops, vpp)
enum vtagtype tag;
struct mount *mp;
int (**vops)();
struct vnode **vpp;
{
- register struct vnode *vp;
+ struct proc *p = curproc; /* XXX */
+ struct vnode *vp;
int s;
+ int cnt;
+top:
+ simple_lock(&vnode_free_list_slock);
if ((vnode_free_list.tqh_first == NULL &&
numvnodes < 2 * desiredvnodes) ||
numvnodes < desiredvnodes) {
+ simple_unlock(&vnode_free_list_slock);
vp = (struct vnode *)malloc((u_long)sizeof *vp,
M_VNODE, M_WAITOK);
bzero((char *)vp, sizeof *vp);
numvnodes++;
} else {
- if ((vp = vnode_free_list.tqh_first) == NULL) {
+ for (vp = vnode_free_list.tqh_first;
+ vp != NULLVP; vp = vp->v_freelist.tqe_next) {
+ if (simple_lock_try(&vp->v_interlock))
+ break;
+ }
+ /*
+ * Unless this is a bad time of the month, at most
+ * the first NCPUS items on the free list are
+ * locked, so this is close enough to being empty.
+ */
+ if (vp == NULLVP) {
+ simple_unlock(&vnode_free_list_slock);
tablefull("vnode");
*vpp = 0;
return (ENFILE);
@@ -263,9 +345,12 @@ getnewvnode(tag, mp, vops, vpp)
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
/* see comment on why 0xdeadb is set at end of vgone (below) */
vp->v_freelist.tqe_prev = (struct vnode **)0xdeadb;
+ simple_unlock(&vnode_free_list_slock);
vp->v_lease = NULL;
if (vp->v_type != VBAD)
- vgone(vp);
+ vgonel(vp, p);
+ else
+ simple_unlock(&vp->v_interlock);
#ifdef DIAGNOSTIC
if (vp->v_data)
panic("cleaned vnode isn't");
@@ -298,11 +383,13 @@ getnewvnode(tag, mp, vops, vpp)
/*
* Move a vnode from one mount queue to another.
*/
+void
insmntque(vp, mp)
- register struct vnode *vp;
- register struct mount *mp;
+ struct vnode *vp;
+ struct mount *mp;
{
+ simple_lock(&mntvnode_slock);
/*
* Delete from old mount point vnode list, if on one.
*/
@@ -311,14 +398,15 @@ insmntque(vp, mp)
/*
* Insert into list of vnodes for the new mount point, if available.
*/
- if ((vp->v_mount = mp) == NULL)
- return;
- LIST_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
+ if ((vp->v_mount = mp) != NULL)
+ LIST_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
+ simple_unlock(&mntvnode_slock);
}
/*
* Update outstanding I/O count and do wakeup if requested.
*/
+void
vwakeup(bp)
register struct buf *bp;
{
@@ -326,12 +414,11 @@ vwakeup(bp)
bp->b_flags &= ~B_WRITEINPROG;
if (vp = bp->b_vp) {
- vp->v_numoutput--;
- if (vp->v_numoutput < 0)
+ if (--vp->v_numoutput < 0)
panic("vwakeup: neg numoutput");
if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
if (vp->v_numoutput < 0)
- panic("vwakeup: neg numoutput");
+ panic("vwakeup: neg numoutput 2");
vp->v_flag &= ~VBWAIT;
wakeup((caddr_t)&vp->v_numoutput);
}
@@ -364,7 +451,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
if ((blist = vp->v_cleanblkhd.lh_first) && flags & V_SAVEMETA)
while (blist && blist->b_lblkno < 0)
blist = blist->b_vnbufs.le_next;
- if (!blist && (blist = vp->v_dirtyblkhd.lh_first) &&
+ if (!blist && (blist = vp->v_dirtyblkhd.lh_first) &&
(flags & V_SAVEMETA))
while (blist && blist->b_lblkno < 0)
blist = blist->b_vnbufs.le_next;
@@ -411,6 +498,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
/*
* Associate a buffer with a vnode.
*/
+void
bgetvp(vp, bp)
register struct vnode *vp;
register struct buf *bp;
@@ -433,6 +521,7 @@ bgetvp(vp, bp)
/*
* Disassociate a buffer from a vnode.
*/
+void
brelvp(bp)
register struct buf *bp;
{
@@ -455,6 +544,7 @@ brelvp(bp)
* Used to assign file specific control information
* (indirect blocks) to the vnode to which they belong.
*/
+void
reassignbuf(bp, newvp)
register struct buf *bp;
register struct vnode *newvp;
@@ -486,6 +576,7 @@ reassignbuf(bp, newvp)
* Used for root filesystem, argdev, and swap areas.
* Also used for memory file system special devices.
*/
+int
bdevvp(dev, vpp)
dev_t dev;
struct vnode **vpp;
@@ -494,11 +585,13 @@ bdevvp(dev, vpp)
struct vnode *nvp;
int error;
- if (dev == NODEV)
- return (0);
+ if (dev == NODEV) {
+ *vpp = NULLVP;
+ return (ENODEV);
+ }
error = getnewvnode(VT_NON, (struct mount *)0, spec_vnodeop_p, &nvp);
if (error) {
- *vpp = 0;
+ *vpp = NULLVP;
return (error);
}
vp = nvp;
@@ -525,7 +618,8 @@ checkalias(nvp, nvp_rdev, mp)
dev_t nvp_rdev;
struct mount *mp;
{
- register struct vnode *vp;
+ struct proc *p = curproc; /* XXX */
+ struct vnode *vp;
struct vnode **vpp;
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
@@ -533,18 +627,23 @@ checkalias(nvp, nvp_rdev, mp)
vpp = &speclisth[SPECHASH(nvp_rdev)];
loop:
+ simple_lock(&spechash_slock);
for (vp = *vpp; vp; vp = vp->v_specnext) {
if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
*/
+ simple_lock(&vp->v_interlock);
if (vp->v_usecount == 0) {
- vgone(vp);
+ simple_unlock(&spechash_slock);
+ vgonel(vp, p);
goto loop;
}
- if (vget(vp, 1))
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) {
+ simple_unlock(&spechash_slock);
goto loop;
+ }
break;
}
if (vp == NULL || vp->v_tag != VT_NON) {
@@ -554,16 +653,19 @@ loop:
nvp->v_hashchain = vpp;
nvp->v_specnext = *vpp;
nvp->v_specflags = 0;
+ simple_unlock(&spechash_slock);
*vpp = nvp;
- if (vp != NULL) {
+ if (vp != NULLVP) {
nvp->v_flag |= VALIASED;
vp->v_flag |= VALIASED;
vput(vp);
}
return (NULLVP);
}
- VOP_UNLOCK(vp);
- vclean(vp, 0);
+ simple_unlock(&spechash_slock);
+ VOP_UNLOCK(vp, 0, p);
+ simple_lock(&vp->v_interlock);
+ vclean(vp, 0, p);
vp->v_op = nvp->v_op;
vp->v_tag = nvp->v_tag;
nvp->v_type = VNON;
@@ -579,76 +681,219 @@ loop:
* indicate that the vnode is no longer usable (possibly having
* been changed to a new file system type).
*/
-vget(vp, lockflag)
- register struct vnode *vp;
- int lockflag;
+int
+vget(vp, flags, p)
+ struct vnode *vp;
+ int flags;
+ struct proc *p;
{
+ int error;
/*
* If the vnode is in the process of being cleaned out for
* another use, we wait for the cleaning to finish and then
- * return failure. Cleaning is determined either by checking
- * that the VXLOCK flag is set, or that the use count is
- * zero with the back pointer set to show that it has been
- * removed from the free list by getnewvnode. The VXLOCK
- * flag may not have been set yet because vclean is blocked in
- * the VOP_LOCK call waiting for the VOP_INACTIVE to complete.
+ * return failure. Cleaning is determined by checking that
+ * the VXLOCK flag is set.
*/
- if ((vp->v_flag & VXLOCK) ||
- (vp->v_usecount == 0 &&
- vp->v_freelist.tqe_prev == (struct vnode **)0xdeadb)) {
+ if ((flags & LK_INTERLOCK) == 0)
+ simple_lock(&vp->v_interlock);
+ if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
- sleep((caddr_t)vp, PINOD);
- return (1);
+ simple_unlock(&vp->v_interlock);
+ tsleep((caddr_t)vp, PINOD, "vget", 0);
+ return (ENOENT);
}
- if (vp->v_usecount == 0)
+ if (vp->v_usecount == 0) {
+ simple_lock(&vnode_free_list_slock);
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
+ simple_unlock(&vnode_free_list_slock);
+ }
vp->v_usecount++;
- if (lockflag)
- VOP_LOCK(vp);
+ if (flags & LK_TYPE_MASK) {
+ if (error = vn_lock(vp, flags | LK_INTERLOCK, p))
+ vrele(vp);
+ return (error);
+ }
+ simple_unlock(&vp->v_interlock);
+ return (0);
+}
+
+/*
+ * Stubs to use when there is no locking to be done on the underlying object.
+ * A minimal shared lock is necessary to ensure that the underlying object
+ * is not revoked while an operation is in progress. So, an active shared
+ * count is maintained in an auxillary vnode lock structure.
+ */
+int
+vop_nolock(ap)
+ struct vop_lock_args /* {
+ struct vnode *a_vp;
+ int a_flags;
+ struct proc *a_p;
+ } */ *ap;
+{
+#ifdef notyet
+ /*
+ * This code cannot be used until all the non-locking filesystems
+ * (notably NFS) are converted to properly lock and release nodes.
+ * Also, certain vnode operations change the locking state within
+ * the operation (create, mknod, remove, link, rename, mkdir, rmdir,
+ * and symlink). Ideally these operations should not change the
+ * lock state, but should be changed to let the caller of the
+ * function unlock them. Otherwise all intermediate vnode layers
+ * (such as union, umapfs, etc) must catch these functions to do
+ * the necessary locking at their layer. Note that the inactive
+ * and lookup operations also change their lock state, but this
+ * cannot be avoided, so these two operations will always need
+ * to be handled in intermediate layers.
+ */
+ struct vnode *vp = ap->a_vp;
+ int vnflags, flags = ap->a_flags;
+
+ if (vp->v_vnlock == NULL) {
+ if ((flags & LK_TYPE_MASK) == LK_DRAIN)
+ return (0);
+ MALLOC(vp->v_vnlock, struct lock *, sizeof(struct lock),
+ M_VNODE, M_WAITOK);
+ lockinit(vp->v_vnlock, PVFS, "vnlock", 0, 0);
+ }
+ switch (flags & LK_TYPE_MASK) {
+ case LK_DRAIN:
+ vnflags = LK_DRAIN;
+ break;
+ case LK_EXCLUSIVE:
+ case LK_SHARED:
+ vnflags = LK_SHARED;
+ break;
+ case LK_UPGRADE:
+ case LK_EXCLUPGRADE:
+ case LK_DOWNGRADE:
+ return (0);
+ case LK_RELEASE:
+ default:
+ panic("vop_nolock: bad operation %d", flags & LK_TYPE_MASK);
+ }
+ if (flags & LK_INTERLOCK)
+ vnflags |= LK_INTERLOCK;
+ return(lockmgr(vp->v_vnlock, vnflags, &vp->v_interlock, ap->a_p));
+#else /* for now */
+ /*
+ * Since we are not using the lock manager, we must clear
+ * the interlock here.
+ */
+ if (ap->a_flags & LK_INTERLOCK)
+ simple_unlock(&ap->a_vp->v_interlock);
return (0);
+#endif
+}
+
+/*
+ * Decrement the active use count.
+ */
+int
+vop_nounlock(ap)
+ struct vop_unlock_args /* {
+ struct vnode *a_vp;
+ int a_flags;
+ struct proc *a_p;
+ } */ *ap;
+{
+ struct vnode *vp = ap->a_vp;
+
+ if (vp->v_vnlock == NULL)
+ return (0);
+ return (lockmgr(vp->v_vnlock, LK_RELEASE, NULL, ap->a_p));
}
/*
- * Vnode reference, just increment the count
+ * Return whether or not the node is in use.
*/
-void vref(vp)
+int
+vop_noislocked(ap)
+ struct vop_islocked_args /* {
+ struct vnode *a_vp;
+ } */ *ap;
+{
+ struct vnode *vp = ap->a_vp;
+
+ if (vp->v_vnlock == NULL)
+ return (0);
+ return (lockstatus(vp->v_vnlock));
+}
+
+/*
+ * Vnode reference.
+ */
+void
+vref(vp)
struct vnode *vp;
{
+ simple_lock(&vp->v_interlock);
if (vp->v_usecount <= 0)
panic("vref used where vget required");
vp->v_usecount++;
+ simple_unlock(&vp->v_interlock);
}
/*
* vput(), just unlock and vrele()
*/
-void vput(vp)
- register struct vnode *vp;
+void
+vput(vp)
+ struct vnode *vp;
{
+ struct proc *p = curproc; /* XXX */
- VOP_UNLOCK(vp);
- vrele(vp);
+#ifdef DIGANOSTIC
+ if (vp == NULL)
+ panic("vput: null vp");
+#endif
+ simple_lock(&vp->v_interlock);
+ vp->v_usecount--;
+ if (vp->v_usecount > 0) {
+ simple_unlock(&vp->v_interlock);
+ VOP_UNLOCK(vp, 0, p);
+ return;
+ }
+#ifdef DIAGNOSTIC
+ if (vp->v_usecount < 0 || vp->v_writecount != 0) {
+ vprint("vput: bad ref count", vp);
+ panic("vput: ref cnt");
+ }
+#endif
+ /*
+ * insert at tail of LRU list
+ */
+ simple_lock(&vnode_free_list_slock);
+ TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
+ simple_unlock(&vnode_free_list_slock);
+ simple_unlock(&vp->v_interlock);
+ VOP_INACTIVE(vp, p);
}
/*
* Vnode release.
* If count drops to zero, call inactive routine and return to freelist.
*/
-void vrele(vp)
- register struct vnode *vp;
+void
+vrele(vp)
+ struct vnode *vp;
{
+ struct proc *p = curproc; /* XXX */
#ifdef DIAGNOSTIC
if (vp == NULL)
panic("vrele: null vp");
#endif
+ simple_lock(&vp->v_interlock);
vp->v_usecount--;
- if (vp->v_usecount > 0)
+ if (vp->v_usecount > 0) {
+ simple_unlock(&vp->v_interlock);
return;
+ }
#ifdef DIAGNOSTIC
- if (vp->v_usecount != 0 || vp->v_writecount != 0) {
+ if (vp->v_usecount < 0 || vp->v_writecount != 0) {
vprint("vrele: bad ref count", vp);
panic("vrele: ref cnt");
}
@@ -656,31 +901,42 @@ void vrele(vp)
/*
* insert at tail of LRU list
*/
+ simple_lock(&vnode_free_list_slock);
TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
- VOP_INACTIVE(vp);
+ simple_unlock(&vnode_free_list_slock);
+ if (vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK, p) == 0)
+ VOP_INACTIVE(vp, p);
}
+#ifdef DIAGNOSTIC
/*
* Page or buffer structure gets a reference.
*/
-void vhold(vp)
+void
+vhold(vp)
register struct vnode *vp;
{
+ simple_lock(&vp->v_interlock);
vp->v_holdcnt++;
+ simple_unlock(&vp->v_interlock);
}
/*
* Page or buffer structure frees a reference.
*/
-void holdrele(vp)
+void
+holdrele(vp)
register struct vnode *vp;
{
+ simple_lock(&vp->v_interlock);
if (vp->v_holdcnt <= 0)
panic("holdrele: holdcnt");
vp->v_holdcnt--;
+ simple_unlock(&vp->v_interlock);
}
+#endif /* DIAGNOSTIC */
/*
* Remove any vnodes in the vnode table belonging to mount point mp.
@@ -695,16 +951,17 @@ int busyprt = 0; /* print out busy vnodes */
struct ctldebug debug1 = { "busyprt", &busyprt };
#endif
+int
vflush(mp, skipvp, flags)
struct mount *mp;
struct vnode *skipvp;
int flags;
{
- register struct vnode *vp, *nvp;
+ struct proc *p = curproc; /* XXX */
+ struct vnode *vp, *nvp;
int busy = 0;
- if ((mp->mnt_flag & MNT_MPBUSY) == 0)
- panic("vflush: not busy");
+ simple_lock(&mntvnode_slock);
loop:
for (vp = mp->mnt_vnodelist.lh_first; vp; vp = nvp) {
if (vp->v_mount != mp)
@@ -715,24 +972,32 @@ loop:
*/
if (vp == skipvp)
continue;
+
+ simple_lock(&vp->v_interlock);
/*
* Skip over a vnodes marked VSYSTEM.
*/
- if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM))
+ if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM)) {
+ simple_unlock(&vp->v_interlock);
continue;
+ }
/*
* If WRITECLOSE is set, only flush out regular file
* vnodes open for writing.
*/
if ((flags & WRITECLOSE) &&
- (vp->v_writecount == 0 || vp->v_type != VREG))
+ (vp->v_writecount == 0 || vp->v_type != VREG)) {
+ simple_unlock(&vp->v_interlock);
continue;
+ }
/*
* With v_usecount == 0, all we need to do is clear
* out the vnode data structures and we are done.
*/
if (vp->v_usecount == 0) {
- vgone(vp);
+ simple_unlock(&mntvnode_slock);
+ vgonel(vp, p);
+ simple_lock(&mntvnode_slock);
continue;
}
/*
@@ -741,21 +1006,25 @@ loop:
* anonymous device. For all other files, just kill them.
*/
if (flags & FORCECLOSE) {
+ simple_unlock(&mntvnode_slock);
if (vp->v_type != VBLK && vp->v_type != VCHR) {
- vgone(vp);
+ vgonel(vp, p);
} else {
- vclean(vp, 0);
+ vclean(vp, 0, p);
vp->v_op = spec_vnodeop_p;
insmntque(vp, (struct mount *)0);
}
+ simple_lock(&mntvnode_slock);
continue;
}
#ifdef DIAGNOSTIC
if (busyprt)
vprint("vflush: busy vnode", vp);
#endif
+ simple_unlock(&vp->v_interlock);
busy++;
}
+ simple_unlock(&mntvnode_slock);
if (busy)
return (EBUSY);
return (0);
@@ -763,11 +1032,13 @@ loop:
/*
* Disassociate the underlying file system from a vnode.
+ * The vnode interlock is held on entry.
*/
-void
-vclean(vp, flags)
- register struct vnode *vp;
+static void
+vclean(vp, flags, p)
+ struct vnode *vp;
int flags;
+ struct proc *p;
{
int active;
@@ -778,15 +1049,7 @@ vclean(vp, flags)
* race against ourselves to recycle it.
*/
if (active = vp->v_usecount)
- VREF(vp);
- /*
- * Even if the count is zero, the VOP_INACTIVE routine may still
- * have the object locked while it cleans it out. The VOP_LOCK
- * ensures that the VOP_INACTIVE routine is done with its work.
- * For active vnodes, it ensures that no other activity can
- * occur while the underlying object is being cleaned out.
- */
- VOP_LOCK(vp);
+ vp->v_usecount++;
/*
* Prevent the vnode from being recycled or
* brought into use while we clean it out.
@@ -795,31 +1058,48 @@ vclean(vp, flags)
panic("vclean: deadlock");
vp->v_flag |= VXLOCK;
/*
- * Clean out any buffers associated with the vnode.
+ * Even if the count is zero, the VOP_INACTIVE routine may still
+ * have the object locked while it cleans it out. The VOP_LOCK
+ * ensures that the VOP_INACTIVE routine is done with its work.
+ * For active vnodes, it ensures that no other activity can
+ * occur while the underlying object is being cleaned out.
*/
- if (flags & DOCLOSE)
- vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0);
+ VOP_LOCK(vp, LK_DRAIN | LK_INTERLOCK, p);
/*
- * Any other processes trying to obtain this lock must first
- * wait for VXLOCK to clear, then call the new lock operation.
+ * Clean out any buffers associated with the vnode.
*/
- VOP_UNLOCK(vp);
+ if (flags & DOCLOSE)
+ vinvalbuf(vp, V_SAVE, NOCRED, p, 0, 0);
/*
* If purging an active vnode, it must be closed and
- * deactivated before being reclaimed.
+ * deactivated before being reclaimed. Note that the
+ * VOP_INACTIVE will unlock the vnode.
*/
if (active) {
if (flags & DOCLOSE)
- VOP_CLOSE(vp, IO_NDELAY, NOCRED, NULL);
- VOP_INACTIVE(vp);
+ VOP_CLOSE(vp, IO_NDELAY, NOCRED, p);
+ VOP_INACTIVE(vp, p);
+ } else {
+ /*
+ * Any other processes trying to obtain this lock must first
+ * wait for VXLOCK to clear, then call the new lock operation.
+ */
+ VOP_UNLOCK(vp, 0, p);
}
/*
* Reclaim the vnode.
*/
- if (VOP_RECLAIM(vp))
+ if (VOP_RECLAIM(vp, p))
panic("vclean: cannot reclaim");
if (active)
vrele(vp);
+ cache_purge(vp);
+ if (vp->v_vnlock) {
+ if ((vp->v_vnlock->lk_flags & LK_DRAINED) == 0)
+ vprint("vclean: lock not drained", vp);
+ FREE(vp->v_vnlock, M_VNODE);
+ vp->v_vnlock = NULL;
+ }
/*
* Done with purge, notify sleepers of the grim news.
@@ -837,10 +1117,23 @@ vclean(vp, flags)
* Eliminate all activity associated with the requested vnode
* and with all vnodes aliased to the requested vnode.
*/
-void vgoneall(vp)
- register struct vnode *vp;
+int
+vop_revoke(ap)
+ struct vop_revoke_args /* {
+ struct vnode *a_vp;
+ int a_flags;
+ } */ *ap;
{
- register struct vnode *vq;
+ struct vnode *vp, *vq;
+ struct proc *p = curproc; /* XXX */
+
+#ifdef DIAGNOSTIC
+ if ((ap->a_flags & REVOKEALL) == 0)
+ panic("vop_revoke");
+#endif
+
+ vp = ap->a_vp;
+ simple_lock(&vp->v_interlock);
if (vp->v_flag & VALIASED) {
/*
@@ -849,41 +1142,86 @@ void vgoneall(vp)
*/
if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
- sleep((caddr_t)vp, PINOD);
- return;
+ simple_unlock(&vp->v_interlock);
+ tsleep((caddr_t)vp, PINOD, "vop_revokeall", 0);
+ return (0);
}
/*
* Ensure that vp will not be vgone'd while we
* are eliminating its aliases.
*/
vp->v_flag |= VXLOCK;
+ simple_unlock(&vp->v_interlock);
while (vp->v_flag & VALIASED) {
+ simple_lock(&spechash_slock);
for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_rdev != vp->v_rdev ||
vq->v_type != vp->v_type || vp == vq)
continue;
+ simple_unlock(&spechash_slock);
vgone(vq);
break;
}
+ if (vq == NULLVP)
+ simple_unlock(&spechash_slock);
}
/*
* Remove the lock so that vgone below will
* really eliminate the vnode after which time
* vgone will awaken any sleepers.
*/
+ simple_lock(&vp->v_interlock);
vp->v_flag &= ~VXLOCK;
}
- vgone(vp);
+ vgonel(vp, p);
+ return (0);
+}
+
+/*
+ * Recycle an unused vnode to the front of the free list.
+ * Release the passed interlock if the vnode will be recycled.
+ */
+int
+vrecycle(vp, inter_lkp, p)
+ struct vnode *vp;
+ struct simplelock *inter_lkp;
+ struct proc *p;
+{
+
+ simple_lock(&vp->v_interlock);
+ if (vp->v_usecount == 0) {
+ if (inter_lkp)
+ simple_unlock(inter_lkp);
+ vgonel(vp, p);
+ return (1);
+ }
+ simple_unlock(&vp->v_interlock);
+ return (0);
}
/*
* Eliminate all activity associated with a vnode
* in preparation for reuse.
*/
-void vgone(vp)
- register struct vnode *vp;
+void
+vgone(vp)
+ struct vnode *vp;
{
- register struct vnode *vq;
+ struct proc *p = curproc; /* XXX */
+
+ simple_lock(&vp->v_interlock);
+ vgonel(vp, p);
+}
+
+/*
+ * vgone, with the vp interlock held.
+ */
+void
+vgonel(vp, p)
+ struct vnode *vp;
+ struct proc *p;
+{
+ struct vnode *vq;
struct vnode *vx;
/*
@@ -892,24 +1230,25 @@ void vgone(vp)
*/
if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
- sleep((caddr_t)vp, PINOD);
+ simple_unlock(&vp->v_interlock);
+ tsleep((caddr_t)vp, PINOD, "vgone", 0);
return;
}
/*
* Clean out the filesystem specific data.
*/
- vclean(vp, DOCLOSE);
+ vclean(vp, DOCLOSE, p);
/*
* Delete from old mount point vnode list, if on one.
*/
- if (vp->v_mount != NULL) {
- LIST_REMOVE(vp, v_mntvnodes);
- vp->v_mount = NULL;
- }
+ if (vp->v_mount != NULL)
+ insmntque(vp, (struct mount *)0);
/*
- * If special device, remove it from special device alias list.
+ * If special device, remove it from special device alias list
+ * if it is on one.
*/
- if (vp->v_type == VBLK || vp->v_type == VCHR) {
+ if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_specinfo != 0) {
+ simple_lock(&spechash_slock);
if (*vp->v_hashchain == vp) {
*vp->v_hashchain = vp->v_specnext;
} else {
@@ -938,6 +1277,7 @@ void vgone(vp)
vx->v_flag &= ~VALIASED;
vp->v_flag &= ~VALIASED;
}
+ simple_unlock(&spechash_slock);
FREE(vp->v_specinfo, M_VNODE);
vp->v_specinfo = NULL;
}
@@ -954,11 +1294,14 @@ void vgone(vp)
* getnewvnode after removing it from the freelist to ensure
* that we do not try to move it here.
*/
- if (vp->v_usecount == 0 &&
- vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb &&
- vnode_free_list.tqh_first != vp) {
- TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
- TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
+ if (vp->v_usecount == 0) {
+ simple_lock(&vnode_free_list_slock);
+ if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb) &&
+ vnode_free_list.tqh_first != vp) {
+ TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
+ TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
+ }
+ simple_unlock(&vnode_free_list_slock);
}
vp->v_type = VBAD;
}
@@ -966,34 +1309,41 @@ void vgone(vp)
/*
* Lookup a vnode by device number.
*/
+int
vfinddev(dev, type, vpp)
dev_t dev;
enum vtype type;
struct vnode **vpp;
{
- register struct vnode *vp;
+ struct vnode *vp;
+ int rc = 0;
+ simple_lock(&spechash_slock);
for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
if (dev != vp->v_rdev || type != vp->v_type)
continue;
*vpp = vp;
- return (1);
+ rc = 1;
+ break;
}
- return (0);
+ simple_unlock(&spechash_slock);
+ return (rc);
}
/*
* Calculate the total number of references to a special device.
*/
+int
vcount(vp)
- register struct vnode *vp;
+ struct vnode *vp;
{
- register struct vnode *vq, *vnext;
+ struct vnode *vq, *vnext;
int count;
loop:
if ((vp->v_flag & VALIASED) == 0)
return (vp->v_usecount);
+ simple_lock(&spechash_slock);
for (count = 0, vq = *vp->v_hashchain; vq; vq = vnext) {
vnext = vq->v_specnext;
if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
@@ -1002,11 +1352,13 @@ loop:
* Alias, but not in use, so flush it out.
*/
if (vq->v_usecount == 0 && vq != vp) {
+ simple_unlock(&spechash_slock);
vgone(vq);
goto loop;
}
count += vq->v_usecount;
}
+ simple_unlock(&spechash_slock);
return (count);
}
@@ -1016,6 +1368,7 @@ loop:
static char *typename[] =
{ "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" };
+void
vprint(label, vp)
char *label;
register struct vnode *vp;
@@ -1057,22 +1410,79 @@ vprint(label, vp)
* List all of the locked vnodes in the system.
* Called when debugging the kernel.
*/
+void
printlockedvnodes()
{
- register struct mount *mp;
- register struct vnode *vp;
+ struct proc *p = curproc; /* XXX */
+ struct mount *mp, *nmp;
+ struct vnode *vp;
printf("Locked vnodes\n");
- for (mp = mountlist.tqh_first; mp != NULL; mp = mp->mnt_list.tqe_next) {
+ simple_lock(&mountlist_slock);
+ for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
+ if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
+ nmp = mp->mnt_list.cqe_next;
+ continue;
+ }
for (vp = mp->mnt_vnodelist.lh_first;
vp != NULL;
- vp = vp->v_mntvnodes.le_next)
+ vp = vp->v_mntvnodes.le_next) {
if (VOP_ISLOCKED(vp))
vprint((char *)0, vp);
+ }
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
}
+ simple_unlock(&mountlist_slock);
}
#endif
+/*
+ * Top level filesystem related information gathering.
+ */
+int
+vfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ struct proc *p;
+{
+ struct ctldebug *cdp;
+ struct vfsconf *vfsp;
+
+ /* all sysctl names at this level are at least name and field */
+ if (namelen < 2)
+ return (ENOTDIR); /* overloaded */
+ if (name[0] != VFS_GENERIC) {
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+ if (vfsp->vfc_typenum == name[0])
+ break;
+ if (vfsp == NULL)
+ return (EOPNOTSUPP);
+ return ((*vfsp->vfc_vfsops->vfs_sysctl)(&name[1], namelen - 1,
+ oldp, oldlenp, newp, newlen, p));
+ }
+ switch (name[1]) {
+ case VFS_MAXTYPENUM:
+ return (sysctl_rdint(oldp, oldlenp, newp, maxvfsconf));
+ case VFS_CONF:
+ if (namelen < 3)
+ return (ENOTDIR); /* overloaded */
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+ if (vfsp->vfc_typenum == name[2])
+ break;
+ if (vfsp == NULL)
+ return (EOPNOTSUPP);
+ return (sysctl_rdstruct(oldp, oldlenp, newp, vfsp,
+ sizeof(struct vfsconf)));
+ }
+ return (EOPNOTSUPP);
+}
+
int kinfo_vdebug = 1;
int kinfo_vgetfailed;
#define KINFO_VNODESLOP 10
@@ -1081,13 +1491,15 @@ int kinfo_vgetfailed;
* Copyout address of vnode followed by vnode.
*/
/* ARGSUSED */
-sysctl_vnode(where, sizep)
+int
+sysctl_vnode(where, sizep, p)
char *where;
size_t *sizep;
+ struct proc *p;
{
- register struct mount *mp, *nmp;
- struct vnode *vp;
- register char *bp = where, *savebp;
+ struct mount *mp, *nmp;
+ struct vnode *nvp, *vp;
+ char *bp = where, *savebp;
char *ewhere;
int error;
@@ -1099,37 +1511,49 @@ sysctl_vnode(where, sizep)
}
ewhere = where + *sizep;
- for (mp = mountlist.tqh_first; mp != NULL; mp = nmp) {
- nmp = mp->mnt_list.tqe_next;
- if (vfs_busy(mp))
+ simple_lock(&mountlist_slock);
+ for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
+ if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
+ nmp = mp->mnt_list.cqe_next;
continue;
+ }
savebp = bp;
again:
+ simple_lock(&mntvnode_slock);
for (vp = mp->mnt_vnodelist.lh_first;
vp != NULL;
- vp = vp->v_mntvnodes.le_next) {
+ vp = nvp) {
/*
* Check that the vp is still associated with
* this filesystem. RACE: could have been
* recycled onto the same filesystem.
*/
if (vp->v_mount != mp) {
+ simple_unlock(&mntvnode_slock);
if (kinfo_vdebug)
printf("kinfo: vp changed\n");
bp = savebp;
goto again;
}
+ nvp = vp->v_mntvnodes.le_next;
if (bp + VPTRSZ + VNODESZ > ewhere) {
+ simple_unlock(&mntvnode_slock);
*sizep = bp - where;
return (ENOMEM);
}
+ simple_unlock(&mntvnode_slock);
if ((error = copyout((caddr_t)&vp, bp, VPTRSZ)) ||
(error = copyout((caddr_t)vp, bp + VPTRSZ, VNODESZ)))
return (error);
bp += VPTRSZ + VNODESZ;
+ simple_lock(&mntvnode_slock);
}
- vfs_unbusy(mp);
+ simple_unlock(&mntvnode_slock);
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
}
+ simple_unlock(&mountlist_slock);
*sizep = bp - where;
return (0);
@@ -1140,22 +1564,46 @@ again:
*/
int
vfs_mountedon(vp)
- register struct vnode *vp;
+ struct vnode *vp;
{
- register struct vnode *vq;
+ struct vnode *vq;
+ int error = 0;
if (vp->v_specflags & SI_MOUNTEDON)
return (EBUSY);
if (vp->v_flag & VALIASED) {
+ simple_lock(&spechash_slock);
for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_rdev != vp->v_rdev ||
vq->v_type != vp->v_type)
continue;
- if (vq->v_specflags & SI_MOUNTEDON)
- return (EBUSY);
+ if (vq->v_specflags & SI_MOUNTEDON) {
+ error = EBUSY;
+ break;
+ }
}
+ simple_unlock(&spechash_slock);
+ }
+ return (error);
+}
+
+/*
+ * Unmount all filesystems. The list is traversed in reverse order
+ * of mounting to avoid dependencies.
+ */
+void
+vfs_unmountall()
+{
+ struct mount *mp, *nmp;
+ struct proc *p = curproc; /* XXX */
+
+ /*
+ * Since this only runs when rebooting, it is not interlocked.
+ */
+ for (mp = mountlist.cqh_last; mp != (void *)&mountlist; mp = nmp) {
+ nmp = mp->mnt_list.cqe_prev;
+ (void) dounmount(mp, MNT_FORCE, p);
}
- return (0);
}
/*
@@ -1221,9 +1669,21 @@ vfs_hang_addrlist(mp, nep, argp)
}
rn = (*rnh->rnh_addaddr)((caddr_t)saddr, (caddr_t)smask, rnh,
np->netc_rnodes);
- if (rn == 0 || np != (struct netcred *)rn) { /* already exists */
- error = EPERM;
- goto out;
+ if (rn == 0) {
+ /*
+ * One of the reasons that rnh_addaddr may fail is that
+ * the entry already exists. To check for this case, we
+ * look up the entry to see if it is there. If so, we
+ * do not need to make a new entry but do return success.
+ */
+ free(np, M_NETADDR);
+ rn = (*rnh->rnh_matchaddr)((caddr_t)saddr, rnh);
+ if (rn != 0 && (rn->rn_flags & RNF_ROOT) == 0 &&
+ ((struct netcred *)rn)->netc_exflags == argp->ex_flags &&
+ !bcmp((caddr_t)&((struct netcred *)rn)->netc_anon,
+ (caddr_t)&argp->ex_anon, sizeof(struct ucred)))
+ return (0);
+ return (EPERM);
}
np->netc_exflags = argp->ex_flags;
np->netc_anon = argp->ex_anon;
@@ -1246,7 +1706,7 @@ vfs_free_netcred(rn, w)
free((caddr_t)rn, M_NETADDR);
return (0);
}
-
+
/*
* Free the net address hash lists that are hanging off the mount points.
*/
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 345c7a7..0cf7680 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
+ * @(#)vfs_syscalls.c 8.41 (Berkeley) 6/15/95
*/
#include <sys/param.h>
@@ -52,10 +52,13 @@
#include <sys/malloc.h>
#include <sys/dirent.h>
+#include <sys/syscallargs.h>
+
#include <vm/vm.h>
#include <sys/sysctl.h>
static int change_dir __P((struct nameidata *ndp, struct proc *p));
+static void checkdirs __P((struct vnode *olddp));
/*
* Virtual File System System Calls
@@ -64,36 +67,36 @@ static int change_dir __P((struct nameidata *ndp, struct proc *p));
/*
* Mount a file system.
*/
-struct mount_args {
- int type;
- char *path;
- int flags;
- caddr_t data;
-};
/* ARGSUSED */
+int
mount(p, uap, retval)
struct proc *p;
- register struct mount_args *uap;
- int *retval;
+ register struct mount_args /* {
+ syscallarg(char *) type;
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ register_t *retval;
{
- register struct vnode *vp;
- register struct mount *mp;
+ struct vnode *vp;
+ struct mount *mp;
+ struct vfsconf *vfsp;
int error, flag;
+ struct vattr va;
+ u_long fstypenum;
struct nameidata nd;
+ char fstypename[MFSNAMELEN];
/*
- * Must be super user
- */
- if (error = suser(p->p_ucred, &p->p_acflag))
- return (error);
- /*
* Get vnode to be covered
*/
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- if (uap->flags & MNT_UPDATE) {
+ if (SCARG(uap, flags) & MNT_UPDATE) {
if ((vp->v_flag & VROOT) == 0) {
vput(vp);
return (EINVAL);
@@ -104,63 +107,134 @@ mount(p, uap, retval)
* We only allow the filesystem to be reloaded if it
* is currently mounted read-only.
*/
- if ((uap->flags & MNT_RELOAD) &&
+ if ((SCARG(uap, flags) & MNT_RELOAD) &&
((mp->mnt_flag & MNT_RDONLY) == 0)) {
vput(vp);
return (EOPNOTSUPP); /* Needs translation */
}
mp->mnt_flag |=
- uap->flags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
- VOP_UNLOCK(vp);
+ SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
+ /*
+ * Only root, or the user that did the original mount is
+ * permitted to update it.
+ */
+ if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
+ (error = suser(p->p_ucred, &p->p_acflag))) {
+ vput(vp);
+ return (error);
+ }
+ /*
+ * Do not allow NFS export by non-root users. Silently
+ * enforce MNT_NOSUID and MNT_NODEV for non-root users.
+ */
+ if (p->p_ucred->cr_uid != 0) {
+ if (SCARG(uap, flags) & MNT_EXPORTED) {
+ vput(vp);
+ return (EPERM);
+ }
+ SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
+ }
+ if (vfs_busy(mp, LK_NOWAIT, 0, p)) {
+ vput(vp);
+ return (EBUSY);
+ }
+ VOP_UNLOCK(vp, 0, p);
goto update;
}
+ /*
+ * If the user is not root, ensure that they own the directory
+ * onto which we are attempting to mount.
+ */
+ if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) ||
+ (va.va_uid != p->p_ucred->cr_uid &&
+ (error = suser(p->p_ucred, &p->p_acflag)))) {
+ vput(vp);
+ return (error);
+ }
+ /*
+ * Do not allow NFS export by non-root users. Silently
+ * enforce MNT_NOSUID and MNT_NODEV for non-root users.
+ */
+ if (p->p_ucred->cr_uid != 0) {
+ if (SCARG(uap, flags) & MNT_EXPORTED) {
+ vput(vp);
+ return (EPERM);
+ }
+ SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
+ }
if (error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0))
return (error);
if (vp->v_type != VDIR) {
vput(vp);
return (ENOTDIR);
}
- if ((u_long)uap->type > MOUNT_MAXTYPE || vfssw[uap->type] == NULL) {
- vput(vp);
- return (ENODEV);
- }
-
+#ifdef COMPAT_43
/*
- * Allocate and initialize the file system.
+ * Historically filesystem types were identified by number. If we
+ * get an integer for the filesystem type instead of a string, we
+ * check to see if it matches one of the historic filesystem types.
*/
- mp = (struct mount *)malloc((u_long)sizeof(struct mount),
- M_MOUNT, M_WAITOK);
- bzero((char *)mp, (u_long)sizeof(struct mount));
- mp->mnt_op = vfssw[uap->type];
- if (error = vfs_lock(mp)) {
- free((caddr_t)mp, M_MOUNT);
+ fstypenum = (u_long)SCARG(uap, type);
+ if (fstypenum < maxvfsconf) {
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+ if (vfsp->vfc_typenum == fstypenum)
+ break;
+ if (vfsp == NULL) {
+ vput(vp);
+ return (ENODEV);
+ }
+ strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN);
+ } else
+#endif /* COMPAT_43 */
+ if (error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) {
vput(vp);
return (error);
}
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+ if (!strcmp(vfsp->vfc_name, fstypename))
+ break;
+ if (vfsp == NULL) {
+ vput(vp);
+ return (ENODEV);
+ }
if (vp->v_mountedhere != NULL) {
- vfs_unlock(mp);
- free((caddr_t)mp, M_MOUNT);
vput(vp);
return (EBUSY);
}
+
+ /*
+ * Allocate and initialize the filesystem.
+ */
+ mp = (struct mount *)malloc((u_long)sizeof(struct mount),
+ M_MOUNT, M_WAITOK);
+ bzero((char *)mp, (u_long)sizeof(struct mount));
+ lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
+ (void)vfs_busy(mp, LK_NOWAIT, 0, p);
+ mp->mnt_op = vfsp->vfc_vfsops;
+ mp->mnt_vfc = vfsp;
+ vfsp->vfc_refcount++;
+ mp->mnt_stat.f_type = vfsp->vfc_typenum;
+ mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
+ strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
vp->v_mountedhere = mp;
mp->mnt_vnodecovered = vp;
+ mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
update:
/*
* Set the mount level flags.
*/
- if (uap->flags & MNT_RDONLY)
+ if (SCARG(uap, flags) & MNT_RDONLY)
mp->mnt_flag |= MNT_RDONLY;
else if (mp->mnt_flag & MNT_RDONLY)
mp->mnt_flag |= MNT_WANTRDWR;
mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC);
- mp->mnt_flag |= uap->flags & (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
- MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC);
+ mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
+ MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC);
/*
* Mount the filesystem.
*/
- error = VFS_MOUNT(mp, uap->path, uap->data, &nd, p);
+ error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p);
if (mp->mnt_flag & MNT_UPDATE) {
vrele(vp);
if (mp->mnt_flag & MNT_WANTRDWR)
@@ -169,6 +243,7 @@ update:
(MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_WANTRDWR);
if (error)
mp->mnt_flag = flag;
+ vfs_unbusy(mp, p);
return (error);
}
/*
@@ -176,13 +251,18 @@ update:
*/
cache_purge(vp);
if (!error) {
- TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- VOP_UNLOCK(vp);
- vfs_unlock(mp);
- error = VFS_START(mp, 0, p);
+ simple_lock(&mountlist_slock);
+ CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
+ simple_unlock(&mountlist_slock);
+ checkdirs(vp);
+ VOP_UNLOCK(vp, 0, p);
+ vfs_unbusy(mp, p);
+ if (error = VFS_START(mp, 0, p))
+ vrele(vp);
} else {
mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
- vfs_unlock(mp);
+ mp->mnt_vfc->vfc_refcount--;
+ vfs_unbusy(mp, p);
free((caddr_t)mp, M_MOUNT);
vput(vp);
}
@@ -190,56 +270,104 @@ update:
}
/*
+ * Scan all active processes to see if any of them have a current
+ * or root directory onto which the new filesystem has just been
+ * mounted. If so, replace them with the new mount point.
+ */
+static void
+checkdirs(olddp)
+ struct vnode *olddp;
+{
+ struct filedesc *fdp;
+ struct vnode *newdp;
+ struct proc *p;
+
+ if (olddp->v_usecount == 1)
+ return;
+ if (VFS_ROOT(olddp->v_mountedhere, &newdp))
+ panic("mount: lost mount");
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
+ fdp = p->p_fd;
+ if (fdp->fd_cdir == olddp) {
+ vrele(fdp->fd_cdir);
+ VREF(newdp);
+ fdp->fd_cdir = newdp;
+ }
+ if (fdp->fd_rdir == olddp) {
+ vrele(fdp->fd_rdir);
+ VREF(newdp);
+ fdp->fd_rdir = newdp;
+ }
+ }
+ if (rootvnode == olddp) {
+ vrele(rootvnode);
+ VREF(newdp);
+ rootvnode = newdp;
+ }
+ vput(newdp);
+}
+
+/*
* Unmount a file system.
*
* Note: unmount takes a path to the vnode mounted on as argument,
* not special file (as before).
*/
-struct unmount_args {
- char *path;
- int flags;
-};
/* ARGSUSED */
+int
unmount(p, uap, retval)
struct proc *p;
- register struct unmount_args *uap;
- int *retval;
+ register struct unmount_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct mount *mp;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
+ mp = vp->v_mount;
/*
- * Unless this is a user mount, then must
- * have suser privilege.
+ * Only root, or the user that did the original mount is
+ * permitted to unmount this filesystem.
*/
- if (((vp->v_mount->mnt_flag & MNT_USER) == 0) &&
+ if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) &&
(error = suser(p->p_ucred, &p->p_acflag))) {
vput(vp);
return (error);
}
/*
+ * Don't allow unmounting the root file system.
+ */
+ if (mp->mnt_flag & MNT_ROOTFS) {
+ vput(vp);
+ return (EINVAL);
+ }
+
+ /*
* Must be the root of the filesystem
*/
if ((vp->v_flag & VROOT) == 0) {
vput(vp);
return (EINVAL);
}
- mp = vp->v_mount;
vput(vp);
- return (dounmount(mp, uap->flags, p));
+ return (dounmount(mp, SCARG(uap, flags), p));
}
/*
* Do the actual file system unmount.
*/
+int
dounmount(mp, flags, p)
register struct mount *mp;
int flags;
@@ -248,71 +376,74 @@ dounmount(mp, flags, p)
struct vnode *coveredvp;
int error;
- coveredvp = mp->mnt_vnodecovered;
- if (vfs_busy(mp))
- return (EBUSY);
+ simple_lock(&mountlist_slock);
mp->mnt_flag |= MNT_UNMOUNT;
- if (error = vfs_lock(mp))
- return (error);
-
+ lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock, p);
mp->mnt_flag &=~ MNT_ASYNC;
vnode_pager_umount(mp); /* release cached vnodes */
cache_purgevfs(mp); /* remove cache entries for this file sys */
- if ((error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0 ||
+ if (((mp->mnt_flag & MNT_RDONLY) ||
+ (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) ||
(flags & MNT_FORCE))
error = VFS_UNMOUNT(mp, flags, p);
- mp->mnt_flag &= ~MNT_UNMOUNT;
- vfs_unbusy(mp);
+ simple_lock(&mountlist_slock);
if (error) {
- vfs_unlock(mp);
- } else {
+ mp->mnt_flag &= ~MNT_UNMOUNT;
+ lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
+ &mountlist_slock, p);
+ return (error);
+ }
+ CIRCLEQ_REMOVE(&mountlist, mp, mnt_list);
+ if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {
+ coveredvp->v_mountedhere = (struct mount *)0;
vrele(coveredvp);
- TAILQ_REMOVE(&mountlist, mp, mnt_list);
- mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
- vfs_unlock(mp);
- if (mp->mnt_vnodelist.lh_first != NULL)
- panic("unmount: dangling vnode");
- free((caddr_t)mp, M_MOUNT);
}
- return (error);
+ mp->mnt_vfc->vfc_refcount--;
+ if (mp->mnt_vnodelist.lh_first != NULL)
+ panic("unmount: dangling vnode");
+ lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p);
+ if (mp->mnt_flag & MNT_MWAIT)
+ wakeup((caddr_t)mp);
+ free((caddr_t)mp, M_MOUNT);
+ return (0);
}
/*
* Sync each mounted filesystem.
*/
-#ifdef DIAGNOSTIC
+#ifdef DEBUG
int syncprt = 0;
struct ctldebug debug0 = { "syncprt", &syncprt };
#endif
-struct sync_args {
- int dummy;
-};
/* ARGSUSED */
+int
sync(p, uap, retval)
struct proc *p;
- struct sync_args *uap;
- int *retval;
+ void *uap;
+ register_t *retval;
{
register struct mount *mp, *nmp;
int asyncflag;
- for (mp = mountlist.tqh_first; mp != NULL; mp = nmp) {
- nmp = mp->mnt_list.tqe_next;
- /*
- * The lock check below is to avoid races with mount
- * and unmount.
- */
- if ((mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 &&
- !vfs_busy(mp)) {
+ simple_lock(&mountlist_slock);
+ for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
+ if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
+ nmp = mp->mnt_list.cqe_next;
+ continue;
+ }
+ if ((mp->mnt_flag & MNT_RDONLY) == 0) {
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);
if (asyncflag)
mp->mnt_flag |= MNT_ASYNC;
- vfs_unbusy(mp);
}
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
}
+ simple_unlock(&mountlist_slock);
#ifdef DIAGNOSTIC
if (syncprt)
vfs_bufstats();
@@ -323,49 +454,50 @@ sync(p, uap, retval)
/*
* Change filesystem quotas.
*/
-struct quotactl_args {
- char *path;
- int cmd;
- int uid;
- caddr_t arg;
-};
/* ARGSUSED */
+int
quotactl(p, uap, retval)
struct proc *p;
- register struct quotactl_args *uap;
- int *retval;
+ register struct quotactl_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) cmd;
+ syscallarg(int) uid;
+ syscallarg(caddr_t) arg;
+ } */ *uap;
+ register_t *retval;
{
register struct mount *mp;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
mp = nd.ni_vp->v_mount;
vrele(nd.ni_vp);
- return (VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, p));
+ return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
+ SCARG(uap, arg), p));
}
/*
* Get filesystem statistics.
*/
-struct statfs_args {
- char *path;
- struct statfs *buf;
-};
/* ARGSUSED */
+int
statfs(p, uap, retval)
struct proc *p;
- register struct statfs_args *uap;
- int *retval;
+ register struct statfs_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct statfs *) buf;
+ } */ *uap;
+ register_t *retval;
{
register struct mount *mp;
register struct statfs *sp;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
mp = nd.ni_vp->v_mount;
@@ -374,77 +506,89 @@ statfs(p, uap, retval)
if (error = VFS_STATFS(mp, sp, p))
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
+ return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
}
/*
* Get filesystem statistics.
*/
-struct fstatfs_args {
- int fd;
- struct statfs *buf;
-};
/* ARGSUSED */
+int
fstatfs(p, uap, retval)
struct proc *p;
- register struct fstatfs_args *uap;
- int *retval;
+ register struct fstatfs_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct statfs *) buf;
+ } */ *uap;
+ register_t *retval;
{
struct file *fp;
struct mount *mp;
register struct statfs *sp;
int error;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
mp = ((struct vnode *)fp->f_data)->v_mount;
sp = &mp->mnt_stat;
if (error = VFS_STATFS(mp, sp, p))
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
+ return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
}
/*
* Get statistics on all filesystems.
*/
-struct getfsstat_args {
- struct statfs *buf;
- long bufsize;
- int flags;
-};
+int
getfsstat(p, uap, retval)
struct proc *p;
- register struct getfsstat_args *uap;
- int *retval;
+ register struct getfsstat_args /* {
+ syscallarg(struct statfs *) buf;
+ syscallarg(long) bufsize;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
register struct mount *mp, *nmp;
register struct statfs *sp;
caddr_t sfsp;
long count, maxcount, error;
- maxcount = uap->bufsize / sizeof(struct statfs);
- sfsp = (caddr_t)uap->buf;
- for (count = 0, mp = mountlist.tqh_first; mp != NULL; mp = nmp) {
- nmp = mp->mnt_list.tqe_next;
- if (sfsp && count < maxcount &&
- ((mp->mnt_flag & MNT_MLOCK) == 0)) {
+ maxcount = SCARG(uap, bufsize) / sizeof(struct statfs);
+ sfsp = (caddr_t)SCARG(uap, buf);
+ count = 0;
+ simple_lock(&mountlist_slock);
+ for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
+ if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
+ nmp = mp->mnt_list.cqe_next;
+ continue;
+ }
+ if (sfsp && count < maxcount) {
sp = &mp->mnt_stat;
/*
* If MNT_NOWAIT is specified, do not refresh the
* fsstat cache. MNT_WAIT overrides MNT_NOWAIT.
*/
- if (((uap->flags & MNT_NOWAIT) == 0 ||
- (uap->flags & MNT_WAIT)) &&
- (error = VFS_STATFS(mp, sp, p)))
+ if (((SCARG(uap, flags) & MNT_NOWAIT) == 0 ||
+ (SCARG(uap, flags) & MNT_WAIT)) &&
+ (error = VFS_STATFS(mp, sp, p))) {
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
continue;
+ }
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
if (error = copyout((caddr_t)sp, sfsp, sizeof(*sp)))
return (error);
sfsp += sizeof(*sp);
}
count++;
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
}
+ simple_unlock(&mountlist_slock);
if (sfsp && count > maxcount)
*retval = maxcount;
else
@@ -455,32 +599,45 @@ getfsstat(p, uap, retval)
/*
* Change current working directory to a given file descriptor.
*/
-struct fchdir_args {
- int fd;
-};
/* ARGSUSED */
+int
fchdir(p, uap, retval)
struct proc *p;
- struct fchdir_args *uap;
- int *retval;
+ struct fchdir_args /* {
+ syscallarg(int) fd;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
- register struct vnode *vp;
+ struct vnode *vp, *tdp;
+ struct mount *mp;
struct file *fp;
int error;
- if (error = getvnode(fdp, uap->fd, &fp))
+ if (error = getvnode(fdp, SCARG(uap, fd), &fp))
return (error);
vp = (struct vnode *)fp->f_data;
- VOP_LOCK(vp);
+ VREF(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_type != VDIR)
error = ENOTDIR;
else
error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
- VOP_UNLOCK(vp);
- if (error)
+ while (!error && (mp = vp->v_mountedhere) != NULL) {
+ if (vfs_busy(mp, 0, 0, p))
+ continue;
+ error = VFS_ROOT(mp, &tdp);
+ vfs_unbusy(mp, p);
+ if (error)
+ break;
+ vput(vp);
+ vp = tdp;
+ }
+ if (error) {
+ vput(vp);
return (error);
- VREF(vp);
+ }
+ VOP_UNLOCK(vp, 0, p);
vrele(fdp->fd_cdir);
fdp->fd_cdir = vp;
return (0);
@@ -489,20 +646,21 @@ fchdir(p, uap, retval)
/*
* Change current working directory (``.'').
*/
-struct chdir_args {
- char *path;
-};
/* ARGSUSED */
+int
chdir(p, uap, retval)
struct proc *p;
- struct chdir_args *uap;
- int *retval;
+ struct chdir_args /* {
+ syscallarg(char *) path;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = change_dir(&nd, p))
return (error);
vrele(fdp->fd_cdir);
@@ -513,14 +671,14 @@ chdir(p, uap, retval)
/*
* Change notion of root (``/'') directory.
*/
-struct chroot_args {
- char *path;
-};
/* ARGSUSED */
+int
chroot(p, uap, retval)
struct proc *p;
- struct chroot_args *uap;
- int *retval;
+ struct chroot_args /* {
+ syscallarg(char *) path;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
int error;
@@ -528,7 +686,8 @@ chroot(p, uap, retval)
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = change_dir(&nd, p))
return (error);
if (fdp->fd_rdir != NULL)
@@ -555,9 +714,10 @@ change_dir(ndp, p)
error = ENOTDIR;
else
error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
- VOP_UNLOCK(vp);
if (error)
- vrele(vp);
+ vput(vp);
+ else
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -565,15 +725,15 @@ change_dir(ndp, p)
* Check permissions, allocate an open file structure,
* and call the device open routine if any.
*/
-struct open_args {
- char *path;
- int flags;
- int mode;
-};
+int
open(p, uap, retval)
struct proc *p;
- register struct open_args *uap;
- int *retval;
+ register struct open_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ syscallarg(int) mode;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
@@ -588,16 +748,16 @@ open(p, uap, retval)
if (error = falloc(p, &nfp, &indx))
return (error);
fp = nfp;
- flags = FFLAGS(uap->flags);
- cmode = ((uap->mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ flags = FFLAGS(SCARG(uap, flags));
+ cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
p->p_dupfd = -indx - 1; /* XXX check for fdopen */
if (error = vn_open(&nd, flags, cmode)) {
ffree(fp);
if ((error == ENODEV || error == ENXIO) &&
- p->p_dupfd >= 0 && /* XXX from fdopen */
+ p->p_dupfd >= 0 && /* XXX from fdopen */
(error =
- dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) {
+ dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) {
*retval = indx;
return (0);
}
@@ -623,17 +783,17 @@ open(p, uap, retval)
type = F_FLOCK;
if ((flags & FNONBLOCK) == 0)
type |= F_WAIT;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
if (error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) {
(void) vn_close(vp, fp->f_flag, fp->f_cred, p);
ffree(fp);
fdp->fd_ofiles[indx] = NULL;
return (error);
}
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
fp->f_flag |= FHASLOCK;
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
*retval = indx;
return (0);
}
@@ -642,46 +802,51 @@ open(p, uap, retval)
/*
* Create a file.
*/
-struct ocreat_args {
- char *path;
- int mode;
-};
-ocreat(p, uap, retval)
+int
+compat_43_creat(p, uap, retval)
struct proc *p;
- register struct ocreat_args *uap;
- int *retval;
+ register struct compat_43_creat_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap;
+ register_t *retval;
{
- struct open_args openuap;
-
- openuap.path = uap->path;
- openuap.mode = uap->mode;
- openuap.flags = O_WRONLY | O_CREAT | O_TRUNC;
- return (open(p, &openuap, retval));
+ struct open_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ syscallarg(int) mode;
+ } */ nuap;
+
+ SCARG(&nuap, path) = SCARG(uap, path);
+ SCARG(&nuap, mode) = SCARG(uap, mode);
+ SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
+ return (open(p, &nuap, retval));
}
#endif /* COMPAT_43 */
/*
* Create a special file.
*/
-struct mknod_args {
- char *path;
- int mode;
- int dev;
-};
/* ARGSUSED */
+int
mknod(p, uap, retval)
struct proc *p;
- register struct mknod_args *uap;
- int *retval;
+ register struct mknod_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ syscallarg(int) dev;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct vattr vattr;
int error;
+ int whiteout;
struct nameidata nd;
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
- NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
@@ -689,10 +854,11 @@ mknod(p, uap, retval)
error = EEXIST;
else {
VATTR_NULL(&vattr);
- vattr.va_mode = (uap->mode & ALLPERMS) &~ p->p_fd->fd_cmask;
- vattr.va_rdev = uap->dev;
+ vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
+ vattr.va_rdev = SCARG(uap, dev);
+ whiteout = 0;
- switch (uap->mode & S_IFMT) {
+ switch (SCARG(uap, mode) & S_IFMT) {
case S_IFMT: /* used by badsect to flag bad sectors */
vattr.va_type = VBAD;
break;
@@ -702,14 +868,25 @@ mknod(p, uap, retval)
case S_IFBLK:
vattr.va_type = VBLK;
break;
+ case S_IFWHT:
+ whiteout = 1;
+ break;
default:
error = EINVAL;
break;
}
}
if (!error) {
- LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
- error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ if (whiteout) {
+ error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
+ if (error)
+ VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+ vput(nd.ni_dvp);
+ } else {
+ error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
+ &nd.ni_cnd, &vattr);
+ }
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
if (nd.ni_dvp == vp)
@@ -723,17 +900,17 @@ mknod(p, uap, retval)
}
/*
- * Create named pipe.
+ * Create a named pipe.
*/
-struct mkfifo_args {
- char *path;
- int mode;
-};
/* ARGSUSED */
+int
mkfifo(p, uap, retval)
struct proc *p;
- register struct mkfifo_args *uap;
- int *retval;
+ register struct mkfifo_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap;
+ register_t *retval;
{
struct vattr vattr;
int error;
@@ -742,7 +919,7 @@ mkfifo(p, uap, retval)
#ifndef FIFO
return (EOPNOTSUPP);
#else
- NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
if (nd.ni_vp != NULL) {
@@ -756,8 +933,8 @@ mkfifo(p, uap, retval)
}
VATTR_NULL(&vattr);
vattr.va_type = VFIFO;
- vattr.va_mode = (uap->mode & ALLPERMS) &~ p->p_fd->fd_cmask;
- LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
return (VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr));
#endif /* FIFO */
}
@@ -765,21 +942,21 @@ mkfifo(p, uap, retval)
/*
* Make a hard file link.
*/
-struct link_args {
- char *path;
- char *link;
-};
/* ARGSUSED */
+int
link(p, uap, retval)
struct proc *p;
- register struct link_args *uap;
- int *retval;
+ register struct link_args /* {
+ syscallarg(char *) path;
+ syscallarg(char *) link;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct nameidata nd;
int error;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
@@ -787,16 +964,15 @@ link(p, uap, retval)
(error = suser(p->p_ucred, &p->p_acflag)) == 0) {
nd.ni_cnd.cn_nameiop = CREATE;
nd.ni_cnd.cn_flags = LOCKPARENT;
- nd.ni_dirp = uap->link;
+ nd.ni_dirp = SCARG(uap, link);
if ((error = namei(&nd)) == 0) {
if (nd.ni_vp != NULL)
error = EEXIST;
if (!error) {
- LEASE_CHECK(nd.ni_dvp,
- p, p->p_ucred, LEASE_WRITE);
- LEASE_CHECK(vp,
- p, p->p_ucred, LEASE_WRITE);
- error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred,
+ LEASE_WRITE);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ error = VOP_LINK(vp, nd.ni_dvp, &nd.ni_cnd);
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
if (nd.ni_dvp == nd.ni_vp)
@@ -815,15 +991,15 @@ link(p, uap, retval)
/*
* Make a symbolic link.
*/
-struct symlink_args {
- char *path;
- char *link;
-};
/* ARGSUSED */
+int
symlink(p, uap, retval)
struct proc *p;
- register struct symlink_args *uap;
- int *retval;
+ register struct symlink_args /* {
+ syscallarg(char *) path;
+ syscallarg(char *) link;
+ } */ *uap;
+ register_t *retval;
{
struct vattr vattr;
char *path;
@@ -831,9 +1007,9 @@ symlink(p, uap, retval)
struct nameidata nd;
MALLOC(path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
- if (error = copyinstr(uap->path, path, MAXPATHLEN, NULL))
+ if (error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL))
goto out;
- NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->link, p);
+ NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, link), p);
if (error = namei(&nd))
goto out;
if (nd.ni_vp) {
@@ -848,7 +1024,7 @@ symlink(p, uap, retval)
}
VATTR_NULL(&vattr);
vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
- LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
out:
FREE(path, M_NAMEI);
@@ -856,27 +1032,66 @@ out:
}
/*
+ * Delete a whiteout from the filesystem.
+ */
+/* ARGSUSED */
+int
+undelete(p, uap, retval)
+ struct proc *p;
+ register struct undelete_args /* {
+ syscallarg(char *) path;
+ } */ *uap;
+ register_t *retval;
+{
+ int error;
+ struct nameidata nd;
+
+ NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE,
+ SCARG(uap, path), p);
+ error = namei(&nd);
+ if (error)
+ return (error);
+
+ if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
+ VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+ if (nd.ni_dvp == nd.ni_vp)
+ vrele(nd.ni_dvp);
+ else
+ vput(nd.ni_dvp);
+ if (nd.ni_vp)
+ vrele(nd.ni_vp);
+ return (EEXIST);
+ }
+
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ if (error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE))
+ VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+ vput(nd.ni_dvp);
+ return (error);
+}
+
+/*
* Delete a name from the filesystem.
*/
-struct unlink_args {
- char *path;
-};
/* ARGSUSED */
+int
unlink(p, uap, retval)
struct proc *p;
- struct unlink_args *uap;
- int *retval;
+ struct unlink_args /* {
+ syscallarg(char *) path;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
int error;
struct nameidata nd;
- NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_type != VDIR ||
(error = suser(p->p_ucred, &p->p_acflag)) == 0) {
@@ -890,7 +1105,7 @@ unlink(p, uap, retval)
}
if (!error) {
- LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
@@ -898,7 +1113,8 @@ unlink(p, uap, retval)
vrele(nd.ni_dvp);
else
vput(nd.ni_dvp);
- vput(vp);
+ if (vp != NULLVP)
+ vput(vp);
}
return (error);
}
@@ -906,16 +1122,16 @@ unlink(p, uap, retval)
/*
* Reposition read/write file offset.
*/
-struct lseek_args {
- int fd;
- int pad;
- off_t offset;
- int whence;
-};
+int
lseek(p, uap, retval)
struct proc *p;
- register struct lseek_args *uap;
- int *retval;
+ register struct lseek_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) pad;
+ syscallarg(off_t) offset;
+ syscallarg(int) whence;
+ } */ *uap;
+ register_t *retval;
{
struct ucred *cred = p->p_ucred;
register struct filedesc *fdp = p->p_fd;
@@ -923,23 +1139,23 @@ lseek(p, uap, retval)
struct vattr vattr;
int error;
- if ((u_int)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
return (EBADF);
if (fp->f_type != DTYPE_VNODE)
return (ESPIPE);
- switch (uap->whence) {
+ switch (SCARG(uap, whence)) {
case L_INCR:
- fp->f_offset += uap->offset;
+ fp->f_offset += SCARG(uap, offset);
break;
case L_XTND:
if (error =
VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p))
return (error);
- fp->f_offset = uap->offset + vattr.va_size;
+ fp->f_offset = SCARG(uap, offset) + vattr.va_size;
break;
case L_SET:
- fp->f_offset = uap->offset;
+ fp->f_offset = SCARG(uap, offset);
break;
default:
return (EINVAL);
@@ -952,23 +1168,28 @@ lseek(p, uap, retval)
/*
* Reposition read/write file offset.
*/
-struct olseek_args {
- int fd;
- long offset;
- int whence;
-};
-olseek(p, uap, retval)
+int
+compat_43_lseek(p, uap, retval)
struct proc *p;
- register struct olseek_args *uap;
- int *retval;
+ register struct compat_43_lseek_args /* {
+ syscallarg(int) fd;
+ syscallarg(long) offset;
+ syscallarg(int) whence;
+ } */ *uap;
+ register_t *retval;
{
- struct lseek_args nuap;
+ struct lseek_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) pad;
+ syscallarg(off_t) offset;
+ syscallarg(int) whence;
+ } */ nuap;
off_t qret;
int error;
- nuap.fd = uap->fd;
- nuap.offset = uap->offset;
- nuap.whence = uap->whence;
+ SCARG(&nuap, fd) = SCARG(uap, fd);
+ SCARG(&nuap, offset) = SCARG(uap, offset);
+ SCARG(&nuap, whence) = SCARG(uap, whence);
error = lseek(p, &nuap, &qret);
*(long *)retval = qret;
return (error);
@@ -978,14 +1199,14 @@ olseek(p, uap, retval)
/*
* Check access permissions.
*/
-struct access_args {
- char *path;
- int flags;
-};
+int
access(p, uap, retval)
struct proc *p;
- register struct access_args *uap;
- int *retval;
+ register struct access_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
register struct ucred *cred = p->p_ucred;
register struct vnode *vp;
@@ -996,19 +1217,20 @@ access(p, uap, retval)
t_gid = cred->cr_groups[0];
cred->cr_uid = p->p_cred->p_ruid;
cred->cr_groups[0] = p->p_cred->p_rgid;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
goto out1;
vp = nd.ni_vp;
/* Flags == 0 means only check for existence. */
- if (uap->flags) {
+ if (SCARG(uap, flags)) {
flags = 0;
- if (uap->flags & R_OK)
+ if (SCARG(uap, flags) & R_OK)
flags |= VREAD;
- if (uap->flags & W_OK)
+ if (SCARG(uap, flags) & W_OK)
flags |= VWRITE;
- if (uap->flags & X_OK)
+ if (SCARG(uap, flags) & X_OK)
flags |= VEXEC;
if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
error = VOP_ACCESS(vp, flags, cred, p);
@@ -1024,22 +1246,23 @@ out1:
/*
* Get file status; this version follows links.
*/
-struct ostat_args {
- char *path;
- struct ostat *ub;
-};
/* ARGSUSED */
-ostat(p, uap, retval)
+int
+compat_43_stat(p, uap, retval)
struct proc *p;
- register struct ostat_args *uap;
- int *retval;
+ register struct compat_43_stat_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct ostat *) ub;
+ } */ *uap;
+ register_t *retval;
{
struct stat sb;
struct ostat osb;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
error = vn_stat(nd.ni_vp, &sb, p);
@@ -1047,43 +1270,74 @@ ostat(p, uap, retval)
if (error)
return (error);
cvtstat(&sb, &osb);
- error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb));
+ error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
return (error);
}
/*
* Get file status; this version does not follow links.
*/
-struct olstat_args {
- char *path;
- struct ostat *ub;
-};
/* ARGSUSED */
-olstat(p, uap, retval)
+int
+compat_43_lstat(p, uap, retval)
struct proc *p;
- register struct olstat_args *uap;
- int *retval;
+ register struct compat_43_lstat_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct ostat *) ub;
+ } */ *uap;
+ register_t *retval;
{
- struct stat sb;
+ struct vnode *vp, *dvp;
+ struct stat sb, sb1;
struct ostat osb;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
- error = vn_stat(nd.ni_vp, &sb, p);
- vput(nd.ni_vp);
- if (error)
- return (error);
+ /*
+ * For symbolic links, always return the attributes of its
+ * containing directory, except for mode, size, and links.
+ */
+ vp = nd.ni_vp;
+ dvp = nd.ni_dvp;
+ if (vp->v_type != VLNK) {
+ if (dvp == vp)
+ vrele(dvp);
+ else
+ vput(dvp);
+ error = vn_stat(vp, &sb, p);
+ vput(vp);
+ if (error)
+ return (error);
+ } else {
+ error = vn_stat(dvp, &sb, p);
+ vput(dvp);
+ if (error) {
+ vput(vp);
+ return (error);
+ }
+ error = vn_stat(vp, &sb1, p);
+ vput(vp);
+ if (error)
+ return (error);
+ sb.st_mode &= ~S_IFDIR;
+ sb.st_mode |= S_IFLNK;
+ sb.st_nlink = sb1.st_nlink;
+ sb.st_size = sb1.st_size;
+ sb.st_blocks = sb1.st_blocks;
+ }
cvtstat(&sb, &osb);
- error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb));
+ error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
return (error);
}
/*
* Convert from an old to a new stat structure.
*/
+void
cvtstat(st, ost)
struct stat *st;
struct ostat *ost;
@@ -1113,43 +1367,44 @@ cvtstat(st, ost)
/*
* Get file status; this version follows links.
*/
-struct stat_args {
- char *path;
- struct stat *ub;
-};
/* ARGSUSED */
+int
stat(p, uap, retval)
struct proc *p;
- register struct stat_args *uap;
- int *retval;
+ register struct stat_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct stat *) ub;
+ } */ *uap;
+ register_t *retval;
{
struct stat sb;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
error = vn_stat(nd.ni_vp, &sb, p);
vput(nd.ni_vp);
if (error)
return (error);
- error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
+ error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
return (error);
}
/*
* Get file status; this version does not follow links.
*/
-struct lstat_args {
- char *path;
- struct stat *ub;
-};
/* ARGSUSED */
+int
lstat(p, uap, retval)
struct proc *p;
- register struct lstat_args *uap;
- int *retval;
+ register struct lstat_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct stat *) ub;
+ } */ *uap;
+ register_t *retval;
{
int error;
struct vnode *vp, *dvp;
@@ -1157,12 +1412,12 @@ lstat(p, uap, retval)
struct nameidata nd;
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
- uap->path, p);
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
/*
- * For symbolic links, always return the attributes of its
- * containing directory, except for mode, size, and links.
+ * For symbolic links, always return the attributes of its containing
+ * directory, except for mode, size, inode number, and links.
*/
vp = nd.ni_vp;
dvp = nd.ni_dvp;
@@ -1191,31 +1446,33 @@ lstat(p, uap, retval)
sb.st_nlink = sb1.st_nlink;
sb.st_size = sb1.st_size;
sb.st_blocks = sb1.st_blocks;
+ sb.st_ino = sb1.st_ino;
}
- error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
+ error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
return (error);
}
/*
* Get configurable pathname variables.
*/
-struct pathconf_args {
- char *path;
- int name;
-};
/* ARGSUSED */
+int
pathconf(p, uap, retval)
struct proc *p;
- register struct pathconf_args *uap;
- int *retval;
+ register struct pathconf_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) name;
+ } */ *uap;
+ register_t *retval;
{
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
- error = VOP_PATHCONF(nd.ni_vp, uap->name, retval);
+ error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), retval);
vput(nd.ni_vp);
return (error);
}
@@ -1223,16 +1480,16 @@ pathconf(p, uap, retval)
/*
* Return target name of a symbolic link.
*/
-struct readlink_args {
- char *path;
- char *buf;
- int count;
-};
/* ARGSUSED */
+int
readlink(p, uap, retval)
struct proc *p;
- register struct readlink_args *uap;
- int *retval;
+ register struct readlink_args /* {
+ syscallarg(char *) path;
+ syscallarg(char *) buf;
+ syscallarg(int) count;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct iovec aiov;
@@ -1240,60 +1497,57 @@ readlink(p, uap, retval)
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
if (vp->v_type != VLNK)
error = EINVAL;
else {
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->count;
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, count);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
- auio.uio_resid = uap->count;
+ auio.uio_resid = SCARG(uap, count);
error = VOP_READLINK(vp, &auio, p->p_ucred);
}
vput(vp);
- *retval = uap->count - auio.uio_resid;
+ *retval = SCARG(uap, count) - auio.uio_resid;
return (error);
}
/*
* Change flags of a file given a path name.
*/
-struct chflags_args {
- char *path;
- int flags;
-};
/* ARGSUSED */
+int
chflags(p, uap, retval)
struct proc *p;
- register struct chflags_args *uap;
- int *retval;
+ register struct chflags_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct vattr vattr;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- VATTR_NULL(&vattr);
- vattr.va_flags = uap->flags;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ VATTR_NULL(&vattr);
+ vattr.va_flags = SCARG(uap, flags);
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
vput(vp);
return (error);
}
@@ -1301,68 +1555,60 @@ chflags(p, uap, retval)
/*
* Change flags of a file given a file descriptor.
*/
-struct fchflags_args {
- int fd;
- int flags;
-};
/* ARGSUSED */
+int
fchflags(p, uap, retval)
struct proc *p;
- register struct fchflags_args *uap;
- int *retval;
+ register struct fchflags_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) flags;
+ } */ *uap;
+ register_t *retval;
{
struct vattr vattr;
struct vnode *vp;
struct file *fp;
int error;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
vp = (struct vnode *)fp->f_data;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- VATTR_NULL(&vattr);
- vattr.va_flags = uap->flags;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
- VOP_UNLOCK(vp);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ VATTR_NULL(&vattr);
+ vattr.va_flags = SCARG(uap, flags);
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
/*
* Change mode of a file given path name.
*/
-struct chmod_args {
- char *path;
- int mode;
-};
/* ARGSUSED */
+int
chmod(p, uap, retval)
struct proc *p;
- register struct chmod_args *uap;
- int *retval;
+ register struct chmod_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct vattr vattr;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- VATTR_NULL(&vattr);
- vattr.va_mode = uap->mode & ALLPERMS;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ VATTR_NULL(&vattr);
+ vattr.va_mode = SCARG(uap, mode) & ALLPERMS;
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
vput(vp);
return (error);
}
@@ -1370,70 +1616,62 @@ chmod(p, uap, retval)
/*
* Change mode of a file given a file descriptor.
*/
-struct fchmod_args {
- int fd;
- int mode;
-};
/* ARGSUSED */
+int
fchmod(p, uap, retval)
struct proc *p;
- register struct fchmod_args *uap;
- int *retval;
+ register struct fchmod_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) mode;
+ } */ *uap;
+ register_t *retval;
{
struct vattr vattr;
struct vnode *vp;
struct file *fp;
int error;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
vp = (struct vnode *)fp->f_data;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- VATTR_NULL(&vattr);
- vattr.va_mode = uap->mode & ALLPERMS;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
- VOP_UNLOCK(vp);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ VATTR_NULL(&vattr);
+ vattr.va_mode = SCARG(uap, mode) & ALLPERMS;
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
/*
* Set ownership given a path name.
*/
-struct chown_args {
- char *path;
- int uid;
- int gid;
-};
/* ARGSUSED */
+int
chown(p, uap, retval)
struct proc *p;
- register struct chown_args *uap;
- int *retval;
+ register struct chown_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) uid;
+ syscallarg(int) gid;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct vattr vattr;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- VATTR_NULL(&vattr);
- vattr.va_uid = uap->uid;
- vattr.va_gid = uap->gid;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ VATTR_NULL(&vattr);
+ vattr.va_uid = SCARG(uap, uid);
+ vattr.va_gid = SCARG(uap, gid);
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
vput(vp);
return (error);
}
@@ -1441,51 +1679,47 @@ chown(p, uap, retval)
/*
* Set ownership given a file descriptor.
*/
-struct fchown_args {
- int fd;
- int uid;
- int gid;
-};
/* ARGSUSED */
+int
fchown(p, uap, retval)
struct proc *p;
- register struct fchown_args *uap;
- int *retval;
+ register struct fchown_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) uid;
+ syscallarg(int) gid;
+ } */ *uap;
+ register_t *retval;
{
struct vattr vattr;
struct vnode *vp;
struct file *fp;
int error;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
vp = (struct vnode *)fp->f_data;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- VATTR_NULL(&vattr);
- vattr.va_uid = uap->uid;
- vattr.va_gid = uap->gid;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
- VOP_UNLOCK(vp);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ VATTR_NULL(&vattr);
+ vattr.va_uid = SCARG(uap, uid);
+ vattr.va_gid = SCARG(uap, gid);
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
/*
* Set the access and modification times of a file.
*/
-struct utimes_args {
- char *path;
- struct timeval *tptr;
-};
/* ARGSUSED */
+int
utimes(p, uap, retval)
struct proc *p;
- register struct utimes_args *uap;
- int *retval;
+ register struct utimes_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct timeval *) tptr;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct timeval tv[2];
@@ -1494,27 +1728,24 @@ utimes(p, uap, retval)
struct nameidata nd;
VATTR_NULL(&vattr);
- if (uap->tptr == NULL) {
+ if (SCARG(uap, tptr) == NULL) {
microtime(&tv[0]);
tv[1] = tv[0];
vattr.va_vaflags |= VA_UTIMES_NULL;
- } else if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)))
+ } else if (error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv,
+ sizeof (tv)))
return (error);
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- vattr.va_atime.ts_sec = tv[0].tv_sec;
- vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
- vattr.va_mtime.ts_sec = tv[1].tv_sec;
- vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ vattr.va_atime.ts_sec = tv[0].tv_sec;
+ vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
+ vattr.va_mtime.ts_sec = tv[1].tv_sec;
+ vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
vput(vp);
return (error);
}
@@ -1522,34 +1753,34 @@ utimes(p, uap, retval)
/*
* Truncate a file given its path name.
*/
-struct truncate_args {
- char *path;
- int pad;
- off_t length;
-};
/* ARGSUSED */
+int
truncate(p, uap, retval)
struct proc *p;
- register struct truncate_args *uap;
- int *retval;
+ register struct truncate_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) pad;
+ syscallarg(off_t) length;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct vattr vattr;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_type == VDIR)
error = EISDIR;
else if ((error = vn_writechk(vp)) == 0 &&
(error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0) {
VATTR_NULL(&vattr);
- vattr.va_size = uap->length;
+ vattr.va_size = SCARG(uap, length);
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
}
vput(vp);
@@ -1559,37 +1790,37 @@ truncate(p, uap, retval)
/*
* Truncate a file given a file descriptor.
*/
-struct ftruncate_args {
- int fd;
- int pad;
- off_t length;
-};
/* ARGSUSED */
+int
ftruncate(p, uap, retval)
struct proc *p;
- register struct ftruncate_args *uap;
- int *retval;
+ register struct ftruncate_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) pad;
+ syscallarg(off_t) length;
+ } */ *uap;
+ register_t *retval;
{
struct vattr vattr;
struct vnode *vp;
struct file *fp;
int error;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
if ((fp->f_flag & FWRITE) == 0)
return (EINVAL);
vp = (struct vnode *)fp->f_data;
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_type == VDIR)
error = EISDIR;
else if ((error = vn_writechk(vp)) == 0) {
VATTR_NULL(&vattr);
- vattr.va_size = uap->length;
+ vattr.va_size = SCARG(uap, length);
error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -1597,40 +1828,48 @@ ftruncate(p, uap, retval)
/*
* Truncate a file given its path name.
*/
-struct otruncate_args {
- char *path;
- long length;
-};
/* ARGSUSED */
-otruncate(p, uap, retval)
+int
+compat_43_truncate(p, uap, retval)
struct proc *p;
- register struct otruncate_args *uap;
- int *retval;
+ register struct compat_43_truncate_args /* {
+ syscallarg(char *) path;
+ syscallarg(long) length;
+ } */ *uap;
+ register_t *retval;
{
- struct truncate_args nuap;
-
- nuap.path = uap->path;
- nuap.length = uap->length;
+ struct truncate_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) pad;
+ syscallarg(off_t) length;
+ } */ nuap;
+
+ SCARG(&nuap, path) = SCARG(uap, path);
+ SCARG(&nuap, length) = SCARG(uap, length);
return (truncate(p, &nuap, retval));
}
/*
* Truncate a file given a file descriptor.
*/
-struct oftruncate_args {
- int fd;
- long length;
-};
/* ARGSUSED */
-oftruncate(p, uap, retval)
+int
+compat_43_ftruncate(p, uap, retval)
struct proc *p;
- register struct oftruncate_args *uap;
- int *retval;
+ register struct compat_43_ftruncate_args /* {
+ syscallarg(int) fd;
+ syscallarg(long) length;
+ } */ *uap;
+ register_t *retval;
{
- struct ftruncate_args nuap;
-
- nuap.fd = uap->fd;
- nuap.length = uap->length;
+ struct ftruncate_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) pad;
+ syscallarg(off_t) length;
+ } */ nuap;
+
+ SCARG(&nuap, fd) = SCARG(uap, fd);
+ SCARG(&nuap, length) = SCARG(uap, length);
return (ftruncate(p, &nuap, retval));
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
@@ -1638,25 +1877,25 @@ oftruncate(p, uap, retval)
/*
* Sync an open file.
*/
-struct fsync_args {
- int fd;
-};
/* ARGSUSED */
+int
fsync(p, uap, retval)
struct proc *p;
- struct fsync_args *uap;
- int *retval;
+ struct fsync_args /* {
+ syscallarg(int) fd;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct file *fp;
int error;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
vp = (struct vnode *)fp->f_data;
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -1664,27 +1903,27 @@ fsync(p, uap, retval)
* Rename files. Source and destination must either both be directories,
* or both not be directories. If target is a directory, it must be empty.
*/
-struct rename_args {
- char *from;
- char *to;
-};
/* ARGSUSED */
+int
rename(p, uap, retval)
struct proc *p;
- register struct rename_args *uap;
- int *retval;
+ register struct rename_args /* {
+ syscallarg(char *) from;
+ syscallarg(char *) to;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *tvp, *fvp, *tdvp;
struct nameidata fromnd, tond;
int error;
NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
- uap->from, p);
+ SCARG(uap, from), p);
if (error = namei(&fromnd))
return (error);
fvp = fromnd.ni_vp;
NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART,
- UIO_USERSPACE, uap->to, p);
+ UIO_USERSPACE, SCARG(uap, to), p);
if (error = namei(&tond)) {
VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
vrele(fromnd.ni_dvp);
@@ -1716,11 +1955,11 @@ rename(p, uap, retval)
error = -1;
out:
if (!error) {
- LEASE_CHECK(tdvp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(tdvp, p, p->p_ucred, LEASE_WRITE);
if (fromnd.ni_dvp != tdvp)
- LEASE_CHECK(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
if (tvp)
- LEASE_CHECK(tvp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(tvp, p, p->p_ucred, LEASE_WRITE);
error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
} else {
@@ -1749,22 +1988,22 @@ out1:
/*
* Make a directory file.
*/
-struct mkdir_args {
- char *path;
- int mode;
-};
/* ARGSUSED */
+int
mkdir(p, uap, retval)
struct proc *p;
- register struct mkdir_args *uap;
- int *retval;
+ register struct mkdir_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct vattr vattr;
int error;
struct nameidata nd;
- NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
@@ -1779,8 +2018,8 @@ mkdir(p, uap, retval)
}
VATTR_NULL(&vattr);
vattr.va_type = VDIR;
- vattr.va_mode = (uap->mode & ACCESSPERMS) &~ p->p_fd->fd_cmask;
- LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask;
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
if (!error)
vput(nd.ni_vp);
@@ -1790,20 +2029,21 @@ mkdir(p, uap, retval)
/*
* Remove a directory file.
*/
-struct rmdir_args {
- char *path;
-};
/* ARGSUSED */
+int
rmdir(p, uap, retval)
struct proc *p;
- struct rmdir_args *uap;
- int *retval;
+ struct rmdir_args /* {
+ syscallarg(char *) path;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
int error;
struct nameidata nd;
- NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
@@ -1825,8 +2065,8 @@ rmdir(p, uap, retval)
error = EBUSY;
out:
if (!error) {
- LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
- LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
@@ -1843,16 +2083,16 @@ out:
/*
* Read a block of directory entries in a file system independent format.
*/
-struct ogetdirentries_args {
- int fd;
- char *buf;
- u_int count;
- long *basep;
-};
-ogetdirentries(p, uap, retval)
+int
+compat_43_getdirentries(p, uap, retval)
struct proc *p;
- register struct ogetdirentries_args *uap;
- int *retval;
+ register struct compat_43_getdirentries_args /* {
+ syscallarg(int) fd;
+ syscallarg(char *) buf;
+ syscallarg(u_int) count;
+ syscallarg(long *) basep;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct file *fp;
@@ -1860,29 +2100,31 @@ ogetdirentries(p, uap, retval)
struct iovec aiov, kiov;
struct dirent *dp, *edp;
caddr_t dirbuf;
- int error, readcnt;
+ int error, eofflag, readcnt;
long loff;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
if ((fp->f_flag & FREAD) == 0)
return (EBADF);
vp = (struct vnode *)fp->f_data;
+unionread:
if (vp->v_type != VDIR)
return (EINVAL);
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->count;
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, count);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
- auio.uio_resid = uap->count;
- VOP_LOCK(vp);
+ auio.uio_resid = SCARG(uap, count);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
loff = auio.uio_offset = fp->f_offset;
# if (BYTE_ORDER != LITTLE_ENDIAN)
if (vp->v_mount->mnt_maxsymlinklen <= 0) {
- error = VOP_READDIR(vp, &auio, fp->f_cred);
+ error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
+ (int *)0, (u_long *)0);
fp->f_offset = auio.uio_offset;
} else
# endif
@@ -1890,13 +2132,14 @@ ogetdirentries(p, uap, retval)
kuio = auio;
kuio.uio_iov = &kiov;
kuio.uio_segflg = UIO_SYSSPACE;
- kiov.iov_len = uap->count;
- MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK);
+ kiov.iov_len = SCARG(uap, count);
+ MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK);
kiov.iov_base = dirbuf;
- error = VOP_READDIR(vp, &kuio, fp->f_cred);
+ error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
+ (int *)0, (u_long *)0);
fp->f_offset = kuio.uio_offset;
if (error == 0) {
- readcnt = uap->count - kuio.uio_resid;
+ readcnt = SCARG(uap, count) - kuio.uio_resid;
edp = (struct dirent *)&dirbuf[readcnt];
for (dp = (struct dirent *)dirbuf; dp < edp; ) {
# if (BYTE_ORDER == LITTLE_ENDIAN)
@@ -1929,37 +2172,93 @@ ogetdirentries(p, uap, retval)
}
FREE(dirbuf, M_TEMP);
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
if (error)
return (error);
- error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long));
- *retval = uap->count - auio.uio_resid;
+
+#ifdef UNION
+{
+ extern int (**union_vnodeop_p)();
+ extern struct vnode *union_dircache __P((struct vnode*, struct proc*));
+
+ if ((SCARG(uap, count) == auio.uio_resid) &&
+ (vp->v_op == union_vnodeop_p)) {
+ struct vnode *lvp;
+
+ lvp = union_dircache(vp, p);
+ if (lvp != NULLVP) {
+ struct vattr va;
+
+ /*
+ * If the directory is opaque,
+ * then don't show lower entries
+ */
+ error = VOP_GETATTR(vp, &va, fp->f_cred, p);
+ if (va.va_flags & OPAQUE) {
+ vput(lvp);
+ lvp = NULL;
+ }
+ }
+
+ if (lvp != NULLVP) {
+ error = VOP_OPEN(lvp, FREAD, fp->f_cred, p);
+ if (error) {
+ vput(lvp);
+ return (error);
+ }
+ VOP_UNLOCK(lvp, 0, p);
+ fp->f_data = (caddr_t) lvp;
+ fp->f_offset = 0;
+ error = vn_close(vp, FREAD, fp->f_cred, p);
+ if (error)
+ return (error);
+ vp = lvp;
+ goto unionread;
+ }
+ }
+}
+#endif /* UNION */
+
+ if ((SCARG(uap, count) == auio.uio_resid) &&
+ (vp->v_flag & VROOT) &&
+ (vp->v_mount->mnt_flag & MNT_UNION)) {
+ struct vnode *tvp = vp;
+ vp = vp->v_mount->mnt_vnodecovered;
+ VREF(vp);
+ fp->f_data = (caddr_t) vp;
+ fp->f_offset = 0;
+ vrele(tvp);
+ goto unionread;
+ }
+ error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
+ sizeof(long));
+ *retval = SCARG(uap, count) - auio.uio_resid;
return (error);
}
-#endif
+#endif /* COMPAT_43 */
/*
* Read a block of directory entries in a file system independent format.
*/
-struct getdirentries_args {
- int fd;
- char *buf;
- u_int count;
- long *basep;
-};
+int
getdirentries(p, uap, retval)
struct proc *p;
- register struct getdirentries_args *uap;
- int *retval;
+ register struct getdirentries_args /* {
+ syscallarg(int) fd;
+ syscallarg(char *) buf;
+ syscallarg(u_int) count;
+ syscallarg(long *) basep;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct file *fp;
struct uio auio;
struct iovec aiov;
long loff;
- int error;
+ int error, eofflag;
- if (error = getvnode(p->p_fd, uap->fd, &fp))
+ if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
if ((fp->f_flag & FREAD) == 0)
return (EBADF);
@@ -1967,53 +2266,67 @@ getdirentries(p, uap, retval)
unionread:
if (vp->v_type != VDIR)
return (EINVAL);
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->count;
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, count);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
- auio.uio_resid = uap->count;
- VOP_LOCK(vp);
+ auio.uio_resid = SCARG(uap, count);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
loff = auio.uio_offset = fp->f_offset;
- error = VOP_READDIR(vp, &auio, fp->f_cred);
+ error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
+ (int *)0, (u_long *)0);
fp->f_offset = auio.uio_offset;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
if (error)
return (error);
#ifdef UNION
{
extern int (**union_vnodeop_p)();
- extern struct vnode *union_lowervp __P((struct vnode *));
+ extern struct vnode *union_dircache __P((struct vnode*, struct proc*));
- if ((uap->count == auio.uio_resid) &&
+ if ((SCARG(uap, count) == auio.uio_resid) &&
(vp->v_op == union_vnodeop_p)) {
- struct vnode *tvp = vp;
+ struct vnode *lvp;
+
+ lvp = union_dircache(vp, p);
+ if (lvp != NULLVP) {
+ struct vattr va;
- vp = union_lowervp(vp);
- if (vp != NULLVP) {
- VOP_LOCK(vp);
- error = VOP_OPEN(vp, FREAD);
- VOP_UNLOCK(vp);
+ /*
+ * If the directory is opaque,
+ * then don't show lower entries
+ */
+ error = VOP_GETATTR(vp, &va, fp->f_cred, p);
+ if (va.va_flags & OPAQUE) {
+ vput(lvp);
+ lvp = NULL;
+ }
+ }
+ if (lvp != NULLVP) {
+ error = VOP_OPEN(lvp, FREAD, fp->f_cred, p);
if (error) {
- vrele(vp);
+ vput(lvp);
return (error);
}
- fp->f_data = (caddr_t) vp;
+ VOP_UNLOCK(lvp, 0, p);
+ fp->f_data = (caddr_t) lvp;
fp->f_offset = 0;
- error = vn_close(tvp, FREAD, fp->f_cred, p);
+ error = vn_close(vp, FREAD, fp->f_cred, p);
if (error)
return (error);
+ vp = lvp;
goto unionread;
}
}
}
-#endif
+#endif /* UNION */
- if ((uap->count == auio.uio_resid) &&
+ if ((SCARG(uap, count) == auio.uio_resid) &&
(vp->v_flag & VROOT) &&
(vp->v_mount->mnt_flag & MNT_UNION)) {
struct vnode *tvp = vp;
@@ -2024,28 +2337,28 @@ unionread:
vrele(tvp);
goto unionread;
}
- error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long));
- *retval = uap->count - auio.uio_resid;
+ error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
+ sizeof(long));
+ *retval = SCARG(uap, count) - auio.uio_resid;
return (error);
}
/*
* Set the mode mask for creation of filesystem nodes.
*/
-struct umask_args {
- int newmask;
-};
-mode_t /* XXX */
+int
umask(p, uap, retval)
struct proc *p;
- struct umask_args *uap;
- int *retval;
+ struct umask_args /* {
+ syscallarg(int) newmask;
+ } */ *uap;
+ register_t *retval;
{
register struct filedesc *fdp;
fdp = p->p_fd;
*retval = fdp->fd_cmask;
- fdp->fd_cmask = uap->newmask & ALLPERMS;
+ fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS;
return (0);
}
@@ -2053,35 +2366,31 @@ umask(p, uap, retval)
* Void all references to file by ripping underlying filesystem
* away from vnode.
*/
-struct revoke_args {
- char *path;
-};
/* ARGSUSED */
+int
revoke(p, uap, retval)
struct proc *p;
- register struct revoke_args *uap;
- int *retval;
+ register struct revoke_args /* {
+ syscallarg(char *) path;
+ } */ *uap;
+ register_t *retval;
{
register struct vnode *vp;
struct vattr vattr;
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
- if (vp->v_type != VCHR && vp->v_type != VBLK) {
- error = EINVAL;
- goto out;
- }
if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
goto out;
if (p->p_ucred->cr_uid != vattr.va_uid &&
(error = suser(p->p_ucred, &p->p_acflag)))
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
- vgoneall(vp);
+ VOP_REVOKE(vp, REVOKEALL);
out:
vrele(vp);
return (error);
@@ -2090,6 +2399,7 @@ out:
/*
* Convert a user file descriptor to a kernel file entry.
*/
+int
getvnode(fdp, fd, fpp)
struct filedesc *fdp;
struct file **fpp;
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index d104bb9..3cfc6fd 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
+ * @(#)vfs_vnops.c 8.14 (Berkeley) 6/15/95
*/
#include <sys/param.h>
@@ -82,7 +82,9 @@ vn_open(ndp, fmode, cmode)
VATTR_NULL(vap);
vap->va_type = VREG;
vap->va_mode = cmode;
- LEASE_CHECK(ndp->ni_dvp, p, cred, LEASE_WRITE);
+ if (fmode & O_EXCL)
+ vap->va_vaflags |= VA_EXCLUSIVE;
+ VOP_LEASE(ndp->ni_dvp, p, cred, LEASE_WRITE);
if (error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
&ndp->ni_cnd, vap))
return (error);
@@ -129,9 +131,9 @@ vn_open(ndp, fmode, cmode)
}
}
if (fmode & O_TRUNC) {
- VOP_UNLOCK(vp); /* XXX */
- LEASE_CHECK(vp, p, cred, LEASE_WRITE);
- VOP_LOCK(vp); /* XXX */
+ VOP_UNLOCK(vp, 0, p); /* XXX */
+ VOP_LEASE(vp, p, cred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */
VATTR_NULL(vap);
vap->va_size = 0;
if (error = VOP_SETATTR(vp, vap, cred, p))
@@ -149,25 +151,13 @@ bad:
/*
* Check for write permissions on the specified vnode.
- * The read-only status of the file system is checked.
- * Also, prototype text segments cannot be written.
+ * Prototype text segments cannot be written.
*/
vn_writechk(vp)
register struct vnode *vp;
{
/*
- * Disallow write attempts on read-only file systems;
- * unless the file is a socket or a block or character
- * device resident on the file system.
- */
- if (vp->v_mount->mnt_flag & MNT_RDONLY) {
- switch (vp->v_type) {
- case VREG: case VDIR: case VLNK:
- return (EROFS);
- }
- }
- /*
* If there's shared text associated with
* the vnode, try to free it up once. If
* we fail, we can't allow writing.
@@ -215,7 +205,7 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p)
int error;
if ((ioflg & IO_NODELOCKED) == 0)
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
aiov.iov_base = base;
@@ -236,7 +226,7 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p)
if (auio.uio_resid && error == 0)
error = EIO;
if ((ioflg & IO_NODELOCKED) == 0)
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -248,17 +238,18 @@ vn_read(fp, uio, cred)
struct uio *uio;
struct ucred *cred;
{
- register struct vnode *vp = (struct vnode *)fp->f_data;
+ struct vnode *vp = (struct vnode *)fp->f_data;
+ struct proc *p = uio->uio_procp;
int count, error;
- LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_READ);
- VOP_LOCK(vp);
+ VOP_LEASE(vp, p, cred, LEASE_READ);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
uio->uio_offset = fp->f_offset;
count = uio->uio_resid;
error = VOP_READ(vp, uio, (fp->f_flag & FNONBLOCK) ? IO_NDELAY : 0,
cred);
fp->f_offset += count - uio->uio_resid;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -270,15 +261,19 @@ vn_write(fp, uio, cred)
struct uio *uio;
struct ucred *cred;
{
- register struct vnode *vp = (struct vnode *)fp->f_data;
- int count, error, ioflag = 0;
+ struct vnode *vp = (struct vnode *)fp->f_data;
+ struct proc *p = uio->uio_procp;
+ int count, error, ioflag = IO_UNIT;
if (vp->v_type == VREG && (fp->f_flag & O_APPEND))
ioflag |= IO_APPEND;
if (fp->f_flag & FNONBLOCK)
ioflag |= IO_NDELAY;
- LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_WRITE);
- VOP_LOCK(vp);
+ if ((fp->f_flag & O_FSYNC) ||
+ (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS)))
+ ioflag |= IO_SYNC;
+ VOP_LEASE(vp, p, cred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
uio->uio_offset = fp->f_offset;
count = uio->uio_resid;
error = VOP_WRITE(vp, uio, ioflag, cred);
@@ -286,7 +281,7 @@ vn_write(fp, uio, cred)
fp->f_offset = uio->uio_offset;
else
fp->f_offset += count - uio->uio_resid;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -345,7 +340,7 @@ vn_stat(vp, sb, p)
sb->st_rdev = vap->va_rdev;
sb->st_size = vap->va_size;
sb->st_atimespec = vap->va_atime;
- sb->st_mtimespec= vap->va_mtime;
+ sb->st_mtimespec = vap->va_mtime;
sb->st_ctimespec = vap->va_ctime;
sb->st_blksize = vap->va_blocksize;
sb->st_flags = vap->va_flags;
@@ -359,7 +354,7 @@ vn_stat(vp, sb, p)
*/
vn_ioctl(fp, com, data, p)
struct file *fp;
- int com;
+ u_long com;
caddr_t data;
struct proc *p;
{
@@ -389,6 +384,8 @@ vn_ioctl(fp, com, data, p)
case VBLK:
error = VOP_IOCTL(vp, com, data, fp->f_flag, p->p_ucred, p);
if (error == 0 && com == TIOCSCTTY) {
+ if (p->p_session->s_ttyvp)
+ vrele(p->p_session->s_ttyvp);
p->p_session->s_ttyvp = vp;
VREF(vp);
}
@@ -410,6 +407,36 @@ vn_select(fp, which, p)
}
/*
+ * Check that the vnode is still valid, and if so
+ * acquire requested lock.
+ */
+int
+vn_lock(vp, flags, p)
+ struct vnode *vp;
+ int flags;
+ struct proc *p;
+{
+ int error;
+
+ do {
+ if ((flags & LK_INTERLOCK) == 0)
+ simple_lock(&vp->v_interlock);
+ if (vp->v_flag & VXLOCK) {
+ vp->v_flag |= VXWANT;
+ simple_unlock(&vp->v_interlock);
+ tsleep((caddr_t)vp, PINOD, "vn_lock", 0);
+ error = ENOENT;
+ } else {
+ error = VOP_LOCK(vp, flags | LK_INTERLOCK, p);
+ if (error == 0)
+ return (error);
+ }
+ flags &= ~LK_INTERLOCK;
+ } while (flags & LK_RETRY);
+ return (error);
+}
+
+/*
* File table vnode close routine.
*/
vn_closefile(fp, p)
diff --git a/sys/kern/vnode_if.sh b/sys/kern/vnode_if.sh
index e190fa0..8b74d83 100644
--- a/sys/kern/vnode_if.sh
+++ b/sys/kern/vnode_if.sh
@@ -1,8 +1,9 @@
#!/bin/sh -
-#
-# Copyright (c) 1992, 1993
-# The Regents of the University of California. All rights reserved.
-#
+copyright='
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -30,19 +31,17 @@
# 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.
-#
-# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
-#
+ *
+ * from: NetBSD: vnode_if.sh,v 1.7 1994/08/25 03:04:28 cgd Exp $
+ */
+'
+SCRIPT_ID='@(#)vnode_if.sh 8.7 (Berkeley) 5/11/95'
# Script to produce VFS front-end sugar.
#
# usage: vnode_if.sh srcfile
# (where srcfile is currently /sys/kern/vnode_if.src)
#
-# These awk scripts are not particularly well written, specifically they
-# don't use arrays well and figure out the same information repeatedly.
-# Please rewrite them if you actually understand how to use awk. Note,
-# they use nawk extensions and gawk's toupper.
if [ $# -ne 1 ] ; then
echo 'usage: vnode_if.sh srcfile'
@@ -50,118 +49,180 @@ if [ $# -ne 1 ] ; then
fi
# Name of the source file.
-SRC=$1
+src=$1
# Names of the created files.
-CFILE=vnode_if.c
-HEADER=vnode_if.h
+out_c=vnode_if.c
+out_h=vnode_if.h
+
+# Awk program (must support nawk extensions)
+# Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
+awk=${AWK:-awk}
+
+# Does this awk have a "toupper" function? (i.e. is it GNU awk)
+isgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null`
+
+# If this awk does not define "toupper" then define our own.
+if [ "$isgawk" = TRUE ] ; then
+ # GNU awk provides it.
+ toupper=
+else
+ # Provide our own toupper()
+ toupper='
+function toupper(str) {
+ _toupper_cmd = "echo "str" |tr a-z A-Z"
+ _toupper_cmd | getline _toupper_str;
+ close(_toupper_cmd);
+ return _toupper_str;
+}'
+fi
-# Awk program (must support nawk extensions and gawk's "toupper")
-# Use "awk" at Berkeley, "gawk" elsewhere.
-AWK=awk
+#
+# This is the common part of all awk programs that read $src
+# This parses the input for one function into the arrays:
+# argdir, argtype, argname, willrele
+# and calls "doit()" to generate output for the function.
+#
+# Input to this parser is pre-processed slightly by sed
+# so this awk parser doesn't have to work so hard. The
+# changes done by the sed pre-processing step are:
+# insert a space beween * and pointer name
+# replace semicolons with spaces
+#
+sed_prep='s:\*\([^\*/]\):\* \1:g
+s/;/ /'
+awk_parser='
+# Comment line
+/^#/ { next; }
+# First line of description
+/^vop_/ {
+ name=$1;
+ argc=0;
+ next;
+}
+# Last line of description
+/^}/ {
+ doit();
+ next;
+}
+# Middle lines of description
+{
+ argdir[argc] = $1; i=2;
+ if ($2 == "WILLRELE") {
+ willrele[argc] = 1;
+ i++;
+ } else
+ willrele[argc] = 0;
+ argtype[argc] = $i; i++;
+ while (i < NF) {
+ argtype[argc] = argtype[argc]" "$i;
+ i++;
+ }
+ argname[argc] = $i;
+ argc++;
+ next;
+}
+'
-# Print out header information for vnode_if.h.
-cat << END_OF_LEADING_COMMENT > $HEADER
+# This is put after the copyright on each generated file.
+warning="
/*
- * This file is produced automatically.
- * Do not modify anything in here by hand.
+ * Warning: This file is generated automatically.
+ * (Modifications made here may easily be lost!)
*
- * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
+ * Created by the script:
+ * ${SCRIPT_ID}
*/
+"
-extern struct vnodeop_desc vop_default_desc;
-END_OF_LEADING_COMMENT
-
-# Awk script to take vnode_if.src and turn it into vnode_if.h.
-$AWK '
- NF == 0 || $0 ~ "^#" {
- next;
- }
- {
- # Get the function name.
- name = $1;
- uname = toupper(name);
+# Get rid of ugly spaces
+space_elim='s:\([^/]\*\) :\1:g'
- # Get the function arguments.
- for (c1 = 0;; ++c1) {
- if (getline <= 0)
- exit
- if ($0 ~ "^};")
- break;
- a[c1] = $0;
- }
+#
+# Redirect stdout to the H file.
+#
+echo "$0: Creating $out_h" 1>&2
+exec > $out_h
- # Print out the vop_F_args structure.
- printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n",
- name);
- for (c2 = 0; c2 < c1; ++c2) {
- c3 = split(a[c2], t);
- printf("\t");
- if (t[2] ~ "WILLRELE")
- c4 = 3;
- else
- c4 = 2;
- for (; c4 < c3; ++c4)
- printf("%s ", t[c4]);
- beg = match(t[c3], "[^*]");
- printf("%sa_%s\n",
- substr(t[c4], 0, beg - 1), substr(t[c4], beg));
- }
- printf("};\n");
+# Begin stuff
+echo "$copyright"
+echo "$warning"
+echo '
+extern struct vnodeop_desc vop_default_desc;
+'
+
+# Body stuff
+# This awk program needs toupper() so define it if necessary.
+sed -e "$sed_prep" $src | $awk "$toupper"'
+function doit() {
+ # Declare arg struct, descriptor.
+ printf("\nstruct %s_args {\n", name);
+ printf("\tstruct vnodeop_desc * a_desc;\n");
+ for (i=0; i<argc; i++) {
+ printf("\t%s a_%s;\n", argtype[i], argname[i]);
+ }
+ printf("};\n");
+ printf("extern struct vnodeop_desc %s_desc;\n", name);
+ # Define inline function.
+ printf("#define %s(", toupper(name));
+ for (i=0; i<argc; i++) {
+ printf("%s", argname[i]);
+ if (i < (argc-1)) printf(", ");
+ }
+ printf(") _%s(", toupper(name));
+ for (i=0; i<argc; i++) {
+ printf("%s", argname[i]);
+ if (i < (argc-1)) printf(", ");
+ }
+ printf(")\n");
+ printf("static __inline int _%s(", toupper(name));
+ for (i=0; i<argc; i++) {
+ printf("%s", argname[i]);
+ if (i < (argc-1)) printf(", ");
+ }
+ printf(")\n");
+ for (i=0; i<argc; i++) {
+ printf("\t%s %s;\n", argtype[i], argname[i]);
+ }
+ printf("{\n\tstruct %s_args a;\n", name);
+ printf("\ta.a_desc = VDESC(%s);\n", name);
+ for (i=0; i<argc; i++) {
+ printf("\ta.a_%s = %s;\n", argname[i], argname[i]);
+ }
+ printf("\treturn (VCALL(%s%s, VOFFSET(%s), &a));\n}\n",
+ argname[0], arg0special, name);
+}
+BEGIN {
+ arg0special="";
+}
+END {
+ printf("\n/* Special cases: */\n#include <sys/buf.h>\n");
+ argc=1;
+ argtype[0]="struct buf *";
+ argname[0]="bp";
+ arg0special="->b_vp";
+ name="vop_strategy";
+ doit();
+ name="vop_bwrite";
+ doit();
+}
+'"$awk_parser" | sed -e "$space_elim"
- # Print out extern declaration.
- printf("extern struct vnodeop_desc %s_desc;\n", name);
+# End stuff
+echo '
+/* End of special cases. */'
- # Print out inline struct.
- printf("static inline int %s(", uname);
- sep = ", ";
- for (c2 = 0; c2 < c1; ++c2) {
- if (c2 == c1 - 1)
- sep = ")\n";
- c3 = split(a[c2], t);
- beg = match(t[c3], "[^*]");
- end = match(t[c3], ";");
- printf("%s%s", substr(t[c3], beg, end - beg), sep);
- }
- for (c2 = 0; c2 < c1; ++c2) {
- c3 = split(a[c2], t);
- printf("\t");
- if (t[2] ~ "WILLRELE")
- c4 = 3;
- else
- c4 = 2;
- for (; c4 < c3; ++c4)
- printf("%s ", t[c4]);
- beg = match(t[c3], "[^*]");
- printf("%s%s\n",
- substr(t[c4], 0, beg - 1), substr(t[c4], beg));
- }
- printf("{\n\tstruct %s_args a;\n\n", name);
- printf("\ta.a_desc = VDESC(%s);\n", name);
- for (c2 = 0; c2 < c1; ++c2) {
- c3 = split(a[c2], t);
- printf("\t");
- beg = match(t[c3], "[^*]");
- end = match(t[c3], ";");
- printf("a.a_%s = %s\n",
- substr(t[c3], beg, end - beg), substr(t[c3], beg));
- }
- c1 = split(a[0], t);
- beg = match(t[c1], "[^*]");
- end = match(t[c1], ";");
- printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
- substr(t[c1], beg, end - beg), name);
- }' < $SRC >> $HEADER
-# Print out header information for vnode_if.c.
-cat << END_OF_LEADING_COMMENT > $CFILE
-/*
- * This file is produced automatically.
- * Do not modify anything in here by hand.
- *
- * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
- */
+#
+# Redirect stdout to the C file.
+#
+echo "$0: Creating $out_c" 1>&2
+exec > $out_c
+# Begin stuff
+echo "$copyright"
+echo "$warning"
+echo '
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/vnode.h>
@@ -177,257 +238,107 @@ struct vnodeop_desc vop_default_desc = {
VDESC_NO_OFFSET,
NULL,
};
-
-END_OF_LEADING_COMMENT
-
-# Awk script to take vnode_if.src and turn it into vnode_if.c.
-$AWK 'function kill_surrounding_ws (s) {
- sub (/^[ \t]*/, "", s);
- sub (/[ \t]*$/, "", s);
- return s;
- }
-
- function read_args() {
- numargs = 0;
- while (getline ln) {
- if (ln ~ /}/) {
- break;
- };
-
- # Delete comments, if any.
- gsub (/\/\*.*\*\//, "", ln);
-
- # Delete leading/trailing space.
- ln = kill_surrounding_ws(ln);
-
- # Pick off direction.
- if (1 == sub(/^INOUT[ \t]+/, "", ln))
- dir = "INOUT";
- else if (1 == sub(/^IN[ \t]+/, "", ln))
- dir = "IN";
- else if (1 == sub(/^OUT[ \t]+/, "", ln))
- dir = "OUT";
- else
- bail("No IN/OUT direction for \"" ln "\".");
-
- # check for "WILLRELE"
- if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
- rele = "WILLRELE";
- } else {
- rele = "WONTRELE";
- };
-
- # kill trailing ;
- if (1 != sub (/;$/, "", ln)) {
- bail("Missing end-of-line ; in \"" ln "\".");
- };
-
- # pick off variable name
- if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
- bail("Missing var name \"a_foo\" in \"" ln "\".");
- };
- arg = substr (ln, i);
- # Want to <<substr(ln, i) = "";>>, but nawk cannot.
- # Hack around this.
- ln = substr(ln, 1, i-1);
-
- # what is left must be type
- # (put clean it up some)
- type = ln;
- gsub (/[ \t]+/, " ", type); # condense whitespace
- type = kill_surrounding_ws(type);
-
- # (boy this was easier in Perl)
-
- numargs++;
- dirs[numargs] = dir;
- reles[numargs] = rele;
- types[numargs] = type;
- args[numargs] = arg;
+'
+
+# Body stuff
+sed -e "$sed_prep" $src | $awk '
+function do_offset(typematch) {
+ for (i=0; i<argc; i++) {
+ if (argtype[i] == typematch) {
+ printf("\tVOPARG_OFFSETOF(struct %s_args, a_%s),\n",
+ name, argname[i]);
+ return i;
};
- }
+ };
+ print "\tVDESC_NO_OFFSET,";
+ return -1;
+}
- function generate_operation_vp_offsets() {
- printf ("int %s_vp_offsets[] = {\n", name);
- # as a side effect, figure out the releflags
- releflags = "";
- vpnum = 0;
- for (i=1; i<=numargs; i++) {
- if (types[i] == "struct vnode *") {
- printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
- name, args[i]);
- if (reles[i] == "WILLRELE") {
- releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
- };
- vpnum++;
- };
- };
- sub (/^\|/, "", releflags);
- print "\tVDESC_NO_OFFSET";
- print "};";
- }
-
- function find_arg_with_type (type) {
- for (i=1; i<=numargs; i++) {
- if (types[i] == type) {
- return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
- };
- };
- return "VDESC_NO_OFFSET";
+function doit() {
+ # Define offsets array
+ printf("\nint %s_vp_offsets[] = {\n", name);
+ for (i=0; i<argc; i++) {
+ if (argtype[i] == "struct vnode *") {
+ printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
+ name, argname[i]);
+ }
}
-
- function generate_operation_desc() {
- printf ("struct vnodeop_desc %s_desc = {\n", name);
- # offset
- printf ("\t0,\n");
- # printable name
- printf ("\t\"%s\",\n", name);
- # flags
- vppwillrele = "";
- for (i=1; i<=numargs; i++) {
- if (types[i] == "struct vnode **" &&
- (reles[i] == "WILLRELE")) {
- vppwillrele = "|VDESC_VPP_WILLRELE";
+ print "\tVDESC_NO_OFFSET";
+ print "};";
+ # Define F_desc
+ printf("struct vnodeop_desc %s_desc = {\n", name);
+ # offset
+ printf ("\t0,\n");
+ # printable name
+ printf ("\t\"%s\",\n", name);
+ # flags
+ printf("\t0");
+ vpnum = 0;
+ for (i=0; i<argc; i++) {
+ if (willrele[i]) {
+ if (argdir[i] ~ /OUT/) {
+ printf(" | VDESC_VPP_WILLRELE");
+ } else {
+ printf(" | VDESC_VP%s_WILLRELE", vpnum);
};
- };
- if (releflags == "") {
- printf ("\t0%s,\n", vppwillrele);
- } else {
- printf ("\t%s%s,\n", releflags, vppwillrele);
- };
- # vp offsets
- printf ("\t%s_vp_offsets,\n", name);
- # vpp (if any)
- printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
- # cred (if any)
- printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
- # proc (if any)
- printf ("\t%s,\n", find_arg_with_type("struct proc *"));
- # componentname
- printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
- # transport layer information
- printf ("\tNULL,\n};\n");
- }
-
- NF == 0 || $0 ~ "^#" {
- next;
+ vpnum++;
+ }
}
- {
- # get the function name
- name = $1;
-
- # get the function arguments
- read_args();
-
- # Print out the vop_F_vp_offsets structure. This all depends
- # on naming conventions and nothing else.
- generate_operation_vp_offsets();
-
- # Print out the vnodeop_desc structure.
- generate_operation_desc();
-
- printf "\n";
-
- }' < $SRC >> $CFILE
-# THINGS THAT DON'T WORK RIGHT YET.
-#
-# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
-# arguments. This means that these operations can't function successfully
-# through a bypass routine.
-#
-# Bwrite and strategy will be replaced when the VM page/buffer cache
-# integration happens.
-#
-# To get around this problem for now we handle these ops as special cases.
-
-cat << END_OF_SPECIAL_CASES >> $HEADER
-#include <sys/buf.h>
-struct vop_strategy_args {
- struct vnodeop_desc *a_desc;
- struct buf *a_bp;
-};
-extern struct vnodeop_desc vop_strategy_desc;
-static inline int VOP_STRATEGY(bp)
- struct buf *bp;
-{
- struct vop_strategy_args a;
-
- a.a_desc = VDESC(vop_strategy);
- a.a_bp = bp;
- return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a));
+ print ",";
+ # vp offsets
+ printf ("\t%s_vp_offsets,\n", name);
+ # vpp (if any)
+ do_offset("struct vnode **");
+ # cred (if any)
+ do_offset("struct ucred *");
+ # proc (if any)
+ do_offset("struct proc *");
+ # componentname
+ do_offset("struct componentname *");
+ # transport layer information
+ printf ("\tNULL,\n};\n");
+}
+END {
+ printf("\n/* Special cases: */\n");
+ argc=1;
+ argdir[0]="IN";
+ argtype[0]="struct buf *";
+ argname[0]="bp";
+ willrele[0]=0;
+ name="vop_strategy";
+ doit();
+ name="vop_bwrite";
+ doit();
}
+'"$awk_parser" | sed -e "$space_elim"
-struct vop_bwrite_args {
- struct vnodeop_desc *a_desc;
- struct buf *a_bp;
-};
-extern struct vnodeop_desc vop_bwrite_desc;
-static inline int VOP_BWRITE(bp)
- struct buf *bp;
-{
- struct vop_bwrite_args a;
+# End stuff
+echo '
+/* End of special cases. */'
- a.a_desc = VDESC(vop_bwrite);
- a.a_bp = bp;
- return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
+# Add the vfs_op_descs array to the C file.
+# Begin stuff
+echo '
+struct vnodeop_desc *vfs_op_descs[] = {
+ &vop_default_desc, /* MUST BE FIRST */
+ &vop_strategy_desc, /* XXX: SPECIAL CASE */
+ &vop_bwrite_desc, /* XXX: SPECIAL CASE */
+'
+
+# Body stuff
+sed -e "$sed_prep" $src | $awk '
+function doit() {
+ printf("\t&%s_desc,\n", name);
}
-END_OF_SPECIAL_CASES
+'"$awk_parser"
-cat << END_OF_SPECIAL_CASES >> $CFILE
-int vop_strategy_vp_offsets[] = {
- VDESC_NO_OFFSET
-};
-struct vnodeop_desc vop_strategy_desc = {
- 0,
- "vop_strategy",
- 0,
- vop_strategy_vp_offsets,
- VDESC_NO_OFFSET,
- VDESC_NO_OFFSET,
- VDESC_NO_OFFSET,
- VDESC_NO_OFFSET,
- NULL,
-};
-int vop_bwrite_vp_offsets[] = {
- VDESC_NO_OFFSET
-};
-struct vnodeop_desc vop_bwrite_desc = {
- 0,
- "vop_bwrite",
- 0,
- vop_bwrite_vp_offsets,
- VDESC_NO_OFFSET,
- VDESC_NO_OFFSET,
- VDESC_NO_OFFSET,
- VDESC_NO_OFFSET,
- NULL,
+# End stuff
+echo ' NULL
};
-END_OF_SPECIAL_CASES
+'
-# Add the vfs_op_descs array to the C file.
-$AWK '
- BEGIN {
- printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
- printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
- printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
- printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
- }
- END {
- printf("\tNULL\n};\n");
- }
- NF == 0 || $0 ~ "^#" {
- next;
- }
- {
- # Get the function name.
- printf("\t&%s_desc,\n", $1);
-
- # Skip the function arguments.
- for (;;) {
- if (getline <= 0)
- exit
- if ($0 ~ "^};")
- break;
- }
- }' < $SRC >> $CFILE
+exit 0
+# Local Variables:
+# tab-width: 4
+# End:
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index caee21d..1e32f29 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -30,7 +30,32 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# @(#)vnode_if.src 8.3 (Berkeley) 2/3/94
+# @(#)vnode_if.src 8.12 (Berkeley) 5/14/95
+#
+
+#
+# Above each of the vop descriptors is a specification of the locking
+# protocol used by each vop call. The first column is the name of
+# the variable, the remaining three columns are in, out and error
+# respectively. The "in" column defines the lock state on input,
+# the "out" column defines the state on succesful return, and the
+# "error" column defines the locking state on error exit.
+#
+# The locking value can take the following values:
+# L: locked.
+# U: unlocked/
+# -: not applicable. vnode does not yet (or no longer) exists.
+# =: the same on input and output, may be either L or U.
+# X: locked if not nil.
+#
+
+#
+#% lookup dvp L ? ?
+#% lookup vpp - L -
+#
+# XXX - the lookup locking protocol defies simple description and depends
+# on the flags and operation fields in the (cnp) structure. Note
+# especially that *vpp may equal dvp and both may be locked.
#
vop_lookup {
IN struct vnode *dvp;
@@ -38,6 +63,10 @@ vop_lookup {
IN struct componentname *cnp;
};
+#
+#% create dvp L U U
+#% create vpp - L -
+#
vop_create {
IN WILLRELE struct vnode *dvp;
OUT struct vnode **vpp;
@@ -45,6 +74,21 @@ vop_create {
IN struct vattr *vap;
};
+#
+#% whiteout dvp L L L
+#% whiteout cnp - - -
+#% whiteout flag - - -
+#
+vop_whiteout {
+ IN WILLRELE struct vnode *dvp;
+ IN struct componentname *cnp;
+ IN int flags;
+};
+
+#
+#% mknod dvp L U U
+#% mknod vpp - X -
+#
vop_mknod {
IN WILLRELE struct vnode *dvp;
OUT WILLRELE struct vnode **vpp;
@@ -52,6 +96,9 @@ vop_mknod {
IN struct vattr *vap;
};
+#
+#% open vp L L L
+#
vop_open {
IN struct vnode *vp;
IN int mode;
@@ -59,6 +106,9 @@ vop_open {
IN struct proc *p;
};
+#
+#% close vp U U U
+#
vop_close {
IN struct vnode *vp;
IN int fflag;
@@ -66,6 +116,9 @@ vop_close {
IN struct proc *p;
};
+#
+#% access vp L L L
+#
vop_access {
IN struct vnode *vp;
IN int mode;
@@ -73,6 +126,9 @@ vop_access {
IN struct proc *p;
};
+#
+#% getattr vp = = =
+#
vop_getattr {
IN struct vnode *vp;
IN struct vattr *vap;
@@ -80,6 +136,9 @@ vop_getattr {
IN struct proc *p;
};
+#
+#% setattr vp L L L
+#
vop_setattr {
IN struct vnode *vp;
IN struct vattr *vap;
@@ -87,6 +146,9 @@ vop_setattr {
IN struct proc *p;
};
+#
+#% read vp L L L
+#
vop_read {
IN struct vnode *vp;
INOUT struct uio *uio;
@@ -94,6 +156,9 @@ vop_read {
IN struct ucred *cred;
};
+#
+#% write vp L L L
+#
vop_write {
IN struct vnode *vp;
INOUT struct uio *uio;
@@ -101,16 +166,33 @@ vop_write {
IN struct ucred *cred;
};
+#
+#% lease vp = = =
+#
+vop_lease {
+ IN struct vnode *vp;
+ IN struct proc *p;
+ IN struct ucred *cred;
+ IN int flag;
+};
+
+#
+#% ioctl vp U U U
+#
vop_ioctl {
IN struct vnode *vp;
- IN int command;
+ IN u_long command;
IN caddr_t data;
IN int fflag;
IN struct ucred *cred;
IN struct proc *p;
};
+#
+#% select vp U U U
+#
# Needs work? (fflags)
+#
vop_select {
IN struct vnode *vp;
IN int which;
@@ -119,6 +201,17 @@ vop_select {
IN struct proc *p;
};
+#
+#% revoke vp U U U
+#
+vop_revoke {
+ IN struct vnode *vp;
+ IN int flags;
+};
+
+#
+# XXX - not used
+#
vop_mmap {
IN struct vnode *vp;
IN int fflags;
@@ -126,6 +219,9 @@ vop_mmap {
IN struct proc *p;
};
+#
+#% fsync vp L L L
+#
vop_fsync {
IN struct vnode *vp;
IN struct ucred *cred;
@@ -133,7 +229,10 @@ vop_fsync {
IN struct proc *p;
};
-# Needs word: Is newoff right? What's it mean?
+#
+# XXX - not used
+# Needs work: Is newoff right? What's it mean?
+#
vop_seek {
IN struct vnode *vp;
IN off_t oldoff;
@@ -141,18 +240,32 @@ vop_seek {
IN struct ucred *cred;
};
+#
+#% remove dvp L U U
+#% remove vp L U U
+#
vop_remove {
IN WILLRELE struct vnode *dvp;
IN WILLRELE struct vnode *vp;
IN struct componentname *cnp;
};
+#
+#% link vp U U U
+#% link tdvp L U U
+#
vop_link {
IN WILLRELE struct vnode *vp;
IN struct vnode *tdvp;
IN struct componentname *cnp;
};
+#
+#% rename fdvp U U U
+#% rename fvp U U U
+#% rename tdvp L U U
+#% rename tvp X U U
+#
vop_rename {
IN WILLRELE struct vnode *fdvp;
IN WILLRELE struct vnode *fvp;
@@ -162,6 +275,10 @@ vop_rename {
IN struct componentname *tcnp;
};
+#
+#% mkdir dvp L U U
+#% mkdir vpp - L -
+#
vop_mkdir {
IN WILLRELE struct vnode *dvp;
OUT struct vnode **vpp;
@@ -169,12 +286,24 @@ vop_mkdir {
IN struct vattr *vap;
};
+#
+#% rmdir dvp L U U
+#% rmdir vp L U U
+#
vop_rmdir {
IN WILLRELE struct vnode *dvp;
IN WILLRELE struct vnode *vp;
IN struct componentname *cnp;
};
+#
+#% symlink dvp L U U
+#% symlink vpp - U -
+#
+# XXX - note that the return vnode has already been VRELE'ed
+# by the filesystem layer. To use it you must use vget,
+# possibly with a further namei.
+#
vop_symlink {
IN WILLRELE struct vnode *dvp;
OUT WILLRELE struct vnode **vpp;
@@ -183,39 +312,73 @@ vop_symlink {
IN char *target;
};
+#
+#% readdir vp L L L
+#
vop_readdir {
IN struct vnode *vp;
INOUT struct uio *uio;
IN struct ucred *cred;
+ INOUT int *eofflag;
+ OUT int *ncookies;
+ INOUT u_long **cookies;
};
+#
+#% readlink vp L L L
+#
vop_readlink {
IN struct vnode *vp;
INOUT struct uio *uio;
IN struct ucred *cred;
};
+#
+#% abortop dvp = = =
+#
vop_abortop {
IN struct vnode *dvp;
IN struct componentname *cnp;
};
+#
+#% inactive vp L U U
+#
vop_inactive {
IN struct vnode *vp;
+ IN struct proc *p;
};
+#
+#% reclaim vp U U U
+#
vop_reclaim {
IN struct vnode *vp;
+ IN struct proc *p;
};
+#
+#% lock vp U L U
+#
vop_lock {
IN struct vnode *vp;
+ IN int flags;
+ IN struct proc *p;
};
+#
+#% unlock vp L U L
+#
vop_unlock {
IN struct vnode *vp;
+ IN int flags;
+ IN struct proc *p;
};
+#
+#% bmap vp L L L
+#% bmap vpp - U -
+#
vop_bmap {
IN struct vnode *vp;
IN daddr_t bn;
@@ -224,24 +387,39 @@ vop_bmap {
OUT int *runp;
};
+#
+# Needs work: no vp?
+#
#vop_strategy {
# IN struct buf *bp;
#};
+#
+#% print vp = = =
+#
vop_print {
IN struct vnode *vp;
};
+#
+#% islocked vp = = =
+#
vop_islocked {
IN struct vnode *vp;
};
+#
+#% pathconf vp L L L
+#
vop_pathconf {
IN struct vnode *vp;
IN int name;
- OUT int *retval;
+ OUT register_t *retval;
};
+#
+#% advlock vp U U U
+#
vop_advlock {
IN struct vnode *vp;
IN caddr_t id;
@@ -250,6 +428,9 @@ vop_advlock {
IN int flags;
};
+#
+#% blkatoff vp L L L
+#
vop_blkatoff {
IN struct vnode *vp;
IN off_t offset;
@@ -257,6 +438,9 @@ vop_blkatoff {
OUT struct buf **bpp;
};
+#
+#% valloc pvp L L L
+#
vop_valloc {
IN struct vnode *pvp;
IN int mode;
@@ -264,17 +448,26 @@ vop_valloc {
OUT struct vnode **vpp;
};
+#
+#% reallocblks vp L L L
+#
vop_reallocblks {
IN struct vnode *vp;
IN struct cluster_save *buflist;
};
+#
+#% vfree pvp L L L
+#
vop_vfree {
IN struct vnode *pvp;
IN ino_t ino;
IN int mode;
};
+#
+#% truncate vp L L L
+#
vop_truncate {
IN struct vnode *vp;
IN off_t length;
@@ -283,6 +476,9 @@ vop_truncate {
IN struct proc *p;
};
+#
+#% update vp L L L
+#
vop_update {
IN struct vnode *vp;
IN struct timeval *access;
@@ -290,7 +486,9 @@ vop_update {
IN int waitfor;
};
+#
# Needs work: no vp?
+#
#vop_bwrite {
# IN struct buf *bp;
#};
OpenPOWER on IntegriCloud