From owner-svn-src-all@FreeBSD.ORG Wed Apr 7 14:49:35 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9C06D1065678; Wed, 7 Apr 2010 14:49:35 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8A5408FC15; Wed, 7 Apr 2010 14:49:35 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o37EnZ75026471; Wed, 7 Apr 2010 14:49:35 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o37EnZLt026467; Wed, 7 Apr 2010 14:49:35 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201004071449.o37EnZLt026467@svn.freebsd.org> From: Konstantin Belousov Date: Wed, 7 Apr 2010 14:49:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r206351 - in stable/8/sys: compat/freebsd32 kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Apr 2010 14:49:35 -0000 Author: kib Date: Wed Apr 7 14:49:35 2010 New Revision: 206351 URL: http://svn.freebsd.org/changeset/base/206351 Log: MFC r205325: Implement compat32 shims for mqueuefs. Modified: stable/8/sys/compat/freebsd32/freebsd32.h stable/8/sys/compat/freebsd32/syscalls.master stable/8/sys/kern/uipc_mqueue.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/compat/freebsd32/freebsd32.h ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32.h Wed Apr 7 14:47:55 2010 (r206350) +++ stable/8/sys/compat/freebsd32/freebsd32.h Wed Apr 7 14:49:35 2010 (r206351) @@ -221,4 +221,12 @@ struct prpsinfo32 { char pr_psargs[PRARGSZ+1]; }; +struct mq_attr32 { + int mq_flags; + int mq_maxmsg; + int mq_msgsize; + int mq_curmsgs; + int __reserved[4]; +}; + #endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */ Modified: stable/8/sys/compat/freebsd32/syscalls.master ============================================================================== --- stable/8/sys/compat/freebsd32/syscalls.master Wed Apr 7 14:47:55 2010 (r206350) +++ stable/8/sys/compat/freebsd32/syscalls.master Wed Apr 7 14:49:35 2010 (r206351) @@ -798,12 +798,23 @@ int param_size); } 456 AUE_NULL NOPROTO { int sigqueue(pid_t pid, int signum, \ void *value); } -457 AUE_NULL UNIMPL kmq_open -458 AUE_NULL UNIMPL kmq_setattr -459 AUE_NULL UNIMPL kmq_timedreceive -460 AUE_NULL UNIMPL kmq_timedsend -461 AUE_NULL UNIMPL kmq_notify -462 AUE_NULL UNIMPL kmq_unlink +457 AUE_NULL NOSTD { int freebsd32_kmq_open( \ + const char *path, int flags, mode_t mode, \ + const struct mq_attr32 *attr); } +458 AUE_NULL NOSTD { int freebsd32_kmq_setattr(int mqd, \ + const struct mq_attr32 *attr, \ + struct mq_attr32 *oattr); } +459 AUE_NULL NOSTD { int freebsd32_kmq_timedreceive(int mqd, \ + char *msg_ptr, size_t msg_len, \ + unsigned *msg_prio, \ + const struct timespec32 *abs_timeout); } +460 AUE_NULL NOSTD { int freebsd32_kmq_timedsend(int mqd, \ + const char *msg_ptr, size_t msg_len,\ + unsigned msg_prio, \ + const struct timespec32 *abs_timeout);} +461 AUE_NULL NOPROTO|NOSTD { int kmq_notify(int mqd, \ + const struct sigevent *sigev); } +462 AUE_NULL NOPROTO|NOSTD { int kmq_unlink(const char *path); } 463 AUE_NULL NOPROTO { int abort2(const char *why, int nargs, void **args); } 464 AUE_NULL NOPROTO { int thr_set_name(long id, const char *name); } 465 AUE_NULL NOSTD { int freebsd32_aio_fsync(int op, \ Modified: stable/8/sys/kern/uipc_mqueue.c ============================================================================== --- stable/8/sys/kern/uipc_mqueue.c Wed Apr 7 14:47:55 2010 (r206350) +++ stable/8/sys/kern/uipc_mqueue.c Wed Apr 7 14:49:35 2010 (r206351) @@ -45,6 +45,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_compat.h" + #include #include #include @@ -1616,7 +1618,7 @@ mqueue_send(struct mqueue *mq, const cha const struct timespec *abs_timeout) { struct mqueue_msg *msg; - struct timespec ets, ts, ts2; + struct timespec ts, ts2; struct timeval tv; int error; @@ -1652,15 +1654,12 @@ mqueue_send(struct mqueue *mq, const cha if (error != EAGAIN) goto bad; - error = copyin(abs_timeout, &ets, sizeof(ets)); - if (error != 0) - goto bad; - if (ets.tv_nsec >= 1000000000 || ets.tv_nsec < 0) { + if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) { error = EINVAL; goto bad; } for (;;) { - ts2 = ets; + ts2 = *abs_timeout; getnanotime(&ts); timespecsub(&ts2, &ts); if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) { @@ -1767,7 +1766,7 @@ mqueue_receive(struct mqueue *mq, char * const struct timespec *abs_timeout) { struct mqueue_msg *msg; - struct timespec ets, ts, ts2; + struct timespec ts, ts2; struct timeval tv; int error; @@ -1798,16 +1797,13 @@ mqueue_receive(struct mqueue *mq, char * if (error != EAGAIN) return (error); - error = copyin(abs_timeout, &ets, sizeof(ets)); - if (error != 0) - return (error); - if (ets.tv_nsec >= 1000000000 || ets.tv_nsec < 0) { + if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) { error = EINVAL; return (error); } for (;;) { - ts2 = ets; + ts2 = *abs_timeout; getnanotime(&ts); timespecsub(&ts2, &ts); if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) { @@ -1928,40 +1924,28 @@ notifier_remove(struct proc *p, struct m PROC_UNLOCK(p); } -/* - * Syscall to open a message queue. - */ -int -kmq_open(struct thread *td, struct kmq_open_args *uap) +static int +kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode, + const struct mq_attr *attr) { char path[MQFS_NAMELEN + 1]; - struct mq_attr attr, *pattr; struct mqfs_node *pn; struct filedesc *fdp; struct file *fp; struct mqueue *mq; - int fd, error, len, flags, cmode; - - if ((uap->flags & O_ACCMODE) == O_ACCMODE) - return (EINVAL); + int fd, error, len, cmode; fdp = td->td_proc->p_fd; - flags = FFLAGS(uap->flags); - cmode = (((uap->mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT); + cmode = (((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT); mq = NULL; - if ((flags & O_CREAT) && (uap->attr != NULL)) { - error = copyin(uap->attr, &attr, sizeof(attr)); - if (error) - return (error); - if (attr.mq_maxmsg <= 0 || attr.mq_maxmsg > maxmsg) + if ((flags & O_CREAT) != 0 && attr != NULL) { + if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg) return (EINVAL); - if (attr.mq_msgsize <= 0 || attr.mq_msgsize > maxmsgsize) + if (attr->mq_msgsize <= 0 || attr->mq_msgsize > maxmsgsize) return (EINVAL); - pattr = &attr; - } else - pattr = NULL; + } - error = copyinstr(uap->path, path, MQFS_NAMELEN + 1, NULL); + error = copyinstr(upath, path, MQFS_NAMELEN + 1, NULL); if (error) return (error); @@ -1984,7 +1968,7 @@ kmq_open(struct thread *td, struct kmq_o if (!(flags & O_CREAT)) { error = ENOENT; } else { - mq = mqueue_alloc(pattr); + mq = mqueue_alloc(attr); if (mq == NULL) { error = ENFILE; } else { @@ -2039,6 +2023,27 @@ kmq_open(struct thread *td, struct kmq_o } /* + * Syscall to open a message queue. + */ +int +kmq_open(struct thread *td, struct kmq_open_args *uap) +{ + struct mq_attr attr; + int flags, error; + + if ((uap->flags & O_ACCMODE) == O_ACCMODE) + return (EINVAL); + flags = FFLAGS(uap->flags); + if ((flags & O_CREAT) != 0 && uap->attr != NULL) { + error = copyin(uap->attr, &attr, sizeof(attr)); + if (error) + return (error); + } + return (kern_kmq_open(td, uap->path, flags, uap->mode, + uap->attr != NULL ? &attr : NULL)); +} + +/* * Syscall to unlink a message queue. */ int @@ -2114,39 +2119,52 @@ getmq_write(struct thread *td, int fd, s return _getmq(td, fd, fget_write, fpp, ppn, pmq); } -int -kmq_setattr(struct thread *td, struct kmq_setattr_args *uap) +static int +kern_kmq_setattr(struct thread *td, int mqd, const struct mq_attr *attr, + struct mq_attr *oattr) { struct mqueue *mq; struct file *fp; - struct mq_attr attr, oattr; u_int oflag, flag; int error; - if (uap->attr) { - error = copyin(uap->attr, &attr, sizeof(attr)); - if (error) - return (error); - if (attr.mq_flags & ~O_NONBLOCK) - return (EINVAL); - } - error = getmq(td, uap->mqd, &fp, NULL, &mq); + if (attr != NULL && (attr->mq_flags & ~O_NONBLOCK) != 0) + return (EINVAL); + error = getmq(td, mqd, &fp, NULL, &mq); if (error) return (error); - oattr.mq_maxmsg = mq->mq_maxmsg; - oattr.mq_msgsize = mq->mq_msgsize; - oattr.mq_curmsgs = mq->mq_curmsgs; - if (uap->attr) { + oattr->mq_maxmsg = mq->mq_maxmsg; + oattr->mq_msgsize = mq->mq_msgsize; + oattr->mq_curmsgs = mq->mq_curmsgs; + if (attr != NULL) { do { oflag = flag = fp->f_flag; flag &= ~O_NONBLOCK; - flag |= (attr.mq_flags & O_NONBLOCK); + flag |= (attr->mq_flags & O_NONBLOCK); } while (atomic_cmpset_int(&fp->f_flag, oflag, flag) == 0); } else oflag = fp->f_flag; - oattr.mq_flags = (O_NONBLOCK & oflag); + oattr->mq_flags = (O_NONBLOCK & oflag); fdrop(fp, td); - if (uap->oattr) + return (error); +} + +int +kmq_setattr(struct thread *td, struct kmq_setattr_args *uap) +{ + struct mq_attr attr, oattr; + int error; + + if (uap->attr != NULL) { + error = copyin(uap->attr, &attr, sizeof(attr)); + if (error != 0) + return (error); + } + error = kern_kmq_setattr(td, uap->mqd, uap->attr != NULL ? &attr : NULL, + &oattr); + if (error != 0) + return (error); + if (uap->oattr != NULL) error = copyout(&oattr, uap->oattr, sizeof(oattr)); return (error); } @@ -2156,15 +2174,23 @@ kmq_timedreceive(struct thread *td, stru { struct mqueue *mq; struct file *fp; + struct timespec *abs_timeout, ets; int error; int waitok; error = getmq_read(td, uap->mqd, &fp, NULL, &mq); if (error) return (error); + if (uap->abs_timeout != NULL) { + error = copyin(uap->abs_timeout, &ets, sizeof(ets)); + if (error != 0) + return (error); + abs_timeout = &ets; + } else + abs_timeout = NULL; waitok = !(fp->f_flag & O_NONBLOCK); error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len, - uap->msg_prio, waitok, uap->abs_timeout); + uap->msg_prio, waitok, abs_timeout); fdrop(fp, td); return (error); } @@ -2174,14 +2200,22 @@ kmq_timedsend(struct thread *td, struct { struct mqueue *mq; struct file *fp; + struct timespec *abs_timeout, ets; int error, waitok; error = getmq_write(td, uap->mqd, &fp, NULL, &mq); if (error) return (error); + if (uap->abs_timeout != NULL) { + error = copyin(uap->abs_timeout, &ets, sizeof(ets)); + if (error != 0) + return (error); + abs_timeout = &ets; + } else + abs_timeout = NULL; waitok = !(fp->f_flag & O_NONBLOCK); error = mqueue_send(mq, uap->msg_ptr, uap->msg_len, - uap->msg_prio, waitok, uap->abs_timeout); + uap->msg_prio, waitok, abs_timeout); fdrop(fp, td); return (error); } @@ -2505,12 +2539,219 @@ static struct vfsops mqfs_vfsops = { .vfs_statfs = mqfs_statfs, }; -SYSCALL_MODULE_HELPER(kmq_open); -SYSCALL_MODULE_HELPER(kmq_setattr); -SYSCALL_MODULE_HELPER(kmq_timedsend); -SYSCALL_MODULE_HELPER(kmq_timedreceive); -SYSCALL_MODULE_HELPER(kmq_notify); -SYSCALL_MODULE_HELPER(kmq_unlink); +static struct vfsconf mqueuefs_vfsconf = { + .vfc_version = VFS_VERSION, + .vfc_name = "mqueuefs", + .vfc_vfsops = &mqfs_vfsops, + .vfc_typenum = -1, + .vfc_flags = VFCF_SYNTHETIC +}; + +static struct syscall_helper_data mq_syscalls[] = { + SYSCALL_INIT_HELPER(kmq_open), + SYSCALL_INIT_HELPER(kmq_setattr), + SYSCALL_INIT_HELPER(kmq_timedsend), + SYSCALL_INIT_HELPER(kmq_timedreceive), + SYSCALL_INIT_HELPER(kmq_notify), + SYSCALL_INIT_HELPER(kmq_unlink), + SYSCALL_INIT_LAST +}; + +#ifdef COMPAT_FREEBSD32 +#include +#include +#include +#include + +static void +mq_attr_from32(const struct mq_attr32 *from, struct mq_attr *to) +{ + + to->mq_flags = from->mq_flags; + to->mq_maxmsg = from->mq_maxmsg; + to->mq_msgsize = from->mq_msgsize; + to->mq_curmsgs = from->mq_curmsgs; +} + +static void +mq_attr_to32(const struct mq_attr *from, struct mq_attr32 *to) +{ + + to->mq_flags = from->mq_flags; + to->mq_maxmsg = from->mq_maxmsg; + to->mq_msgsize = from->mq_msgsize; + to->mq_curmsgs = from->mq_curmsgs; +} + +int +freebsd32_kmq_open(struct thread *td, struct freebsd32_kmq_open_args *uap) +{ + struct mq_attr attr; + struct mq_attr32 attr32; + int flags, error; + + if ((uap->flags & O_ACCMODE) == O_ACCMODE) + return (EINVAL); + flags = FFLAGS(uap->flags); + if ((flags & O_CREAT) != 0 && uap->attr != NULL) { + error = copyin(uap->attr, &attr32, sizeof(attr32)); + if (error) + return (error); + mq_attr_from32(&attr32, &attr); + } + return (kern_kmq_open(td, uap->path, flags, uap->mode, + uap->attr != NULL ? &attr : NULL)); +} + +int +freebsd32_kmq_setattr(struct thread *td, struct freebsd32_kmq_setattr_args *uap) +{ + struct mq_attr attr, oattr; + struct mq_attr32 attr32, oattr32; + int error; + + if (uap->attr != NULL) { + error = copyin(uap->attr, &attr32, sizeof(attr32)); + if (error != 0) + return (error); + mq_attr_from32(&attr32, &attr); + } + error = kern_kmq_setattr(td, uap->mqd, uap->attr != NULL ? &attr : NULL, + &oattr); + if (error != 0) + return (error); + if (uap->oattr != NULL) { + mq_attr_to32(&oattr, &oattr32); + error = copyout(&oattr32, uap->oattr, sizeof(oattr32)); + } + return (error); +} + +int +freebsd32_kmq_timedsend(struct thread *td, + struct freebsd32_kmq_timedsend_args *uap) +{ + struct mqueue *mq; + struct file *fp; + struct timespec32 ets32; + struct timespec *abs_timeout, ets; + int error; + int waitok; + + error = getmq_read(td, uap->mqd, &fp, NULL, &mq); + if (error) + return (error); + if (uap->abs_timeout != NULL) { + error = copyin(uap->abs_timeout, &ets32, sizeof(ets32)); + if (error != 0) + return (error); + CP(ets32, ets, tv_sec); + CP(ets32, ets, tv_nsec); + abs_timeout = &ets; + } else + abs_timeout = NULL; + waitok = !(fp->f_flag & O_NONBLOCK); + error = mqueue_send(mq, uap->msg_ptr, uap->msg_len, + uap->msg_prio, waitok, abs_timeout); + fdrop(fp, td); + return (error); +} + +int +freebsd32_kmq_timedreceive(struct thread *td, + struct freebsd32_kmq_timedreceive_args *uap) +{ + struct mqueue *mq; + struct file *fp; + struct timespec32 ets32; + struct timespec *abs_timeout, ets; + int error, waitok; + + error = getmq_write(td, uap->mqd, &fp, NULL, &mq); + if (error) + return (error); + if (uap->abs_timeout != NULL) { + error = copyin(uap->abs_timeout, &ets32, sizeof(ets32)); + if (error != 0) + return (error); + CP(ets32, ets, tv_sec); + CP(ets32, ets, tv_nsec); + abs_timeout = &ets; + } else + abs_timeout = NULL; + waitok = !(fp->f_flag & O_NONBLOCK); + error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len, + uap->msg_prio, waitok, abs_timeout); + fdrop(fp, td); + return (error); +} + +static struct syscall_helper_data mq32_syscalls[] = { + SYSCALL32_INIT_HELPER(freebsd32_kmq_open), + SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr), + SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend), + SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive), + SYSCALL32_INIT_HELPER(kmq_notify), + SYSCALL32_INIT_HELPER(kmq_unlink), + SYSCALL_INIT_LAST +}; +#endif + +static int +mqinit(void) +{ + int error; + + error = syscall_helper_register(mq_syscalls); + if (error != 0) + return (error); +#ifdef COMPAT_FREEBSD32 + error = syscall32_helper_register(mq32_syscalls); + if (error != 0) + return (error); +#endif + return (0); +} -VFS_SET(mqfs_vfsops, mqueuefs, VFCF_SYNTHETIC); +static int +mqunload(void) +{ + +#ifdef COMPAT_FREEBSD32 + syscall32_helper_unregister(mq32_syscalls); +#endif + syscall_helper_unregister(mq_syscalls); + return (0); +} + +static int +mq_modload(struct module *module, int cmd, void *arg) +{ + int error = 0; + + error = vfs_modevent(module, cmd, arg); + if (error != 0) + return (error); + + switch (cmd) { + case MOD_LOAD: + error = mqinit(); + if (error != 0) + mqunload(); + break; + case MOD_UNLOAD: + error = mqunload(); + break; + default: + break; + } + return (error); +} + +static moduledata_t mqueuefs_mod = { + "mqueuefs", + mq_modload, + &mqueuefs_vfsconf +}; +DECLARE_MODULE(mqueuefs, mqueuefs_mod, SI_SUB_VFS, SI_ORDER_MIDDLE); MODULE_VERSION(mqueuefs, 1);