[BACK]Return to netbsd32_fs.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / netbsd32

Annotation of src/sys/compat/netbsd32/netbsd32_fs.c, Revision 1.36.2.2

1.36.2.2! ad          1: /*     $NetBSD: netbsd32_fs.c,v 1.36.2.1 2007/03/13 16:50:19 ad Exp $  */
1.1       mrg         2:
                      3: /*
                      4:  * Copyright (c) 1998, 2001 Matthew R. Green
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of the author may not be used to endorse or promote products
                     16:  *    derived from this software without specific prior written permission.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
                     23:  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
                     24:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
                     25:  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                     26:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     28:  * SUCH DAMAGE.
                     29:  */
1.7       lukem      30:
                     31: #include <sys/cdefs.h>
1.36.2.2! ad         32: __KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.36.2.1 2007/03/13 16:50:19 ad Exp $");
1.1       mrg        33:
1.5       mrg        34: #if defined(_KERNEL_OPT)
1.1       mrg        35: #include "opt_ktrace.h"
                     36: #endif
                     37:
                     38: #include <sys/param.h>
                     39: #include <sys/systm.h>
                     40: #include <sys/malloc.h>
                     41: #include <sys/mount.h>
                     42: #include <sys/socket.h>
                     43: #include <sys/socketvar.h>
                     44: #include <sys/stat.h>
                     45: #include <sys/time.h>
                     46: #include <sys/ktrace.h>
                     47: #include <sys/resourcevar.h>
                     48: #include <sys/vnode.h>
                     49: #include <sys/file.h>
                     50: #include <sys/filedesc.h>
                     51: #include <sys/namei.h>
1.18      cube       52: #include <sys/statvfs.h>
1.1       mrg        53: #include <sys/syscallargs.h>
                     54: #include <sys/proc.h>
1.22      christos   55: #include <sys/dirent.h>
1.27      elad       56: #include <sys/kauth.h>
1.36.2.1  ad         57: #include <sys/vfs_syscalls.h>
1.1       mrg        58:
                     59: #include <compat/netbsd32/netbsd32.h>
                     60: #include <compat/netbsd32/netbsd32_syscallargs.h>
                     61: #include <compat/netbsd32/netbsd32_conv.h>
1.28      martin     62: #include <compat/sys/mount.h>
1.1       mrg        63:
                     64:
1.23      christos   65: static int dofilereadv32 __P((struct lwp *, int, struct file *, struct netbsd32_iovec *,
1.1       mrg        66:                              int, off_t *, int, register_t *));
1.23      christos   67: static int dofilewritev32 __P((struct lwp *, int, struct file *, struct netbsd32_iovec *,
1.1       mrg        68:                               int,  off_t *, int, register_t *));
1.23      christos   69: static int change_utimes32 __P((struct vnode *, netbsd32_timevalp_t, struct lwp *));
1.1       mrg        70:
                     71: int
1.11      thorpej    72: netbsd32_readv(l, v, retval)
                     73:        struct lwp *l;
1.1       mrg        74:        void *v;
                     75:        register_t *retval;
                     76: {
                     77:        struct netbsd32_readv_args /* {
                     78:                syscallarg(int) fd;
                     79:                syscallarg(const netbsd32_iovecp_t) iovp;
                     80:                syscallarg(int) iovcnt;
                     81:        } */ *uap = v;
                     82:        int fd = SCARG(uap, fd);
1.11      thorpej    83:        struct proc *p = l->l_proc;
1.1       mrg        84:        struct file *fp;
                     85:        struct filedesc *fdp = p->p_fd;
                     86:
1.6       thorpej    87:        if ((fp = fd_getfile(fdp, fd)) == NULL)
                     88:                return (EBADF);
                     89:
                     90:        if ((fp->f_flag & FREAD) == 0)
1.1       mrg        91:                return (EBADF);
                     92:
1.9       jdolecek   93:        FILE_USE(fp);
                     94:
1.23      christos   95:        return (dofilereadv32(l, fd, fp,
1.19      perry      96:            (struct netbsd32_iovec *)NETBSD32PTR64(SCARG(uap, iovp)),
1.10      scw        97:            SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
1.1       mrg        98: }
                     99:
                    100: /* Damn thing copies in the iovec! */
                    101: int
1.23      christos  102: dofilereadv32(l, fd, fp, iovp, iovcnt, offset, flags, retval)
                    103:        struct lwp *l;
1.1       mrg       104:        int fd;
                    105:        struct file *fp;
                    106:        struct netbsd32_iovec *iovp;
                    107:        int iovcnt;
                    108:        off_t *offset;
                    109:        int flags;
                    110:        register_t *retval;
                    111: {
                    112:        struct uio auio;
                    113:        struct iovec *iov;
                    114:        struct iovec *needfree;
                    115:        struct iovec aiov[UIO_SMALLIOV];
                    116:        long i, cnt, error = 0;
                    117:        u_int iovlen;
                    118: #ifdef KTRACE
                    119:        struct iovec *ktriov = NULL;
                    120: #endif
                    121:
                    122:        /* note: can't use iovlen until iovcnt is validated */
                    123:        iovlen = iovcnt * sizeof(struct iovec);
                    124:        if ((u_int)iovcnt > UIO_SMALLIOV) {
1.9       jdolecek  125:                if ((u_int)iovcnt > IOV_MAX) {
                    126:                        error = EINVAL;
                    127:                        goto out;
                    128:                }
                    129:                iov = malloc(iovlen, M_IOV, M_WAITOK);
1.1       mrg       130:                needfree = iov;
                    131:        } else if ((u_int)iovcnt > 0) {
                    132:                iov = aiov;
                    133:                needfree = NULL;
1.9       jdolecek  134:        } else {
                    135:                error = EINVAL;
                    136:                goto out;
                    137:        }
1.1       mrg       138:
                    139:        auio.uio_iov = iov;
                    140:        auio.uio_iovcnt = iovcnt;
                    141:        auio.uio_rw = UIO_READ;
1.24      yamt      142:        auio.uio_vmspace = l->l_proc->p_vmspace;
1.1       mrg       143:        error = netbsd32_to_iovecin(iovp, iov, iovcnt);
                    144:        if (error)
                    145:                goto done;
                    146:        auio.uio_resid = 0;
                    147:        for (i = 0; i < iovcnt; i++) {
                    148:                auio.uio_resid += iov->iov_len;
                    149:                /*
                    150:                 * Reads return ssize_t because -1 is returned on error.
                    151:                 * Therefore we must restrict the length to SSIZE_MAX to
                    152:                 * avoid garbage return values.
                    153:                 */
                    154:                if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
                    155:                        error = EINVAL;
                    156:                        goto done;
                    157:                }
                    158:                iov++;
                    159:        }
                    160: #ifdef KTRACE
                    161:        /*
                    162:         * if tracing, save a copy of iovec
                    163:         */
1.23      christos  164:        if (KTRPOINT(l->l_proc, KTR_GENIO))  {
1.9       jdolecek  165:                ktriov = malloc(iovlen, M_TEMP, M_WAITOK);
1.36      christos  166:                memcpy((void *)ktriov, (void *)auio.uio_iov, iovlen);
1.1       mrg       167:        }
                    168: #endif
                    169:        cnt = auio.uio_resid;
                    170:        error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
                    171:        if (error)
                    172:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    173:                    error == EINTR || error == EWOULDBLOCK))
                    174:                        error = 0;
                    175:        cnt -= auio.uio_resid;
                    176: #ifdef KTRACE
