diff options
Diffstat (limited to 'sys/xfs/xfs_syscalls-common.c')
-rw-r--r-- | sys/xfs/xfs_syscalls-common.c | 206 |
1 files changed, 148 insertions, 58 deletions
diff --git a/sys/xfs/xfs_syscalls-common.c b/sys/xfs/xfs_syscalls-common.c index ce26bf82d87..a9d52a8468c 100644 --- a/sys/xfs/xfs_syscalls-common.c +++ b/sys/xfs/xfs_syscalls-common.c @@ -1,7 +1,5 @@ -/* $OpenBSD: xfs_syscalls-common.c,v 1.2 2000/03/03 00:54:58 todd Exp $ */ - /* - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -40,7 +38,7 @@ #include <xfs/xfs_locl.h> -RCSID("$OpenBSD: xfs_syscalls-common.c,v 1.2 2000/03/03 00:54:58 todd Exp $"); +RCSID("$Id: xfs_syscalls-common.c,v 1.3 2000/09/11 14:26:53 art Exp $"); /* * XFS system calls. @@ -60,16 +58,33 @@ RCSID("$OpenBSD: xfs_syscalls-common.c,v 1.2 2000/03/03 00:54:58 todd Exp $"); #elif defined(HAVE_SYS_IOCTL_H) #include <sys/ioctl.h> #endif +/* + * XXX - horrible kludge. If we're built without HAVE_CONFIG_H we assume that + * we're built inside the kernel on OpenBSD. + */ +#ifdef HAVE_CONFIG_H +#include <kafs.h> +#else #include <xfs/xfs_pioctl.h> +#endif /* * the syscall entry point */ +#if defined(_LKM) || defined(KLD_MODULE) || defined(__osf__) +int +xfspioctl(struct proc *proc, void *varg, register_t *return_value) +#else int sys_xfspioctl(struct proc *proc, void *varg, register_t *return_value) +#endif { +#if defined(_LKM) || defined(KLD_MODULE) || defined(__osf__) struct sys_pioctl_args *arg = (struct sys_pioctl_args *) varg; +#else + struct sys_xfspioctl_args *arg = (struct sys_xfspioctl_args *) varg; +#endif int error = EINVAL; switch (SCARG(arg, operation)) { @@ -126,7 +141,7 @@ xfs_is_pag(struct ucred *cred) * Return the pag used by `cred' */ -pag_t +xfs_pag_t xfs_get_pag(struct ucred *cred) { if (xfs_is_pag(cred)) { @@ -139,44 +154,113 @@ xfs_get_pag(struct ucred *cred) } /* - * Acquire a new pag in `ret_cred' + * Set the pag in `ret_cred' and return a new cred. */ -int -xfs_setpag_call(struct ucred **ret_cred) +static int +store_pag (struct ucred **ret_cred, gid_t part1, gid_t part2) { struct ucred *cred = *ret_cred; - int i; - if (!xfs_is_pag(cred)) { + if (!xfs_is_pag (cred)) { + int i; - /* Check if it fits */ if (cred->cr_ngroups + 2 >= NGROUPS) - return E2BIG; /* XXX Hmmm, better error ? */ + return E2BIG; cred = crcopy (cred); - /* Copy the groups */ for (i = cred->cr_ngroups - 1; i > 0; i--) { cred->cr_groups[i + 2] = cred->cr_groups[i]; } cred->cr_ngroups += 2; + } else { + cred = crcopy (cred); + } + cred->cr_groups[1] = part1; + cred->cr_groups[2] = part2; + *ret_cred = cred; - } else - cred = crcopy(cred); + return 0; +} - cred->cr_groups[1] = pag_part_one; - cred->cr_groups[2] = pag_part_two++; +/* + * Acquire a new pag in `ret_cred' + */ + +int +xfs_setpag_call(struct ucred **ret_cred) +{ + int ret; + + ret = store_pag (ret_cred, pag_part_one, pag_part_two++); + if (ret) + return ret; if (pag_part_two > XFS_PAG2_ULIM) { pag_part_one++; pag_part_two = XFS_PAG2_LLIM; } - *ret_cred = cred; + return 0; +} + +#if defined(_LKM) || defined(KLD_MODULE) || defined(__osf__) +/* + * remove a pag + */ + +static int +xfs_unpag (struct ucred *cred) +{ + while (xfs_is_pag (cred)) { + int i; + + for (i = 0; i < cred->cr_ngroups - 2; ++i) + cred->cr_groups[i] = cred->cr_groups[i+2]; + cred->cr_ngroups -= 2; + } return 0; } /* + * A wrapper around setgroups that preserves the pag. + */ + +int +xfs_setgroups (struct proc *p, + void *varg) +{ + struct xfs_setgroups_args *uap = (struct xfs_setgroups_args *)varg; + struct ucred **cred = &xfs_proc_to_cred(p); + + if (xfs_is_pag (*cred)) { + gid_t part1, part2; + int ret; + + if (SCARG(uap,gidsetsize) + 2 > NGROUPS) + return EINVAL; + + part1 = (*cred)->cr_groups[1]; + part2 = (*cred)->cr_groups[2]; + ret = (*old_setgroups_func) (p, uap); + if (ret) + return ret; + return store_pag (cred, part1, part2); + } else { + int ret; + + ret = (*old_setgroups_func) (p, uap); + /* don't support setting a PAG */ + if (xfs_is_pag (*cred)) { + xfs_unpag (*cred); + return EINVAL; + } + return ret; + } +} +#endif + +/* * Return the vnode corresponding to `pathptr' */ @@ -194,14 +278,13 @@ lookup_node (const char *pathptr, struct nameidata nd, *ndp = &nd; #endif struct vnode *vp; - size_t done; - XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %p\n", pathptr)); + XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %lx\n", + (unsigned long)pathptr)); - error = copyinstr(pathptr, path, MAXPATHLEN, &done); + error = copyinstr((char *) pathptr, path, MAXPATHLEN, NULL); - XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %s len: %lu error: %d\n", - path, (unsigned long)done, error)); + XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %s, error: %d\n", path, error)); if (error) return error; @@ -233,25 +316,46 @@ fhget_call (struct proc *p, struct vnode *vp) { int error; +#if !((defined(HAVE_GETFH) && defined(HAVE_FHOPEN)) || defined(__osf__)) struct mount *mnt; struct vattr vattr; size_t len; + struct xfs_fhandle_t xfs_handle; struct xfs_fh_args fh_args; +#endif XFSDEB(XDEBSYS, ("fhget_call\n")); if (vp == NULL) return EBADF; - error = suser (xfs_proc_to_cred(p), NULL); + error = xfs_suser (p); if (error) return error; -#ifdef __osf__ - VOP_GETATTR(vp, &vattr, p->p_rcred, error); +#if (defined(HAVE_GETFH) && defined(HAVE_FHOPEN)) || defined(__osf__) + { + /* This is to be same as getfh */ + fhandle_t fh; + + bzero((caddr_t)&fh, sizeof(fh)); + fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; +#if __osf__ + VFS_VPTOFH(vp, &fh.fh_fid, error); #else - error = VOP_GETATTR(vp, &vattr, p->p_ucred, p); + error = VFS_VPTOFH(vp, &fh.fh_fid); #endif + if (error) + return (error); + + if (vice_ioctl->out_size < sizeof(fh)) + return EINVAL; + + error = copyout((caddr_t)&fh, vice_ioctl->out, sizeof (fh)); + return (error); + } +#else + xfs_vop_getattr(vp, &vattr, xfs_proc_to_cred(p), p, error); if (error) goto out; @@ -261,21 +365,25 @@ fhget_call (struct proc *p, SCARG(&fh_args, fileid) = vattr.va_fileid; SCARG(&fh_args, gen) = vattr.va_gen; - len = sizeof(fh_args); + xfs_handle.len = sizeof(fh_args); + memcpy (xfs_handle.fhdata, &fh_args, sizeof(fh_args)); + len = sizeof(xfs_handle); if (vice_ioctl->out_size < len) { error = EINVAL; goto out; } - error = copyout (&fh_args, vice_ioctl->out, len); + error = copyout (&xfs_handle, vice_ioctl->out, len); if (error) { XFSDEB(XDEBSYS, ("fhget_call: copyout failed: %d\n", error)); } - -out: + + out: vrele (vp); return error; +#endif /* HAVE_GETFH && HAVE_FHOPEN */ + } /* @@ -289,8 +397,6 @@ fhopen_call (struct proc *p, int flags, register_t *retval) { - int error; - struct xfs_fh_args fh_args; XFSDEB(XDEBSYS, ("fhopen_call: flags = %d\n", flags)); @@ -299,19 +405,8 @@ fhopen_call (struct proc *p, return EINVAL; } - if (vice_ioctl->in_size < sizeof(fh_args)) - return EINVAL; - - error = copyin (vice_ioctl->in, - &fh_args, - sizeof(fh_args)); - if (error) - return error; - return xfs_fhopen (p, - SCARG(&fh_args, fsid), - SCARG(&fh_args, fileid), - SCARG(&fh_args, gen), + (struct xfs_fhandle_t *)vice_ioctl->in, flags, retval); } @@ -364,21 +459,16 @@ remote_pioctl (struct proc *p, msg.insize = vice_ioctl->in_size; msg.outsize = vice_ioctl->out_size; -#ifdef __osf__ - msg.cred.uid = p->p_ruid; - msg.cred.pag = xfs_get_pag(p->p_rcred); -#else - msg.cred.uid = p->p_cred->p_ruid; - msg.cred.pag = xfs_get_pag(p->p_ucred); -#endif + msg.cred.uid = xfs_proc_to_ruid(p); + msg.cred.pag = xfs_get_pag(xfs_proc_to_cred(p)); error = xfs_message_rpc(0, &msg.header, sizeof(msg)); /* XXX */ msg2 = (struct xfs_message_wakeup_data *) &msg; if (error == 0) error = msg2->error; - else - error = EINVAL; /* return EINVAL to not confuse applications */ + if (error == ENODEV) + error = EINVAL; if (error == 0 && msg2->header.opcode == XFS_MSG_WAKEUP_DATA) error = copyout(msg2->msg, vice_ioctl->out, @@ -397,7 +487,7 @@ xfs_debug (struct proc *p, if (vice_ioctl->in_size < sizeof(int32_t)) return EINVAL; - error = suser (xfs_proc_to_cred(p), NULL); + error = xfs_suser (p); if (error) return error; @@ -439,11 +529,11 @@ xfs_pioctl_call(struct proc *proc, char *pathptr; struct vnode *vp = NULL; - XFSDEB(XDEBSYS, ("xfs_syscall(%d, %p, %d, %p, %d)\n", + XFSDEB(XDEBSYS, ("xfs_syscall(%d, %lx, %d, %lx, %d)\n", SCARG(arg, operation), - SCARG(arg, a_pathP), + (unsigned long)SCARG(arg, a_pathP), SCARG(arg, a_opcode), - SCARG(arg, a_paramsP), + (unsigned long)SCARG(arg, a_paramsP), SCARG(arg, a_followSymlinks))); /* Copy in the data structure for us */ |