root/sys/compat/netbsd32/netbsd32_quota.c
/*      $NetBSD: netbsd32_quota.c,v 1.3 2020/03/12 15:02:29 pgoyette Exp $      */

/*
 * Copyright (c) 1998, 2001, 2008, 2018 Matthew R. Green
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * from: NetBSD: netbsd32_netbsd.c,v 1.218 2018/08/10 21:44:58 pgoyette Exp
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: netbsd32_quota.c,v 1.3 2020/03/12 15:02:29 pgoyette Exp $");

#ifdef _KERNEL_OPT
#include "opt_quota.h"
#endif

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/quotactl.h>
#include <sys/module.h>
#include <sys/vfs_syscalls.h>
#include <sys/syscallvar.h>

#include <compat/netbsd32/netbsd32.h>
#include <compat/netbsd32/netbsd32_syscall.h>
#include <compat/netbsd32/netbsd32_syscallargs.h>

#ifdef QUOTA
int
netbsd32___quotactl(struct lwp *l, const struct netbsd32___quotactl_args *uap, register_t *retval)
{
        /* {
                syscallarg(const netbsd32_charp) path;
                syscallarg(netbsd32_voidp) args;
        } */
        struct netbsd32_quotactlargs args32;
        struct quotactl_args args;
        int error;

        error = copyin(SCARG_P32(uap, args), &args32, sizeof(args32));
        if (error) {
                return error;
        }

        args.qc_op = args32.qc_op;
        switch (args.qc_op) {
            case QUOTACTL_STAT:
                args.u.stat.qc_info = NETBSD32PTR64(args32.u.stat.qc_info);
                break;
            case QUOTACTL_IDTYPESTAT:
                args.u.idtypestat.qc_idtype = args32.u.idtypestat.qc_idtype;
                args.u.idtypestat.qc_info =
                        NETBSD32PTR64(args32.u.idtypestat.qc_info);
                break;
            case QUOTACTL_OBJTYPESTAT:
                args.u.objtypestat.qc_objtype =
                        args32.u.objtypestat.qc_objtype;
                args.u.objtypestat.qc_info =
                        NETBSD32PTR64(args32.u.objtypestat.qc_info);
                break;
            case QUOTACTL_GET:
                args.u.get.qc_key = NETBSD32PTR64(args32.u.get.qc_key);
                args.u.get.qc_val = NETBSD32PTR64(args32.u.get.qc_val);
                break;
            case QUOTACTL_PUT:
                args.u.put.qc_key = NETBSD32PTR64(args32.u.put.qc_key);
                args.u.put.qc_val = NETBSD32PTR64(args32.u.put.qc_val);
                break;
            case QUOTACTL_DEL:
                args.u.del.qc_key = NETBSD32PTR64(args32.u.del.qc_key);
                break;
            case QUOTACTL_CURSOROPEN:
                args.u.cursoropen.qc_cursor =
                        NETBSD32PTR64(args32.u.cursoropen.qc_cursor);
                break;
            case QUOTACTL_CURSORCLOSE:
                args.u.cursorclose.qc_cursor =
                        NETBSD32PTR64(args32.u.cursorclose.qc_cursor);
                break;
            case QUOTACTL_CURSORSKIPIDTYPE:
                args.u.cursorskipidtype.qc_cursor =
                        NETBSD32PTR64(args32.u.cursorskipidtype.qc_cursor);
                args.u.cursorskipidtype.qc_idtype =
                        args32.u.cursorskipidtype.qc_idtype;
                break;
            case QUOTACTL_CURSORGET:
                args.u.cursorget.qc_cursor =
                        NETBSD32PTR64(args32.u.cursorget.qc_cursor);
                args.u.cursorget.qc_keys =
                        NETBSD32PTR64(args32.u.cursorget.qc_keys);
                args.u.cursorget.qc_vals =
                        NETBSD32PTR64(args32.u.cursorget.qc_vals);
                args.u.cursorget.qc_maxnum =
                        args32.u.cursorget.qc_maxnum;
                args.u.cursorget.qc_ret =
                        NETBSD32PTR64(args32.u.cursorget.qc_ret);
                break;
            case QUOTACTL_CURSORATEND:
                args.u.cursoratend.qc_cursor =
                        NETBSD32PTR64(args32.u.cursoratend.qc_cursor);
                args.u.cursoratend.qc_ret =
                        NETBSD32PTR64(args32.u.cursoratend.qc_ret);
                break;
            case QUOTACTL_CURSORREWIND:
                args.u.cursorrewind.qc_cursor =
                        NETBSD32PTR64(args32.u.cursorrewind.qc_cursor);
                break;
            case QUOTACTL_QUOTAON:
                args.u.quotaon.qc_idtype = args32.u.quotaon.qc_idtype;
                args.u.quotaon.qc_quotafile =
                        NETBSD32PTR64(args32.u.quotaon.qc_quotafile);
                break;
            case QUOTACTL_QUOTAOFF:
                args.u.quotaoff.qc_idtype = args32.u.quotaoff.qc_idtype;
                break;
            default:
                return EINVAL;
        }

        return do_sys_quotactl(SCARG_P32(uap, path), &args);
}
static struct syscall_package compat_netbsd32_quota_syscalls[] = {
        { NETBSD32_SYS_netbsd32___quotactl, 0,
            (sy_call_t *)netbsd32___quotactl },
        { 0, 0, NULL }
};

MODULE(MODULE_CLASS_EXEC, compat_netbsd32_quota, "compat_netbsd32");

static int
compat_netbsd32_quota_modcmd(modcmd_t cmd, void *arg)
{
        int ret;

        switch (cmd) {
        case MODULE_CMD_INIT:
                ret = syscall_establish(&emul_netbsd32,
                    compat_netbsd32_quota_syscalls);
                return ret;
        case MODULE_CMD_FINI:
                ret = syscall_disestablish(&emul_netbsd32,
                    compat_netbsd32_quota_syscalls);
                return ret;
        default:
                return ENOTTY;
        }
}
#endif