1.23      christos  177:        if (KTRPOINT(l->l_proc, KTR_GENIO))
1.1       mrg       178:                if (error == 0) {
1.23      christos  179:                        ktrgenio(l, fd, UIO_READ, ktriov, cnt,
1.1       mrg       180:                            error);
1.9       jdolecek  181:                free(ktriov, M_TEMP);
1.1       mrg       182:        }
                    183: #endif
                    184:        *retval = cnt;
                    185: done:
                    186:        if (needfree)
1.9       jdolecek  187:                free(needfree, M_IOV);
                    188: out:
1.23      christos  189:        FILE_UNUSE(fp, l);
1.1       mrg       190:        return (error);
                    191: }
                    192:
                    193: int
1.11      thorpej   194: netbsd32_writev(l, v, retval)
                    195:        struct lwp *l;
1.1       mrg       196:        void *v;
                    197:        register_t *retval;
                    198: {
                    199:        struct netbsd32_writev_args /* {
                    200:                syscallarg(int) fd;
                    201:                syscallarg(const netbsd32_iovecp_t) iovp;
                    202:                syscallarg(int) iovcnt;
                    203:        } */ *uap = v;
                    204:        int fd = SCARG(uap, fd);
                    205:        struct file *fp;
1.11      thorpej   206:        struct proc *p = l->l_proc;
1.1       mrg       207:        struct filedesc *fdp = p->p_fd;
                    208:
1.6       thorpej   209:        if ((fp = fd_getfile(fdp, fd)) == NULL)
                    210:                return (EBADF);
                    211:
                    212:        if ((fp->f_flag & FWRITE) == 0)
1.1       mrg       213:                return (EBADF);
                    214:
1.9       jdolecek  215:        FILE_USE(fp);
                    216:
1.23      christos  217:        return (dofilewritev32(l, fd, fp,
1.10      scw       218:            (struct netbsd32_iovec *)NETBSD32PTR64(SCARG(uap, iovp)),
                    219:            SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
1.1       mrg       220: }
                    221:
                    222: int
1.23      christos  223: dofilewritev32(l, fd, fp, iovp, iovcnt, offset, flags, retval)
                    224:        struct lwp *l;
1.1       mrg       225:        int fd;
                    226:        struct file *fp;
                    227:        struct netbsd32_iovec *iovp;
                    228:        int iovcnt;
                    229:        off_t *offset;
                    230:        int flags;
                    231:        register_t *retval;
                    232: {
                    233:        struct uio auio;
                    234:        struct iovec *iov;
                    235:        struct iovec *needfree;
                    236:        struct iovec aiov[UIO_SMALLIOV];
1.23      christos  237:        struct proc *p = l->l_proc;
1.1       mrg       238:        long i, cnt, error = 0;
                    239:        u_int iovlen;
                    240: #ifdef KTRACE
                    241:        struct iovec *ktriov = NULL;
                    242: #endif
                    243:
                    244:        /* note: can't use iovlen until iovcnt is validated */
                    245:        iovlen = iovcnt * sizeof(struct iovec);
                    246:        if ((u_int)iovcnt > UIO_SMALLIOV) {
1.9       jdolecek  247:                if ((u_int)iovcnt > IOV_MAX) {
                    248:                        error = EINVAL;
                    249:                        goto out;
                    250:                }
                    251:                iov = malloc(iovlen, M_IOV, M_WAITOK);
1.1       mrg       252:                needfree = iov;
                    253:        } else if ((u_int)iovcnt > 0) {
                    254:                iov = aiov;
                    255:                needfree = NULL;
1.9       jdolecek  256:        } else {
                    257:                error = EINVAL;
                    258:                goto out;
                    259:        }
1.1       mrg       260:
                    261:        auio.uio_iov = iov;
                    262:        auio.uio_iovcnt = iovcnt;
                    263:        auio.uio_rw = UIO_WRITE;
1.24      yamt      264:        auio.uio_vmspace = l->l_proc->p_vmspace;
1.1       mrg       265:        error = netbsd32_to_iovecin(iovp, iov, iovcnt);
                    266:        if (error)
                    267:                goto done;
                    268:        auio.uio_resid = 0;
                    269:        for (i = 0; i < iovcnt; i++) {
                    270:                auio.uio_resid += iov->iov_len;
                    271:                /*
                    272:                 * Writes return ssize_t because -1 is returned on error.
                    273:                 * Therefore we must restrict the length to SSIZE_MAX to
                    274:                 * avoid garbage return values.
                    275:                 */
                    276:                if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
                    277:                        error = EINVAL;
                    278:                        goto done;
                    279:                }
                    280:                iov++;
                    281:        }
                    282: #ifdef KTRACE
                    283:        /*
                    284:         * if tracing, save a copy of iovec
                    285:         */
1.14      fvdl      286:        if (KTRPOINT(p, KTR_GENIO))  {
1.9       jdolecek  287:                ktriov = malloc(iovlen, M_TEMP, M_WAITOK);
1.36      christos  288:                memcpy((void *)ktriov, (void *)auio.uio_iov, iovlen);
1.1       mrg       289:        }
                    290: #endif
                    291:        cnt = auio.uio_resid;
                    292:        error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
                    293:        if (error) {
                    294:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    295:                    error == EINTR || error == EWOULDBLOCK))
                    296:                        error = 0;
                    297:                if (error == EPIPE)
1.14      fvdl      298:                        psignal(p, SIGPIPE);
1.1       mrg       299:        }
                    300:        cnt -= auio.uio_resid;
                    301: #ifdef KTRACE
