[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

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