Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/compat/linux/common/linux_file64.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/compat/linux/common/linux_file64.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.28.2.9 retrieving revision 1.29 diff -u -p -r1.28.2.9 -r1.29 --- src/sys/compat/linux/common/linux_file64.c 2008/03/24 09:38:41 1.28.2.9 +++ src/sys/compat/linux/common/linux_file64.c 2005/08/19 02:03:57 1.29 @@ -1,7 +1,7 @@ -/* $NetBSD: linux_file64.c,v 1.28.2.9 2008/03/24 09:38:41 yamt Exp $ */ +/* $NetBSD: linux_file64.c,v 1.29 2005/08/19 02:03:57 christos Exp $ */ /*- - * Copyright (c) 1995, 1998, 2000, 2008 The NetBSD Foundation, Inc. + * Copyright (c) 1995, 1998, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.28.2.9 2008/03/24 09:38:41 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.29 2005/08/19 02:03:57 christos Exp $"); #include #include @@ -55,12 +55,11 @@ __KERNEL_RCSID(0, "$NetBSD: linux_file64 #include #include #include -#include -#include #include #include #include +#include #include #include @@ -69,14 +68,13 @@ __KERNEL_RCSID(0, "$NetBSD: linux_file64 #include #include #include -#include -#include #include #ifndef alpha -static void bsd_to_linux_stat(struct stat *, struct linux_stat64 *); +static void bsd_to_linux_stat __P((struct stat *, struct linux_stat64 *)); +static int linux_do_stat64 __P((struct lwp *, void *, register_t *, int)); /* * Convert a NetBSD stat structure to a Linux stat structure. @@ -87,7 +85,9 @@ static void bsd_to_linux_stat(struct sta * things against constant major device numbers? sigh) */ static void -bsd_to_linux_stat(struct stat *bsp, struct linux_stat64 *lsp) +bsd_to_linux_stat(bsp, lsp) + struct stat *bsp; + struct linux_stat64 *lsp; { lsp->lst_dev = linux_fakedev(bsp->st_dev, 0); lsp->lst_ino = bsp->st_ino; @@ -105,14 +105,14 @@ bsd_to_linux_stat(struct stat *bsp, stru lsp->lst_atime = bsp->st_atime; lsp->lst_mtime = bsp->st_mtime; lsp->lst_ctime = bsp->st_ctime; -# ifdef LINUX_STAT64_HAS_NSEC +#ifdef LINUX_STAT64_HAS_NSEC lsp->lst_atime_nsec = bsp->st_atimensec; lsp->lst_mtime_nsec = bsp->st_mtimensec; lsp->lst_ctime_nsec = bsp->st_ctimensec; -# endif -# if LINUX_STAT64_HAS_BROKEN_ST_INO +#endif +#if LINUX_STAT64_HAS_BROKEN_ST_INO lsp->__lst_ino = (linux_ino_t) bsp->st_ino; -# endif +#endif } /* @@ -120,71 +120,123 @@ bsd_to_linux_stat(struct stat *bsp, stru * by one function to avoid code duplication. */ int -linux_sys_fstat64(struct lwp *l, const struct linux_sys_fstat64_args *uap, register_t *retval) +linux_sys_fstat64(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; { - /* { + struct linux_sys_fstat64_args /* { syscallarg(int) fd; syscallarg(struct linux_stat64 *) sp; - } */ + } */ *uap = v; + struct proc *p = l->l_proc; + struct sys___fstat30_args fsa; struct linux_stat64 tmplst; - struct stat tmpst; + struct stat *st,tmpst; + caddr_t sg; int error; - error = do_sys_fstat(SCARG(uap, fd), &tmpst); - if (error != 0) + sg = stackgap_init(p, 0); + + st = stackgap_alloc(p, &sg, sizeof (struct stat)); + + SCARG(&fsa, fd) = SCARG(uap, fd); + SCARG(&fsa, sb) = st; + + if ((error = sys___fstat30(l, &fsa, retval))) + return error; + + if ((error = copyin(st, &tmpst, sizeof tmpst))) return error; bsd_to_linux_stat(&tmpst, &tmplst); - return copyout(&tmplst, SCARG(uap, sp), sizeof tmplst); + if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst))) + return error; + + return 0; } static int -linux_do_stat64(struct lwp *l, const struct linux_sys_stat64_args *uap, register_t *retval, int flags) +linux_do_stat64(l, v, retval, dolstat) + struct lwp *l; + void *v; + register_t *retval; + int dolstat; { + struct proc *p = l->l_proc; + struct sys___stat30_args sa; struct linux_stat64 tmplst; - struct stat tmpst; + struct stat *st, tmpst; + caddr_t sg; int error; + struct linux_sys_stat64_args *uap = v; + + sg = stackgap_init(p, 0); + st = stackgap_alloc(p, &sg, sizeof (struct stat)); + CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); - error = do_sys_stat(SCARG(uap, path), flags, &tmpst); - if (error != 0) + SCARG(&sa, ub) = st; + SCARG(&sa, path) = SCARG(uap, path); + + if ((error = (dolstat ? sys___lstat30(l, &sa, retval) : + sys___stat30(l, &sa, retval)))) + return error; + + if ((error = copyin(st, &tmpst, sizeof tmpst))) return error; bsd_to_linux_stat(&tmpst, &tmplst); - return copyout(&tmplst, SCARG(uap, sp), sizeof tmplst); + if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst))) + return error; + + return 0; } int -linux_sys_stat64(struct lwp *l, const struct linux_sys_stat64_args *uap, register_t *retval) +linux_sys_stat64(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; { - /* { + struct linux_sys_stat64_args /* { syscallarg(const char *) path; syscallarg(struct linux_stat64 *) sp; - } */ + } */ *uap = v; - return linux_do_stat64(l, uap, retval, FOLLOW); + return linux_do_stat64(l, uap, retval, 0); } int -linux_sys_lstat64(struct lwp *l, const struct linux_sys_lstat64_args *uap, register_t *retval) +linux_sys_lstat64(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; { - /* { + struct linux_sys_lstat64_args /* { syscallarg(const char *) path; syscallarg(struct linux_stat64 *) sp; - } */ + } */ *uap = v; - return linux_do_stat64(l, (const void *)uap, retval, NOFOLLOW); + return linux_do_stat64(l, uap, retval, 1); } int -linux_sys_truncate64(struct lwp *l, const struct linux_sys_truncate64_args *uap, register_t *retval) +linux_sys_truncate64(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; { - /* { + struct linux_sys_truncate64_args /* { syscallarg(const char *) path; syscallarg(off_t) length; - } */ + } */ *uap = v; struct sys_truncate_args ta; + struct proc *p = l->l_proc; + caddr_t sg = stackgap_init(p, 0); + + CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); /* Linux doesn't have the 'pad' pseudo-parameter */ SCARG(&ta, path) = SCARG(uap, path); @@ -195,12 +247,15 @@ linux_sys_truncate64(struct lwp *l, cons } int -linux_sys_ftruncate64(struct lwp *l, const struct linux_sys_ftruncate64_args *uap, register_t *retval) +linux_sys_ftruncate64(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; { - /* { + struct linux_sys_ftruncate64_args /* { syscallarg(unsigned int) fd; syscallarg(off_t) length; - } */ + } */ *uap = v; struct sys_ftruncate_args ta; /* Linux doesn't have the 'pad' pseudo-parameter */ @@ -210,6 +265,118 @@ linux_sys_ftruncate64(struct lwp *l, con return sys_ftruncate(l, &ta, retval); } + +#if !defined(__m68k__) && !defined(__amd64__) +static void bsd_to_linux_flock64 __P((struct linux_flock64 *, + const struct flock *)); +static void linux_to_bsd_flock64 __P((struct flock *, + const struct linux_flock64 *)); + +static void +bsd_to_linux_flock64(lfp, bfp) + struct linux_flock64 *lfp; + const struct flock *bfp; +{ + + lfp->l_start = bfp->l_start; + lfp->l_len = bfp->l_len; + lfp->l_pid = bfp->l_pid; + lfp->l_whence = bfp->l_whence; + switch (bfp->l_type) { + case F_RDLCK: + lfp->l_type = LINUX_F_RDLCK; + break; + case F_UNLCK: + lfp->l_type = LINUX_F_UNLCK; + break; + case F_WRLCK: + lfp->l_type = LINUX_F_WRLCK; + break; + } +} + +static void +linux_to_bsd_flock64(bfp, lfp) + struct flock *bfp; + const struct linux_flock64 *lfp; +{ + + bfp->l_start = lfp->l_start; + bfp->l_len = lfp->l_len; + bfp->l_pid = lfp->l_pid; + bfp->l_whence = lfp->l_whence; + switch (lfp->l_type) { + case LINUX_F_RDLCK: + bfp->l_type = F_RDLCK; + break; + case LINUX_F_UNLCK: + bfp->l_type = F_UNLCK; + break; + case LINUX_F_WRLCK: + bfp->l_type = F_WRLCK; + break; + } +} + +int +linux_sys_fcntl64(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; +{ + struct linux_sys_fcntl64_args /* { + syscallarg(int) fd; + syscallarg(int) cmd; + syscallarg(void *) arg; + } */ *uap = v; + struct proc *p = l->l_proc; + struct sys_fcntl_args fca; + struct linux_flock64 lfl; + struct flock bfl, *bfp; + int error; + caddr_t sg; + void *arg = SCARG(uap, arg); + int cmd = SCARG(uap, cmd); + int fd = SCARG(uap, fd); + + switch (cmd) { + case LINUX_F_GETLK64: + sg = stackgap_init(p, 0); + bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp); + if ((error = copyin(arg, &lfl, sizeof lfl)) != 0) + return error; + linux_to_bsd_flock64(&bfl, &lfl); + if ((error = copyout(&bfl, bfp, sizeof bfl)) != 0) + return error; + SCARG(&fca, fd) = fd; + SCARG(&fca, cmd) = F_GETLK; + SCARG(&fca, arg) = bfp; + if ((error = sys_fcntl(l, &fca, retval)) != 0) + return error; + if ((error = copyin(bfp, &bfl, sizeof bfl)) != 0) + return error; + bsd_to_linux_flock64(&lfl, &bfl); + return copyout(&lfl, arg, sizeof lfl); + case LINUX_F_SETLK64: + case LINUX_F_SETLKW64: + cmd = (cmd == LINUX_F_SETLK64 ? F_SETLK : F_SETLKW); + if ((error = copyin(arg, &lfl, sizeof lfl)) != 0) + return error; + linux_to_bsd_flock64(&bfl, &lfl); + sg = stackgap_init(p, 0); + bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp); + if ((error = copyout(&bfl, bfp, sizeof bfl)) != 0) + return error; + SCARG(&fca, fd) = fd; + SCARG(&fca, cmd) = cmd; + SCARG(&fca, arg) = bfp; + return sys_fcntl(l, &fca, retval); + default: + return linux_sys_fcntl(l, v, retval); + } +} +#endif /* !m68k && !amd64 */ + #endif /* !alpha */ /* @@ -227,20 +394,24 @@ linux_sys_ftruncate64(struct lwp *l, con * Note that this doesn't handle union-mounted filesystems. */ int -linux_sys_getdents64(struct lwp *l, const struct linux_sys_getdents64_args *uap, register_t *retval) +linux_sys_getdents64(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; { - /* { + struct linux_sys_getdents_args /* { syscallarg(int) fd; syscallarg(struct linux_dirent64 *) dent; syscallarg(unsigned int) count; - } */ + } */ *uap = v; + struct proc *p = l->l_proc; struct dirent *bdp; struct vnode *vp; - char *inp, *tbuf; /* BSD-format */ + caddr_t inp, tbuf; /* BSD-format */ int len, reclen; /* BSD-format */ - char *outp; /* Linux-format */ + caddr_t outp; /* Linux-format */ int resid, linux_reclen = 0; /* Linux-format */ - file_t *fp; + struct file *fp; struct uio auio; struct iovec aiov; struct linux_dirent64 idb; @@ -251,7 +422,7 @@ linux_sys_getdents64(struct lwp *l, cons int ncookies; /* getvnode() will use the descriptor for us */ - if ((error = getvnode(SCARG(uap, fd), &fp)) != 0) + if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) return (error); if ((fp->f_flag & FREAD) == 0) { @@ -265,7 +436,7 @@ linux_sys_getdents64(struct lwp *l, cons goto out1; } - if ((error = VOP_GETATTR(vp, &va, l->l_cred))) + if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) goto out1; nbytes = SCARG(uap, count); @@ -282,9 +453,10 @@ again: auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_procp = NULL; auio.uio_resid = buflen; auio.uio_offset = off; - UIO_SETUP_SYSSPACE(&auio); /* * First we read into the malloc'ed buffer, then * we massage it into user space, one record at a time. @@ -295,7 +467,7 @@ again: goto out; inp = tbuf; - outp = (void *)SCARG(uap, dent); + outp = (caddr_t)SCARG(uap, dent); resid = nbytes; if ((len = buflen - auio.uio_resid) == 0) goto eof; @@ -333,7 +505,7 @@ again: idb.d_off = off; idb.d_reclen = (u_short)linux_reclen; strcpy(idb.d_name, bdp->d_name); - if ((error = copyout((void *)&idb, outp, linux_reclen))) + if ((error = copyout((caddr_t)&idb, outp, linux_reclen))) goto out; /* advance past this real entry */ inp += reclen; @@ -343,7 +515,7 @@ again: } /* if we squished out the whole block, try again */ - if (outp == (void *)SCARG(uap, dent)) + if (outp == (caddr_t)SCARG(uap, dent)) goto again; fp->f_offset = off; /* update the vnode offset */ @@ -355,6 +527,6 @@ out: free(cookiebuf, M_TEMP); free(tbuf, M_TEMP); out1: - fd_putfile(SCARG(uap, fd)); + FILE_UNUSE(fp, p); return error; }