1.14      fvdl      302:        if (KTRPOINT(p, KTR_GENIO))
1.1       mrg       303:                if (error == 0) {
1.23      christos  304:                        ktrgenio(l, fd, UIO_WRITE, ktriov, cnt,
1.1       mrg       305:                            error);
1.9       jdolecek  306:                free(ktriov, M_TEMP);
1.1       mrg       307:        }
                    308: #endif
                    309:        *retval = cnt;
                    310: done:
                    311:        if (needfree)
1.9       jdolecek  312:                free(needfree, M_IOV);
                    313: out:
1.23      christos  314:        FILE_UNUSE(fp, l);
1.1       mrg       315:        return (error);
                    316: }
                    317:
                    318: int
1.11      thorpej   319: netbsd32_utimes(l, v, retval)
                    320:        struct lwp *l;
1.1       mrg       321:        void *v;
                    322:        register_t *retval;
                    323: {
                    324:        struct netbsd32_utimes_args /* {
                    325:                syscallarg(const netbsd32_charp) path;
                    326:                syscallarg(const netbsd32_timevalp_t) tptr;
                    327:        } */ *uap = v;
                    328:        int error;
                    329:        struct nameidata nd;
                    330:
1.10      scw       331:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE,
1.23      christos  332:            (char *)NETBSD32PTR64(SCARG(uap, path)), l);
1.1       mrg       333:        if ((error = namei(&nd)) != 0)
                    334:                return (error);
                    335:
1.23      christos  336:        error = change_utimes32(nd.ni_vp, SCARG(uap, tptr), l);
1.1       mrg       337:
                    338:        vrele(nd.ni_vp);
                    339:        return (error);
                    340: }
                    341:
                    342: /*
                    343:  * Common routine to set access and modification times given a vnode.
                    344:  */
                    345: static int
1.23      christos  346: change_utimes32(vp, tptr, l)
1.1       mrg       347:        struct vnode *vp;
                    348:        netbsd32_timevalp_t tptr;
1.23      christos  349:        struct lwp *l;
1.1       mrg       350: {
                    351:        struct netbsd32_timeval tv32[2];
                    352:        struct timeval tv[2];
                    353:        struct vattr vattr;
                    354:        int error;
                    355:
                    356:        VATTR_NULL(&vattr);
1.15      fvdl      357:        if (tptr == 0) {
1.1       mrg       358:                microtime(&tv[0]);
                    359:                tv[1] = tv[0];
                    360:                vattr.va_vaflags |= VA_UTIMES_NULL;
                    361:        } else {
1.36      christos  362:                error = copyin((void *)NETBSD32PTR64(tptr), tv32,
1.10      scw       363:                    sizeof(tv32));
1.1       mrg       364:                if (error)
                    365:                        return (error);
                    366:                netbsd32_to_timeval(&tv32[0], &tv[0]);
                    367:                netbsd32_to_timeval(&tv32[1], &tv[1]);
                    368:        }
1.31      ad        369:        VOP_LEASE(vp, l, l->l_cred, LEASE_WRITE);
1.1       mrg       370:        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
                    371:        vattr.va_atime.tv_sec = tv[0].tv_sec;
                    372:        vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
                    373:        vattr.va_mtime.tv_sec = tv[1].tv_sec;
                    374:        vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
1.31      ad        375:        error = VOP_SETATTR(vp, &vattr, l->l_cred, l);
1.1       mrg       376:        VOP_UNLOCK(vp, 0);
                    377:        return (error);
                    378: }
                    379:
                    380: int
