[BACK]Return to xfs_syscalls-common.c CVS log [TXT][DIR] Up to [local] / sys / xfs

Annotation of sys/xfs/xfs_syscalls-common.c, Revision 1.1

1.1     ! nbrk        1: /*
        !             2:  * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
        !             3:  * (Royal Institute of Technology, Stockholm, Sweden).
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  *
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  *
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  *
        !            17:  * 3. Neither the name of the Institute nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #include <xfs/xfs_locl.h>
        !            35:
        !            36: RCSID("$arla: xfs_syscalls-common.c,v 1.72 2003/01/19 20:53:49 lha Exp $");
        !            37:
        !            38: /*
        !            39:  * NNPFS system calls.
        !            40:  */
        !            41:
        !            42: #include <xfs/xfs_syscalls.h>
        !            43: #include <xfs/xfs_message.h>
        !            44: #include <xfs/xfs_fs.h>
        !            45: #include <xfs/xfs_dev.h>
        !            46: #include <xfs/xfs_node.h>
        !            47: #include <xfs/xfs_vfsops.h>
        !            48: #include <xfs/xfs_deb.h>
        !            49:
        !            50: /* Misc syscalls */
        !            51: #ifdef HAVE_SYS_IOCCOM_H
        !            52: #include <sys/ioccom.h>
        !            53: #elif defined(HAVE_SYS_IOCTL_H)
        !            54: #include <sys/ioctl.h>
        !            55: #endif
        !            56: /*
        !            57:  * XXX - horrible kludge.  If we are openbsd and not building an lkm,
        !            58:  *     then use their headerfile.
        !            59:  */
        !            60: #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(_LKM)
        !            61: #define NNPFS_NOT_LKM 1
        !            62: #elif defined(__FreeBSD__) && !defined(KLD_MODULE)
        !            63: #define NNPFS_NOT_LKM 1
        !            64: #endif
        !            65:
        !            66: #ifdef NNPFS_NOT_LKM
        !            67: #include <xfs/xfs_pioctl.h>
        !            68: #else
        !            69: #include <kafs.h>
        !            70: #endif
        !            71:
        !            72: int (*old_setgroups_func)(syscall_d_thread_t *p, void *v, register_t *retval);
        !            73:
        !            74: #if defined(__FreeBSD__) && __FreeBSD_version >= 500026
        !            75: /*
        !            76:  * XXX This is wrong
        !            77:  */
        !            78: static struct ucred *
        !            79: xfs_crcopy(struct ucred *cr)
        !            80: {
        !            81:     struct ucred *ncr;
        !            82:
        !            83:     if (crshared(cr)) {
        !            84:        ncr = crdup(cr);
        !            85:        crfree(cr);
        !            86:        return ncr;
        !            87:     }
        !            88:     return cr;
        !            89: }
        !            90: #else
        !            91: #define xfs_crcopy crcopy
        !            92: #endif
        !            93:
        !            94:
        !            95: /*
        !            96:  * the syscall entry point
        !            97:  */
        !            98:
        !            99: #ifdef NNPFS_NOT_LKM
        !           100: int
        !           101: sys_xfspioctl(syscall_d_thread_t *proc, void *varg, register_t *return_value)
        !           102: #else
        !           103: int
        !           104: xfspioctl(syscall_d_thread_t *proc, void *varg, register_t *return_value)
        !           105: #endif
        !           106: {
        !           107: #ifdef NNPFS_NOT_LKM
        !           108:     struct sys_xfspioctl_args *arg = (struct sys_xfspioctl_args *) varg;
        !           109: #else
        !           110:     struct sys_pioctl_args *arg = (struct sys_pioctl_args *) varg;
        !           111: #endif
        !           112:     int error = EINVAL;
        !           113:
        !           114:     switch (SCARG(arg, operation)) {
        !           115:     case AFSCALL_PIOCTL:
        !           116:        error = xfs_pioctl_call(syscall_thread_to_thread(proc),
        !           117:                                  varg, return_value);
        !           118:        break;
        !           119:     case AFSCALL_SETPAG:
        !           120: #ifdef HAVE_FREEBSD_THREAD
        !           121:        error = xfs_setpag_call(&xfs_thread_to_cred(proc));
        !           122: #else
        !           123:        error = xfs_setpag_call(&xfs_proc_to_cred(syscall_thread_to_thread(proc)));
        !           124: #endif
        !           125:        break;
        !           126:     default:
        !           127:        NNPFSDEB(XDEBSYS, ("Unimplemeted xfspioctl: %d\n",
        !           128:                         SCARG(arg, operation)));
        !           129:        error = EINVAL;
        !           130:        break;
        !           131:     }
        !           132:
        !           133:     return error;
        !           134: }
        !           135:
        !           136: /*
        !           137:  * Def pag:
        !           138:  *  33536 <= g0 <= 34560
        !           139:  *  32512 <= g1 <= 48896
        !           140:  */
        !           141:
        !           142: #define NNPFS_PAG1_LLIM 33536
        !           143: #define NNPFS_PAG1_ULIM 34560
        !           144: #define NNPFS_PAG2_LLIM 32512
        !           145: #define NNPFS_PAG2_ULIM 48896
        !           146:
        !           147: static gid_t pag_part_one = NNPFS_PAG1_LLIM;
        !           148: static gid_t pag_part_two = NNPFS_PAG2_LLIM;
        !           149:
        !           150: /*
        !           151:  * Is `cred' member of a PAG?
        !           152:  */
        !           153:
        !           154: static int
        !           155: xfs_is_pag(struct ucred *cred)
        !           156: {
        !           157:     /* The first group is the gid of the user ? */
        !           158:
        !           159:     if (cred->cr_ngroups >= 3 &&
        !           160:        cred->cr_groups[1] >= NNPFS_PAG1_LLIM &&
        !           161:        cred->cr_groups[1] <= NNPFS_PAG1_ULIM &&
        !           162:        cred->cr_groups[2] >= NNPFS_PAG2_LLIM &&
        !           163:        cred->cr_groups[2] <= NNPFS_PAG2_ULIM)
        !           164:        return 1;
        !           165:     else
        !           166:        return 0;
        !           167: }
        !           168:
        !           169: /*
        !           170:  * Return the pag used by `cred'
        !           171:  */
        !           172:
        !           173: xfs_pag_t
        !           174: xfs_get_pag(struct ucred *cred)
        !           175: {
        !           176:     if (xfs_is_pag(cred)) {
        !           177:
        !           178:        return (((cred->cr_groups[1] << 16) & 0xFFFF0000) |
        !           179:                ((cred->cr_groups[2] & 0x0000FFFF)));
        !           180:
        !           181:     } else
        !           182:        return cred->cr_uid;           /* XXX */
        !           183: }
        !           184:
        !           185: /*
        !           186:  * Set the pag in `ret_cred' and return a new cred.
        !           187:  */
        !           188:
        !           189: static int
        !           190: store_pag (struct ucred **ret_cred, gid_t part1, gid_t part2)
        !           191: {
        !           192:     struct ucred *cred = *ret_cred;
        !           193:
        !           194:     if (!xfs_is_pag (cred)) {
        !           195:        int i;
        !           196:
        !           197:        if (cred->cr_ngroups + 2 >= NGROUPS)
        !           198:            return E2BIG;
        !           199:
        !           200:        cred = xfs_crcopy (cred);
        !           201:
        !           202:        for (i = cred->cr_ngroups - 1; i > 0; i--) {
        !           203:            cred->cr_groups[i + 2] = cred->cr_groups[i];
        !           204:        }
        !           205:        cred->cr_ngroups += 2;
        !           206:     } else {
        !           207:        cred = xfs_crcopy (cred);
        !           208:     }
        !           209:     cred->cr_groups[1] = part1;
        !           210:     cred->cr_groups[2] = part2;
        !           211:     *ret_cred = cred;
        !           212:
        !           213:     return 0;
        !           214: }
        !           215:
        !           216: /*
        !           217:  * Acquire a new pag in `ret_cred'
        !           218:  */
        !           219:
        !           220: int
        !           221: xfs_setpag_call(struct ucred **ret_cred)
        !           222: {
        !           223:     int ret;
        !           224:
        !           225:     ret = store_pag (ret_cred, pag_part_one, pag_part_two++);
        !           226:     if (ret)
        !           227:        return ret;
        !           228:
        !           229:     if (pag_part_two > NNPFS_PAG2_ULIM) {
        !           230:        pag_part_one++;
        !           231:        pag_part_two = NNPFS_PAG2_LLIM;
        !           232:     }
        !           233:     return 0;
        !           234: }
        !           235:
        !           236: #ifndef NNPFS_NOT_LKM
        !           237: /*
        !           238:  * remove a pag
        !           239:  */
        !           240:
        !           241: static int
        !           242: xfs_unpag (struct ucred *cred)
        !           243: {
        !           244:     while (xfs_is_pag (cred)) {
        !           245:        int i;
        !           246:
        !           247:        for (i = 0; i < cred->cr_ngroups - 2; ++i)
        !           248:            cred->cr_groups[i] = cred->cr_groups[i+2];
        !           249:        cred->cr_ngroups -= 2;
        !           250:     }
        !           251:     return 0;
        !           252: }
        !           253:
        !           254: /*
        !           255:  * A wrapper around setgroups that preserves the pag.
        !           256:  */
        !           257:
        !           258: int
        !           259: xfs_setgroups (syscall_d_thread_t *p,
        !           260:               void *varg,
        !           261:               register_t *retval)
        !           262: {
        !           263:     struct xfs_setgroups_args *uap = (struct xfs_setgroups_args *)varg;
        !           264: #ifdef HAVE_FREEBSD_THREAD
        !           265:     struct ucred **cred = &xfs_thread_to_cred(p);
        !           266: #else
        !           267:     struct ucred **cred = &xfs_proc_to_cred(syscall_thread_to_thread(p));
        !           268: #endif
        !           269:
        !           270:     if (xfs_is_pag (*cred)) {
        !           271:        gid_t part1, part2;
        !           272:        int ret;
        !           273:
        !           274:        if (SCARG(uap,gidsetsize) + 2 > NGROUPS)
        !           275:            return EINVAL;
        !           276:
        !           277:        part1 = (*cred)->cr_groups[1];
        !           278:        part2 = (*cred)->cr_groups[2];
        !           279:        ret = (*old_setgroups_func) (p, uap, retval);
        !           280:        if (ret)
        !           281:            return ret;
        !           282:        return store_pag (cred, part1, part2);
        !           283:     } else {
        !           284:        int ret;
        !           285:
        !           286:        ret = (*old_setgroups_func) (p, uap, retval);
        !           287:        /* don't support setting a PAG */
        !           288:        if (xfs_is_pag (*cred)) {
        !           289:            xfs_unpag (*cred);
        !           290:            return EINVAL;
        !           291:        }
        !           292:        return ret;
        !           293:     }
        !           294: }
        !           295: #endif /* !NNPFS_NOT_LKM */
        !           296:
        !           297: /*
        !           298:  * Return the vnode corresponding to `pathptr'
        !           299:  */
        !           300:
        !           301: static int
        !           302: lookup_node (const char *pathptr,
        !           303:             int follow_links_p,
        !           304:             struct vnode **res,
        !           305:             d_thread_t *proc)
        !           306: {
        !           307:     int error;
        !           308:     char path[MAXPATHLEN];
        !           309: #ifdef __osf__
        !           310:     struct nameidata *ndp = &u.u_nd;
        !           311: #else
        !           312:     struct nameidata nd, *ndp = &nd;
        !           313: #endif
        !           314:     struct vnode *vp;
        !           315:     size_t count;
        !           316:
        !           317:     NNPFSDEB(XDEBSYS, ("xfs_syscall: looking up: %lx\n",
        !           318:                     (unsigned long)pathptr));
        !           319:
        !           320:     error = copyinstr((char *) pathptr, path, MAXPATHLEN, &count);
        !           321:
        !           322:     NNPFSDEB(XDEBSYS, ("xfs_syscall: looking up: %s, error: %d\n", path, error));
        !           323:
        !           324:     if (error)
        !           325:        return error;
        !           326:
        !           327:     NDINIT(ndp, LOOKUP,
        !           328:           follow_links_p ? FOLLOW : 0,
        !           329:           UIO_SYSSPACE, path, proc);
        !           330:
        !           331:     error = namei(ndp);
        !           332:
        !           333:     if (error != 0) {
        !           334:        NNPFSDEB(XDEBSYS, ("xfs_syscall: error during namei: %d\n", error));
        !           335:        return EINVAL;
        !           336:     }
        !           337:
        !           338:     vp = ndp->ni_vp;
        !           339:
        !           340:     *res = vp;
        !           341:     return 0;
        !           342: }
        !           343:
        !           344: /*
        !           345:  * implement xfs fhget in a way that should be compatible with the native
        !           346:  * getfh
        !           347:  */
        !           348:
        !           349: static int
        !           350: getfh_compat (d_thread_t *p,
        !           351:              struct ViceIoctl *vice_ioctl,
        !           352:              struct vnode *vp)
        !           353: {
        !           354:     /* This is to be same as getfh */
        !           355:     fhandle_t fh;
        !           356:     int error;
        !           357:
        !           358:     bzero((caddr_t)&fh, sizeof(fh));
        !           359:     fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
        !           360: #if __osf__
        !           361:     VFS_VPTOFH(vp, &fh.fh_fid, error);
        !           362: #else
        !           363:     error = VFS_VPTOFH(vp, &fh.fh_fid);
        !           364: #endif
        !           365:     if (error)
        !           366:        return error;
        !           367:
        !           368:     if (vice_ioctl->out_size < sizeof(fh))
        !           369:        return EINVAL;
        !           370:
        !           371:     return copyout((caddr_t)&fh, vice_ioctl->out, sizeof (fh));
        !           372: }
        !           373:
        !           374: /*
        !           375:  * implement xfs fhget by combining (dev, ino, generation)
        !           376:  */
        !           377:
        !           378: #ifndef __OpenBSD__
        !           379: static int
        !           380: trad_fhget (d_thread_t *p,
        !           381:            struct ViceIoctl *vice_ioctl,
        !           382:            struct vnode *vp)
        !           383: {
        !           384:     int error;
        !           385:     struct mount *mnt;
        !           386:     struct vattr vattr;
        !           387:     size_t len;
        !           388:     struct xfs_fhandle_t xfs_handle;
        !           389:     struct xfs_fh_args fh_args;
        !           390:
        !           391: #ifdef HAVE_FREEBSD_THREAD
        !           392:     xfs_vop_getattr(vp, &vattr, xfs_thread_to_cred(p), p, error);
        !           393: #else
        !           394:     xfs_vop_getattr(vp, &vattr, xfs_proc_to_cred(p), p, error);
        !           395: #endif
        !           396:     if (error)
        !           397:        return error;
        !           398:
        !           399:     mnt = vp->v_mount;
        !           400:
        !           401:     SCARG(&fh_args, fsid)   = mnt->mnt_stat.f_fsid;
        !           402:     SCARG(&fh_args, fileid) = vattr.va_fileid;
        !           403:     SCARG(&fh_args, gen)    = vattr.va_gen;
        !           404:
        !           405:     xfs_handle.len = sizeof(fh_args);
        !           406:     memcpy (xfs_handle.fhdata, &fh_args, sizeof(fh_args));
        !           407:     len = sizeof(xfs_handle);
        !           408:
        !           409:     if (vice_ioctl->out_size < len)
        !           410:        return EINVAL;
        !           411:
        !           412:     error = copyout (&xfs_handle, vice_ioctl->out, len);
        !           413:     if (error) {
        !           414:        NNPFSDEB(XDEBSYS, ("fhget_call: copyout failed: %d\n", error));
        !           415:     }
        !           416:     return error;
        !           417: }
        !           418: #endif  /* ! __OpenBSD__ */
        !           419:
        !           420: /*
        !           421:  * return file handle of `vp' in vice_ioctl->out
        !           422:  * vp is vrele:d
        !           423:  */
        !           424:
        !           425: static int
        !           426: fhget_call (d_thread_t *p,
        !           427:            struct ViceIoctl *vice_ioctl,
        !           428:            struct vnode *vp)
        !           429: {
        !           430:     int error;
        !           431:
        !           432:     NNPFSDEB(XDEBSYS, ("fhget_call\n"));
        !           433:
        !           434:     if (vp == NULL)
        !           435:        return EBADF;
        !           436:
        !           437: #if defined(__APPLE__) || defined(__osf__)
        !           438:     error = EINVAL; /* XXX: Leaks vnodes if fhget/fhopen is used */
        !           439:     goto out;
        !           440: #endif
        !           441:
        !           442:     error = xfs_suser (p);
        !           443:     if (error)
        !           444:        goto out;
        !           445:
        !           446: #if (defined(HAVE_GETFH) && defined(HAVE_FHOPEN)) || defined(__osf__)
        !           447:     error = getfh_compat (p, vice_ioctl, vp);
        !           448: #else
        !           449:     error = trad_fhget (p, vice_ioctl, vp);
        !           450: #endif /* HAVE_GETFH && HAVE_FHOPEN */
        !           451: out:
        !           452:     vrele(vp);
        !           453:     return error;
        !           454: }
        !           455:
        !           456: /*
        !           457:  * open the file specified in `vice_ioctl->in'
        !           458:  */
        !           459:
        !           460: static int
        !           461: fhopen_call (d_thread_t *p,
        !           462:             struct ViceIoctl *vice_ioctl,
        !           463:             struct vnode *vp,
        !           464:             int flags,
        !           465:             register_t *retval)
        !           466: {
        !           467:
        !           468:     NNPFSDEB(XDEBSYS, ("fhopen_call: flags = %d\n", flags));
        !           469:
        !           470:     if (vp != NULL) {
        !           471:        vrele (vp);
        !           472:        return EINVAL;
        !           473:     }
        !           474:
        !           475: #if defined(__APPLE__) || defined(__osf__)
        !           476:     return EINVAL; /* XXX: Leaks vnodes if fhget/fhopen is used */
        !           477: #endif
        !           478:
        !           479:     return xfs_fhopen (p,
        !           480:                       (struct xfs_fhandle_t *)vice_ioctl->in,
        !           481:                       flags,
        !           482:                       retval);
        !           483: }
        !           484:
        !           485: /*
        !           486:  * Send the pioctl to arlad
        !           487:  */
        !           488:
        !           489: static int
        !           490: remote_pioctl (d_thread_t *p,
        !           491:               struct sys_pioctl_args *arg,
        !           492:               struct ViceIoctl *vice_ioctl,
        !           493:               struct vnode *vp)
        !           494: {
        !           495:     int error = 0;
        !           496:     struct xfs_message_pioctl *msg = NULL;
        !           497:     struct xfs_message_wakeup_data *msg2;
        !           498:
        !           499:     msg = malloc(sizeof(struct xfs_message_symlink), M_TEMP, M_WAITOK);
        !           500:     if (msg == NULL) {
        !           501:         error = ENOMEM;
        !           502:        goto done;
        !           503:     }
        !           504:     memset(msg, 0, sizeof(*msg));
        !           505:
        !           506:     if (vp != NULL) {
        !           507:        struct xfs_node *xn;
        !           508:
        !           509:        if (vp->v_tag != VT_XFS) {
        !           510:            NNPFSDEB(XDEBSYS, ("xfs_syscall: file is not in afs\n"));
        !           511:            vrele(vp);
        !           512:            error = EINVAL;
        !           513:            goto done;
        !           514:        }
        !           515:
        !           516:        xn = VNODE_TO_XNODE(vp);
        !           517:
        !           518:        msg->handle = xn->handle;
        !           519:        vrele(vp);
        !           520:     }
        !           521:
        !           522:     if (vice_ioctl->in_size < 0) {
        !           523:        printf("xfs: remote pioctl: got a negative data size: opcode: %d",
        !           524:               SCARG(arg, a_opcode));
        !           525:        error = EINVAL;
        !           526:        goto done;
        !           527:     }
        !           528:
        !           529:     if (vice_ioctl->in_size > NNPFS_MSG_MAX_DATASIZE) {
        !           530:        printf("xfs_pioctl_call: got a humongous in packet: opcode: %d",
        !           531:               SCARG(arg, a_opcode));
        !           532:        error = EINVAL;
        !           533:        goto done;
        !           534:     }
        !           535:     if (vice_ioctl->in_size != 0) {
        !           536:        error = copyin(vice_ioctl->in, msg->msg, vice_ioctl->in_size);
        !           537:        if (error)
        !           538:          goto done;
        !           539:     }
        !           540:
        !           541:     msg->header.opcode = NNPFS_MSG_PIOCTL;
        !           542:     msg->header.size = sizeof(*msg);
        !           543:     msg->opcode = SCARG(arg, a_opcode);
        !           544:
        !           545:     msg->insize = vice_ioctl->in_size;
        !           546:     msg->outsize = vice_ioctl->out_size;
        !           547: #ifdef HAVE_FREEBSD_THREAD
        !           548:     msg->cred.uid = xfs_thread_to_euid(p);
        !           549:     msg->cred.pag = xfs_get_pag(xfs_thread_to_cred(p));
        !           550: #else
        !           551:     msg->cred.uid = xfs_proc_to_euid(p);
        !           552:     msg->cred.pag = xfs_get_pag(xfs_proc_to_cred(p));
        !           553: #endif
        !           554:
        !           555:     error = xfs_message_rpc(0, &(msg->header), sizeof(*msg), p); /* XXX */
        !           556:     msg2 = (struct xfs_message_wakeup_data *) msg;
        !           557:
        !           558:     if (error == 0)
        !           559:        error = msg2->error;
        !           560:     if (error == ENODEV)
        !           561:        error = EINVAL;
        !           562:
        !           563:     if (error == 0 && msg2->header.opcode == NNPFS_MSG_WAKEUP_DATA) {
        !           564:        int len;
        !           565:
        !           566:        len = msg2->len;
        !           567:        if (len > vice_ioctl->out_size)
        !           568:            len = vice_ioctl->out_size;
        !           569:        if (len > NNPFS_MSG_MAX_DATASIZE)
        !           570:            len = NNPFS_MSG_MAX_DATASIZE;
        !           571:        if (len < 0)
        !           572:            len = 0;
        !           573:
        !           574:        error = copyout(msg2->msg, vice_ioctl->out, len);
        !           575:     }
        !           576:  done:
        !           577:     free(msg, M_TEMP);
        !           578:     return error;
        !           579: }
        !           580:
        !           581: static int
        !           582: xfs_debug (d_thread_t *p,
        !           583:           struct ViceIoctl *vice_ioctl)
        !           584: {
        !           585:     int32_t flags;
        !           586:     int error;
        !           587:
        !           588:     if (vice_ioctl->in_size != 0) {
        !           589:        if (vice_ioctl->in_size < sizeof(int32_t))
        !           590:            return EINVAL;
        !           591:
        !           592:        error = xfs_suser (p);
        !           593:        if (error)
        !           594:            return error;
        !           595:
        !           596:        error = copyin (vice_ioctl->in,
        !           597:                        &flags,
        !           598:                        sizeof(flags));
        !           599:        if (error)
        !           600:            return error;
        !           601:
        !           602:        xfsdeb = flags;
        !           603:     }
        !           604:
        !           605:     if (vice_ioctl->out_size != 0) {
        !           606:        if (vice_ioctl->out_size < sizeof(int32_t))
        !           607:            return EINVAL;
        !           608:
        !           609:        error = copyout (&xfsdeb,
        !           610:                         vice_ioctl->out,
        !           611:                         sizeof(int32_t));
        !           612:        if (error)
        !           613:            return error;
        !           614:     }
        !           615:
        !           616:     return 0;
        !           617: }
        !           618:
        !           619:
        !           620: /*
        !           621:  * Handle `pioctl'
        !           622:  */
        !           623:
        !           624: int
        !           625: xfs_pioctl_call(d_thread_t *proc,
        !           626:                struct sys_pioctl_args *arg,
        !           627:                register_t *return_value)
        !           628: {
        !           629:     int error;
        !           630:     struct ViceIoctl vice_ioctl;
        !           631:     char *pathptr;
        !           632:     struct vnode *vp = NULL;
        !           633:
        !           634:     NNPFSDEB(XDEBSYS, ("xfs_syscall(%d, %lx, %d, %lx, %d)\n",
        !           635:                     SCARG(arg, operation),
        !           636:                     (unsigned long)SCARG(arg, a_pathP),
        !           637:                     SCARG(arg, a_opcode),
        !           638:                     (unsigned long)SCARG(arg, a_paramsP),
        !           639:                     SCARG(arg, a_followSymlinks)));
        !           640:
        !           641:     /* Copy in the data structure for us */
        !           642:
        !           643:     error = copyin(SCARG(arg, a_paramsP),
        !           644:                   &vice_ioctl,
        !           645:                   sizeof(vice_ioctl));
        !           646:
        !           647:     if (error)
        !           648:        return error;
        !           649:
        !           650:     pathptr = SCARG(arg, a_pathP);
        !           651:
        !           652:     if (pathptr != NULL) {
        !           653:        error = lookup_node (pathptr, SCARG(arg, a_followSymlinks), &vp,
        !           654:                             proc);
        !           655:        if(error)
        !           656:            return error;
        !           657:     }
        !           658:
        !           659:     switch (SCARG(arg, a_opcode)) {
        !           660:     case VIOC_FHGET :
        !           661:        return fhget_call (proc, &vice_ioctl, vp);
        !           662:     case VIOC_FHOPEN :
        !           663:        return fhopen_call (proc, &vice_ioctl, vp,
        !           664:                            SCARG(arg, a_followSymlinks), return_value);
        !           665:     case VIOC_XFSDEBUG :
        !           666:        if (vp != NULL)
        !           667:            vrele (vp);
        !           668:        return xfs_debug (proc, &vice_ioctl);
        !           669:     default :
        !           670:        NNPFSDEB(XDEBSYS, ("a_opcode = %x\n", SCARG(arg, a_opcode)));
        !           671:        return remote_pioctl (proc, arg, &vice_ioctl, vp);
        !           672:     }
        !           673: }

CVSweb