1.18      cube      381: netbsd32_statvfs1(l, v, retval)
1.11      thorpej   382:        struct lwp *l;
1.1       mrg       383:        void *v;
                    384:        register_t *retval;
                    385: {
1.18      cube      386:        struct netbsd32_statvfs1_args /* {
1.1       mrg       387:                syscallarg(const netbsd32_charp) path;
1.18      cube      388:                syscallarg(netbsd32_statvfsp_t) buf;
                    389:                syscallarg(int) flags;
1.1       mrg       390:        } */ *uap = v;
                    391:        struct mount *mp;
1.18      cube      392:        struct statvfs *sbuf;
                    393:        struct netbsd32_statvfs *s32;
                    394:        struct nameidata nd;
1.1       mrg       395:        int error;
                    396:
1.10      scw       397:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE,
1.23      christos  398:            (char *)NETBSD32PTR64(SCARG(uap, path)), l);
1.1       mrg       399:        if ((error = namei(&nd)) != 0)
                    400:                return (error);
1.18      cube      401:        /* Allocating on the stack would blow it up */
                    402:        sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
                    403:            M_WAITOK);
1.1       mrg       404:        mp = nd.ni_vp->v_mount;
                    405:        vrele(nd.ni_vp);
1.23      christos  406:        if ((error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 1)) != 0)
1.18      cube      407:                goto out;
                    408:        s32 = (struct netbsd32_statvfs *)
                    409:            malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
                    410:        netbsd32_from_statvfs(sbuf, s32);
1.36      christos  411:        error = copyout(s32, (void *)NETBSD32PTR64(SCARG(uap, buf)),
1.18      cube      412:            sizeof(struct netbsd32_statvfs));
                    413:        free(s32, M_TEMP);
                    414: out:
                    415:        free(sbuf, M_TEMP);
                    416:        return (error);
1.1       mrg       417: }
                    418:
                    419: int
1.18      cube      420: netbsd32_fstatvfs1(l, v, retval)
1.11      thorpej   421:        struct lwp *l;
1.1       mrg       422:        void *v;
                    423:        register_t *retval;
                    424: {
1.18      cube      425:        struct netbsd32_fstatvfs1_args /* {
1.1       mrg       426:                syscallarg(int) fd;
1.18      cube      427:                syscallarg(netbsd32_statvfsp_t) buf;
                    428:                syscallarg(int) flags;
1.1       mrg       429:        } */ *uap = v;
1.18      cube      430:        struct proc *p = l->l_proc;
1.1       mrg       431:        struct file *fp;
                    432:        struct mount *mp;
1.18      cube      433:        struct statvfs *sbuf;
                    434:        struct netbsd32_statvfs *s32;
1.1       mrg       435:        int error;
                    436:
                    437:        /* getvnode() will use the descriptor for us */
1.14      fvdl      438:        if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
1.1       mrg       439:                return (error);
                    440:        mp = ((struct vnode *)fp->f_data)->v_mount;
1.18      cube      441:        sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
                    442:            M_WAITOK);
1.23      christos  443:        if ((error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 1)) != 0)
1.1       mrg       444:                goto out;
1.18      cube      445:        s32 = (struct netbsd32_statvfs *)
                    446:            malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
                    447:        netbsd32_from_statvfs(sbuf, s32);
1.36      christos  448:        error = copyout(s32, (void *)NETBSD32PTR64(SCARG(uap, buf)),
1.18      cube      449:            sizeof(struct netbsd32_statvfs));
                    450:        free(s32, M_TEMP);
1.1       mrg       451:  out:
1.18      cube      452:        free(sbuf, M_TEMP);
1.23      christos  453:        FILE_UNUSE(fp, l);
1.18      cube      454:        return error;
                    455: }
                    456:
                    457: int
                    458: netbsd32_getvfsstat(l, v, retval)
                    459:        struct lwp *l;
                    460:        void *v;
                    461:        register_t *retval;
                    462: {
                    463:        struct netbsd32_getvfsstat_args /* {
                    464:                syscallarg(netbsd32_statvfsp_t) buf;
                    465:                syscallarg(netbsd32_size_t) bufsize;
                    466:                syscallarg(int) flags;
                    467:        } */ *uap = v;
                    468:        int root = 0;
                    469:        struct proc *p = l->l_proc;
                    470:        struct mount *mp, *nmp;
                    471:        struct statvfs *sbuf;
                    472:        struct netbsd32_statvfs *sfsp;
                    473:        struct netbsd32_statvfs *s32;
                    474:        size_t count, maxcount;
                    475:        int error = 0;
                    476:
                    477:        maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statvfs);
                    478:        sfsp = (struct netbsd32_statvfs *)NETBSD32PTR64(SCARG(uap, buf));
                    479:        sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
                    480:            M_WAITOK);
                    481:        s32 = (struct netbsd32_statvfs *)
                    482:            malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
1.36.2.2! ad        483:        mutex_enter(&mountlist_lock);
1.25      cube      484:        count = 0;
1.18      cube      485:        for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
                    486:             mp = nmp) {
1.36.2.2! ad        487:                if (vfs_busy(mp, LK_NOWAIT, &mountlist_lock)) {
1.18      cube      488:                        nmp = CIRCLEQ_NEXT(mp, mnt_list);
                    489:                        continue;
                    490:                }
                    491:                if (sfsp && count < maxcount) {
1.23      christos  492:                        error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 0);
1.18      cube      493:                        if (error) {
1.36.2.2! ad        494:                                mutex_enter(&mountlist_lock);
1.18      cube      495:                                nmp = CIRCLEQ_NEXT(mp, mnt_list);
                    496:                                vfs_unbusy(mp);
                    497:                                continue;
                    498:                        }
                    499:                        netbsd32_from_statvfs(sbuf, s32);
                    500:                        error = copyout(s32, sfsp, sizeof(*sfsp));
                    501:                        if (error) {
                    502:                                vfs_unbusy(mp);
                    503:                                goto out;
                    504:                        }
                    505:                        sfsp++;
                    506:                        root |= strcmp(sbuf->f_mntonname, "/") == 0;
                    507:                }
                    508:                count++;
1.36.2.2! ad        509:                mutex_enter(&mountlist_lock);
1.18      cube      510:                nmp = CIRCLEQ_NEXT(mp, mnt_list);
                    511:                vfs_unbusy(mp);
                    512:        }
1.36.2.2! ad        513:        mutex_exit(&mountlist_lock);
1.18      cube      514:        if (root == 0 && p->p_cwdi->cwdi_rdir) {
                    515:                /*
                    516:                 * fake a root entry
                    517:                 */
1.23      christos  518:                if ((error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount, sbuf, l,
1.18      cube      519:                    SCARG(uap, flags), 1)) != 0)
                    520:                        goto out;
                    521:                if (sfsp) {
                    522:                        netbsd32_from_statvfs(sbuf, s32);
                    523:                        error = copyout(s32, sfsp, sizeof(*sfsp));
                    524:                }
                    525:                count++;
                    526:        }
                    527:        if (sfsp && count > maxcount)
                    528:                *retval = maxcount;
                    529:        else
                    530:                *retval = count;
                    531:
                    532: out:
                    533:        free(s32, M_TEMP);
                    534:        free(sbuf, M_TEMP);
                    535:        return (error);
                    536: }
                    537:
                    538: int
1.32      martin    539: netbsd32___fhstatvfs140(l, v, retval)
1.18      cube      540:        struct lwp *l;
                    541:        void *v;
                    542:        register_t *retval;
                    543: {
1.32      martin    544:        struct netbsd32___fhstatvfs140_args /* {
                    545:                syscallarg(const netbsd32_pointer_t) fhp;
                    546:                syscallarg(netbsd32_size_t) fh_size;
1.18      cube      547:                syscallarg(netbsd32_statvfsp_t) buf;
                    548:                syscallarg(int) flags;
                    549:        } */ *uap = v;
                    550:        struct statvfs *sbuf;
                    551:        struct netbsd32_statvfs *s32;
1.29      martin    552:        fhandle_t *fh;
1.18      cube      553:        struct vnode *vp;
                    554:        int error;
                    555:
                    556:        /*
                    557:         * Must be super user
                    558:         */
1.34      elad      559:        if ((error = kauth_authorize_system(l->l_cred,
                    560:            KAUTH_SYSTEM_FILEHANDLE, 0, NULL, NULL, NULL)) != 0)
1.18      cube      561:                return error;
                    562:
1.33      yamt      563:        if ((error = vfs_copyinfh_alloc(NETBSD32PTR64(SCARG(uap, fhp)),
1.32      martin    564:            SCARG(uap, fh_size), &fh)) != 0)
1.29      martin    565:                goto bad;
                    566:        if ((error = vfs_fhtovp(fh, &vp)) != 0)
                    567:                goto bad;
1.18      cube      568:
                    569:        sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
                    570:            M_WAITOK);
1.29      martin    571:        error = dostatvfs(vp->v_mount, sbuf, l, SCARG(uap, flags), 1);
                    572:        vput(vp);
                    573:        if (error != 0)
1.18      cube      574:                goto out;
                    575:
                    576:        s32 = (struct netbsd32_statvfs *)
                    577:            malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
                    578:        netbsd32_from_statvfs(sbuf, s32);
1.36      christos  579:        error = copyout(s32, (void *)NETBSD32PTR64(SCARG(uap, buf)),
1.18      cube      580:            sizeof(struct netbsd32_statvfs));
                    581:        free(s32, M_TEMP);
                    582:
                    583: out:
                    584:        free(sbuf, M_TEMP);
1.29      martin    585: bad:
                    586:        vfs_copyinfh_free(fh);
1.1       mrg       587:        return (error);
                    588: }
                    589:
                    590: int
1.11      thorpej   591: netbsd32_futimes(l, v, retval)
                    592:        struct lwp *l;
1.1       mrg       593:        void *v;
                    594:        register_t *retval;
                    595: {
                    596:        struct netbsd32_futimes_args /* {
                    597:                syscallarg(int) fd;
                    598:                syscallarg(const netbsd32_timevalp_t) tptr;
                    599:        } */ *uap = v;
                    600:        int error;
                    601:        struct file *fp;
1.14      fvdl      602:        struct proc *p = l->l_proc;
1.1       mrg       603:
                    604:        /* getvnode() will use the descriptor for us */
1.14      fvdl      605:        if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
1.1       mrg       606:                return (error);
                    607:
1.19      perry     608:        error = change_utimes32((struct vnode *)fp->f_data,
1.23      christos  609:                                SCARG(uap, tptr), l);
                    610:        FILE_UNUSE(fp, l);
1.1       mrg       611:        return (error);
                    612: }
                    613:
                    614: int
1.22      christos  615: netbsd32_sys___getdents30(l, v, retval)
1.11      thorpej   616:        struct lwp *l;
1.1       mrg       617:        void *v;
                    618:        register_t *retval;
                    619: {
1.22      christos  620:        struct netbsd32_sys___getdents30_args /* {
1.1       mrg       621:                syscallarg(int) fd;
                    622:                syscallarg(netbsd32_charp) buf;
                    623:                syscallarg(netbsd32_size_t) count;
                    624:        } */ *uap = v;
                    625:        struct file *fp;
                    626:        int error, done;
1.11      thorpej   627:        struct proc *p = l->l_proc;
1.1       mrg       628:
                    629:        /* getvnode() will use the descriptor for us */
                    630:        if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
                    631:                return (error);
                    632:        if ((fp->f_flag & FREAD) == 0) {
                    633:                error = EBADF;
                    634:                goto out;
                    635:        }
1.36      christos  636:        error = vn_readdir(fp, (void *)NETBSD32PTR64(SCARG(uap, buf)),
1.23      christos  637:            UIO_USERSPACE, SCARG(uap, count), &done, l, 0, 0);
1.1       mrg       638:        *retval = done;
                    639:  out:
1.23      christos  640:        FILE_UNUSE(fp, l);
1.1       mrg       641:        return (error);
                    642: }
                    643:
                    644: int
1.11      thorpej   645: netbsd32_lutimes(l, v, retval)
                    646:        struct lwp *l;
1.1       mrg       647:        void *v;
                    648:        register_t *retval;
                    649: {
                    650:        struct netbsd32_lutimes_args /* {
                    651:                syscallarg(const netbsd32_charp) path;
                    652:                syscallarg(const netbsd32_timevalp_t) tptr;
                    653:        } */ *uap = v;
                    654:        int error;
                    655:        struct nameidata nd;
                    656:
1.10      scw       657:        NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE,
1.36      christos  658:            (void *)NETBSD32PTR64(SCARG(uap, path)), l);
1.1       mrg       659:        if ((error = namei(&nd)) != 0)
                    660:                return (error);
                    661:
1.23      christos  662:        error = change_utimes32(nd.ni_vp, SCARG(uap, tptr), l);
1.1       mrg       663:
                    664:        vrele(nd.ni_vp);
                    665:        return (error);
                    666: }
                    667:
                    668: int
1.22      christos  669: netbsd32_sys___stat30(l, v, retval)
1.11      thorpej   670:        struct lwp *l;
1.1       mrg       671:        void *v;
                    672:        register_t *retval;
                    673: {
1.22      christos  674:        struct netbsd32_sys___stat30_args /* {
1.1       mrg       675:                syscallarg(const netbsd32_charp) path;
                    676:                syscallarg(netbsd32_statp_t) ub;
                    677:        } */ *uap = v;
                    678:        struct netbsd32_stat sb32;
                    679:        struct stat sb;
                    680:        int error;
1.36      christos  681:        void *sg;
1.1       mrg       682:        const char *path;
1.14      fvdl      683:        struct proc *p = l->l_proc;
1.1       mrg       684:
1.10      scw       685:        path = (char *)NETBSD32PTR64(SCARG(uap, path));
1.14      fvdl      686:        sg = stackgap_init(p, 0);
1.23      christos  687:        CHECK_ALT_EXIST(l, &sg, path);
1.1       mrg       688:
1.36.2.1  ad        689:        error = do_sys_stat(l, path, FOLLOW, &sb);
1.22      christos  690:        netbsd32_from___stat30(&sb, &sb32);
1.36      christos  691:        error = copyout(&sb32, (void *)NETBSD32PTR64(SCARG(uap, ub)),
1.10      scw       692:            sizeof(sb32));
1.1       mrg       693:        return (error);
                    694: }
                    695:
                    696: int
1.22      christos  697: netbsd32_sys___fstat30(l, v, retval)
1.11      thorpej   698:        struct lwp *l;
1.1       mrg       699:        void *v;
                    700:        register_t *retval;
                    701: {
1.22      christos  702:        struct netbsd32_sys___fstat30_args /* {
1.1       mrg       703:                syscallarg(int) fd;
                    704:                syscallarg(netbsd32_statp_t) sb;
                    705:        } */ *uap = v;
                    706:        int fd = SCARG(uap, fd);
1.14      fvdl      707:        struct proc *p = l->l_proc;
                    708:        struct filedesc *fdp = p->p_fd;
1.1       mrg       709:        struct file *fp;
                    710:        struct netbsd32_stat sb32;
                    711:        struct stat ub;
                    712:        int error = 0;
                    713:
1.6       thorpej   714:        if ((fp = fd_getfile(fdp, fd)) == NULL)
1.1       mrg       715:                return (EBADF);
                    716:
1.3       jdolecek  717:        FILE_USE(fp);
1.23      christos  718:        error = (*fp->f_ops->fo_stat)(fp, &ub, l);
                    719:        FILE_UNUSE(fp, l);
1.3       jdolecek  720:
1.1       mrg       721:        if (error == 0) {
1.22      christos  722:                netbsd32_from___stat30(&ub, &sb32);
1.36      christos  723:                error = copyout(&sb32, (void *)NETBSD32PTR64(SCARG(uap, sb)),
1.10      scw       724:                    sizeof(sb32));
1.1       mrg       725:        }
                    726:        return (error);
                    727: }
                    728:
                    729: int
1.22      christos  730: netbsd32_sys___lstat30(l, v, retval)
1.11      thorpej   731:        struct lwp *l;
1.1       mrg       732:        void *v;
                    733:        register_t *retval;
                    734: {
1.22      christos  735:        struct netbsd32_sys___lstat30_args /* {
1.1       mrg       736:                syscallarg(const netbsd32_charp) path;
                    737:                syscallarg(netbsd32_statp_t) ub;
                    738:        } */ *uap = v;
                    739:        struct netbsd32_stat sb32;
                    740:        struct stat sb;
                    741:        int error;
1.36      christos  742:        void *sg;
1.1       mrg       743:        const char *path;
1.14      fvdl      744:        struct proc *p = l->l_proc;
1.1       mrg       745:
1.10      scw       746:        path = (char *)NETBSD32PTR64(SCARG(uap, path));
1.14      fvdl      747:        sg = stackgap_init(p, 0);
1.23      christos  748:        CHECK_ALT_EXIST(l, &sg, path);
1.1       mrg       749:
1.36.2.1  ad        750:        error = do_sys_stat(l, path, NOFOLLOW, &sb);
1.1       mrg       751:        if (error)
                    752:                return (error);
1.22      christos  753:        netbsd32_from___stat30(&sb, &sb32);
1.36      christos  754:        error = copyout(&sb32, (void *)NETBSD32PTR64(SCARG(uap, ub)),
1.10      scw       755:            sizeof(sb32));
1.1       mrg       756:        return (error);
                    757: }
                    758:
1.32      martin    759: int netbsd32___fhstat40(l, v, retval)
1.26      cube      760:        struct lwp *l;
                    761:        void *v;
                    762:        register_t *retval;
                    763: {
1.32      martin    764:        struct netbsd32___fhstat40_args /* {
                    765:                syscallarg(const netbsd32_pointer_t) fhp;
                    766:                syscallarg(netbsd32_size_t) fh_size;
1.26      cube      767:                syscallarg(netbsd32_statp_t) sb;
                    768:        } */ *uap = v;
                    769:        struct stat sb;
                    770:        struct netbsd32_stat sb32;
                    771:        int error;
1.29      martin    772:        fhandle_t *fh;
1.26      cube      773:        struct vnode *vp;
                    774:
                    775:        /*
                    776:         * Must be super user
                    777:         */
1.34      elad      778:        if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FILEHANDLE,
                    779:            0, NULL, NULL, NULL)))
1.29      martin    780:                return error;
                    781:
1.33      yamt      782:        if ((error = vfs_copyinfh_alloc(NETBSD32PTR64(SCARG(uap, fhp)),
                    783:            SCARG(uap, fh_size), &fh)) != 0)
1.29      martin    784:                goto bad;
1.26      cube      785:
1.29      martin    786:        if ((error = vfs_fhtovp(fh, &vp)) != 0)
                    787:                goto bad;
1.26      cube      788:
                    789:        error = vn_stat(vp, &sb, l);
                    790:        vput(vp);
                    791:        if (error)
1.29      martin    792:                goto bad;
1.26      cube      793:        netbsd32_from___stat30(&sb, &sb32);
                    794:        error = copyout(&sb32, NETBSD32PTR64(SCARG(uap, sb)), sizeof(sb));
1.29      martin    795: bad:
                    796:        vfs_copyinfh_free(fh);
                    797:        return error;
1.26      cube      798: }
                    799:
1.1       mrg       800: int
1.11      thorpej   801: netbsd32_preadv(l, v, retval)
                    802:        struct lwp *l;
1.1       mrg       803:        void *v;
                    804:        register_t *retval;
                    805: {
                    806:        struct netbsd32_preadv_args /* {
                    807:                syscallarg(int) fd;
                    808:                syscallarg(const netbsd32_iovecp_t) iovp;
                    809:                syscallarg(int) iovcnt;
                    810:                syscallarg(int) pad;
                    811:                syscallarg(off_t) offset;
                    812:        } */ *uap = v;
1.14      fvdl      813:        struct proc *p = l->l_proc;
                    814:        struct filedesc *fdp = p->p_fd;
1.1       mrg       815:        struct file *fp;
                    816:        struct vnode *vp;
                    817:        off_t offset;
                    818:        int error, fd = SCARG(uap, fd);
                    819:
1.6       thorpej   820:        if ((fp = fd_getfile(fdp, fd)) == NULL)
                    821:                return (EBADF);
                    822:
                    823:        if ((fp->f_flag & FREAD) == 0)
1.1       mrg       824:                return (EBADF);
                    825:
1.9       jdolecek  826:        FILE_USE(fp);
                    827:
1.1       mrg       828:        vp = (struct vnode *)fp->f_data;
1.9       jdolecek  829:        if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
                    830:                error = ESPIPE;
                    831:                goto out;
                    832:        }
1.1       mrg       833:
                    834:        offset = SCARG(uap, offset);
                    835:
                    836:        /*
                    837:         * XXX This works because no file systems actually
                    838:         * XXX take any action on the seek operation.
                    839:         */
                    840:        if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
1.9       jdolecek  841:                goto out;
1.1       mrg       842:
1.23      christos  843:        return (dofilereadv32(l, fd, fp,
1.10      scw       844:            (struct netbsd32_iovec *)NETBSD32PTR64(SCARG(uap, iovp)),
                    845:            SCARG(uap, iovcnt), &offset, 0, retval));
1.9       jdolecek  846:
                    847: out:
1.23      christos  848:        FILE_UNUSE(fp, l);
1.9       jdolecek  849:        return (error);
1.1       mrg       850: }
                    851:
                    852: int
1.11      thorpej   853: netbsd32_pwritev(l, v, retval)
                    854:        struct lwp *l;
1.1       mrg       855:        void *v;
                    856:        register_t *retval;
                    857: {
                    858:        struct netbsd32_pwritev_args /* {
                    859:                syscallarg(int) fd;
                    860:                syscallarg(const netbsd32_iovecp_t) iovp;
                    861:                syscallarg(int) iovcnt;
                    862:                syscallarg(int) pad;
                    863:                syscallarg(off_t) offset;
                    864:        } */ *uap = v;
1.14      fvdl      865:        struct proc *p = l->l_proc;
                    866:        struct filedesc *fdp = p->p_fd;
1.1       mrg       867:        struct file *fp;
                    868:        struct vnode *vp;
                    869:        off_t offset;
                    870:        int error, fd = SCARG(uap, fd);
                    871:
1.6       thorpej   872:        if ((fp = fd_getfile(fdp, fd)) == NULL)
                    873:                return (EBADF);
                    874:
                    875:        if ((fp->f_flag & FWRITE) == 0)
1.1       mrg       876:                return (EBADF);
                    877:
1.9       jdolecek  878:        FILE_USE(fp);
                    879:
1.1       mrg       880:        vp = (struct vnode *)fp->f_data;
1.9       jdolecek  881:        if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
                    882:                error = ESPIPE;
                    883:                goto out;
                    884:        }
1.1       mrg       885:
                    886:        offset = SCARG(uap, offset);
                    887:
                    888:        /*
                    889:         * XXX This works because no file systems actually
                    890:         * XXX take any action on the seek operation.
                    891:         */
                    892:        if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
1.9       jdolecek  893:                goto out;
1.1       mrg       894:
1.23      christos  895:        return (dofilewritev32(l, fd, fp,
1.10      scw       896:            (struct netbsd32_iovec *)NETBSD32PTR64(SCARG(uap, iovp)),
                    897:            SCARG(uap, iovcnt), &offset, 0, retval));
1.9       jdolecek  898:
                    899: out:
1.23      christos  900:        FILE_UNUSE(fp, l);
1.9       jdolecek  901:        return (error);
1.1       mrg       902: }
                    903:
                    904: /*
                    905:  * Find pathname of process's current directory.
                    906:  *
                    907:  * Use vfs vnode-to-name reverse cache; if that fails, fall back
                    908:  * to reading directory contents.
                    909:  */
1.23      christos  910: /* XXX NH Why does this exist */
1.14      fvdl      911: int
                    912: getcwd_common __P((struct vnode *, struct vnode *,
1.23      christos  913:                   char **, char *, int, int, struct lwp *));
1.14      fvdl      914:
1.19      perry     915: int netbsd32___getcwd(l, v, retval)
1.11      thorpej   916:        struct lwp *l;
1.1       mrg       917:        void   *v;
                    918:        register_t *retval;
                    919: {
                    920:        struct netbsd32___getcwd_args /* {
                    921:                syscallarg(char *) bufp;
                    922:                syscallarg(size_t) length;
                    923:        } */ *uap = v;
1.11      thorpej   924:        struct proc *p = l->l_proc;
1.1       mrg       925:        int     error;
                    926:        char   *path;
                    927:        char   *bp, *bend;
                    928:        int     len = (int)SCARG(uap, length);
                    929:        int     lenused;
                    930:
                    931:        if (len > MAXPATHLEN*4)
                    932:                len = MAXPATHLEN*4;
                    933:        else if (len < 2)
                    934:                return ERANGE;
                    935:
                    936:        path = (char *)malloc(len, M_TEMP, M_WAITOK);
                    937:        if (!path)
                    938:                return ENOMEM;
                    939:
                    940:        bp = &path[len];
                    941:        bend = bp;
                    942:        *(--bp) = '\0';
                    943:
                    944:        /*
                    945:         * 5th argument here is "max number of vnodes to traverse".
                    946:         * Since each entry takes up at least 2 bytes in the output buffer,
                    947:         * limit it to N/2 vnodes for an N byte buffer.
                    948:         */
                    949: #define GETCWD_CHECK_ACCESS 0x0001
                    950:        error = getcwd_common (p->p_cwdi->cwdi_cdir, NULL, &bp, path, len/2,
1.23      christos  951:                               GETCWD_CHECK_ACCESS, l);
1.1       mrg       952:
                    953:        if (error)
                    954:                goto out;
                    955:        lenused = bend - bp;
                    956:        *retval = lenused;
                    957:        /* put the result into user buffer */
1.36      christos  958:        error = copyout(bp, (void *)NETBSD32PTR64(SCARG(uap, bufp)), lenused);
1.1       mrg       959:
                    960: out:
                    961:        free(path, M_TEMP);
                    962:        return error;
                    963: }

CVSweb <webmaster@jp.NetBSD.org>