Add a new libquota library, which contains some blocks to build and/or

parse quota plists; as well as a getfsquota() function to retrieve quotas
for a single id from a single filesystem (whatever filesystem this is:
a local quota-enabled fs or NFS). This is build on functions getufsquota()
(for local filesystems with UFS-like quotas) and getnfsquota();
which are also available to userland programs.
move functions from quota2_subr.c to libquota or libprop as appropriate,
and ajust in-tree quota tools.
move some declarations from kernel headers to either sys/quota.h or
quota/quota.h as appropriate. ufs/ufs/quota.h still installed because
it's needed by other installed ufs headers.
ufs/ufs/quota1.h still installed as a quick&dirty way to get a code
using the old quotactl() to compile (just include ufs/ufs/quota1.h instead of
ufs/ufs/quota.h - old code won't compile without this change and this is
on purpose).
Discussed on tech-kern@ and tech-net@ (long thread, but not much about
libquota itself ...)
This commit is contained in:
bouyer 2011-03-24 17:05:39 +00:00
parent c37993815d
commit d9210c2405
65 changed files with 1606 additions and 844 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_array.h,v 1.11 2011/01/20 11:17:58 bouyer Exp $ */
/* $NetBSD: prop_array.h,v 1.12 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006, 2009 The NetBSD Foundation, Inc.
@ -154,6 +154,8 @@ bool prop_array_set_cstring_nocopy(prop_array_t,
unsigned int,
const char *);
bool prop_array_add_and_rel(prop_array_t, prop_object_t);
__END_DECLS
#endif /* _PROPLIB_PROP_ARRAY_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_dictionary.h,v 1.12 2011/01/20 11:17:58 bouyer Exp $ */
/* $NetBSD: prop_dictionary.h,v 1.13 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006, 2009 The NetBSD Foundation, Inc.
@ -115,6 +115,8 @@ int prop_dictionary_copyout_ioctl(struct plistref *,
* Utility routines to make it more convenient to work with values
* stored in dictionaries.
*/
bool prop_dictionary_get_dict(prop_dictionary_t, const char *,
prop_dictionary_t *);
bool prop_dictionary_get_bool(prop_dictionary_t, const char *,
bool *);
bool prop_dictionary_set_bool(prop_dictionary_t, const char *,
@ -168,6 +170,10 @@ bool prop_dictionary_set_cstring_nocopy(prop_dictionary_t,
const char *,
const char *);
bool prop_dictionary_set_and_rel(prop_dictionary_t,
const char *,
prop_object_t);
__END_DECLS
#endif /* _PROPLIB_PROP_DICTIONARY_H_ */

View File

@ -0,0 +1,6 @@
# $NetBSD: Makefile,v 1.1 2011/03/24 17:05:39 bouyer Exp $
INCS= quotaprop.h quota.h
INCSDIR= /usr/include/quota
.include <bsd.prog.mk>

View File

@ -0,0 +1,61 @@
/* $NetBSD: quota.h,v 1.1 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
* This software is distributed under the following condiions
* compliant with the NetBSD foundation policy.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION OR CONTRIBUTORS
* 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.
*/
#ifndef _QUOTA_QUOTA_H
#define _QUOTA_QUOTA_H
#include <sys/types.h>
#include <quota/quotaprop.h>
/* check a quota usage against limits (assumes UFS semantic) */
int quota_check_limit(uint64_t, uint64_t, uint64_t, uint64_t, time_t, time_t);
/* return values for above */
#define QL_S_ALLOW_OK 0x00 /* below soft limit */
#define QL_S_ALLOW_SOFT 0x01 /* over soft limit */
#define QL_S_DENY_GRACE 0x02 /* over soft limit, grace time expired */
#define QL_S_DENY_HARD 0x03 /* over hard limit */
#define QL_F_CROSS 0x80 /* crossing soft limit */
#define QL_STATUS(x) ((x) & 0x0f)
#define QL_FLAGS(x) ((x) & 0xf0)
/*
* retrieve quotas with ufs semantics from vfs, for the given id and class.
* second argument points to a struct ufs_quota_entry array of QUOTA_NLIMITS
* elements.
*/
int getufsquota(const char *, struct ufs_quota_entry *, uid_t, const char *);
/* same as above, but for NFS */
int getnfsquota(const char *, struct ufs_quota_entry *, uid_t, const char *);
/* call one of the above, if appropriate, after a statvfs(2) */
int getfsquota(const char *, struct ufs_quota_entry *, uid_t, const char *);
#endif /* _QUOTA_QUOTA_H */

View File

@ -0,0 +1,83 @@
/* $NetBSD: quotaprop.h,v 1.1 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
* This software is distributed under the following condiions
* compliant with the NetBSD foundation policy.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION OR CONTRIBUTORS
* 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.
*/
#ifndef _QUOTA_QUOTAPROP_H
#define _QUOTA_QUOTAPROP_H
#include <prop/proplib.h>
#include <sys/quota.h>
int quotaprop_dict_get_uint64(prop_dictionary_t, uint64_t[],
const char *[], int, bool);
int proptoquota64(prop_dictionary_t, uint64_t *[], const char *[], int,
const char *[], int);
int quota_get_cmds(prop_dictionary_t, prop_array_t *);
prop_dictionary_t quota_prop_create(void);
bool quota_prop_add_command(prop_array_t, const char *, const char *,
prop_array_t);
prop_dictionary_t limits64toprop(uint64_t[], const char *[], int);
prop_dictionary_t quota64toprop(uid_t, int, uint64_t *[], const char *[], int,
const char *[], int);
/* structure used to describe a UFS-like quota entry */
struct ufs_quota_entry {
uint64_t ufsqe_hardlimit; /* absolute limit */
uint64_t ufsqe_softlimit; /* overflowable limit */
uint64_t ufsqe_cur; /* current usage */
int64_t ufsqe_time; /* grace expiration date for softlimit overflow */
int64_t ufsqe_grace; /* allowed time for softlimit overflow */
};
/* array of strings for the above */
#define UFS_QUOTA_ENTRY_NAMES \
{QUOTADICT_LIMIT_HARD, \
QUOTADICT_LIMIT_SOFT, \
QUOTADICT_LIMIT_USAGE, \
QUOTADICT_LIMIT_ETIME, \
QUOTADICT_LIMIT_GTIME \
}
#define UFS_QUOTA_NENTRIES 5
extern const char *ufs_quota_entry_names[];
/* array of strings for limit types and associated #define */
extern const char *ufs_quota_limit_names[];
#define QUOTA_LIMIT_BLOCK 0
#define QUOTA_LIMIT_FILE 1
#define QUOTA_NLIMITS 2
#define QUOTA_LIMIT_NAMES { QUOTADICT_LTYPE_BLOCK, QUOTADICT_LTYPE_FILE }
/* array of strings for quota class and associated #define */
extern const char *ufs_quota_class_names[];
#define QUOTA_CLASS_USER 0
#define QUOTA_CLASS_GROUP 1
#define QUOTA_NCLASS 2
#define QUOTA_CLASS_NAMES { QUOTADICT_CLASS_USER, QUOTADICT_CLASS_GROUP }
#endif /* _QUOTA_QUOTAPROP_H */

View File

@ -1,4 +1,4 @@
.\" $NetBSD: prop_array_util.3,v 1.4 2011/01/20 10:42:19 wiz Exp $
.\" $NetBSD: prop_array_util.3,v 1.5 2011/03/24 17:05:39 bouyer Exp $
.\"
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd June 2, 2008
.Dd March 12, 2011
.Dt PROP_ARRAY_UTIL 3
.Os
.Sh NAME
@ -61,7 +61,8 @@
.Nm prop_array_get_cstring ,
.Nm prop_array_set_cstring ,
.Nm prop_array_get_cstring_nocopy ,
.Nm prop_array_set_cstring_nocopy
.Nm prop_array_set_cstring_nocopy,
.Nm prop_array_add_and_rel
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
@ -163,6 +164,9 @@
.Ft bool
.Fn prop_array_set_cstring_nocopy "prop_array_t dict" \
"unsigned int indx" "const char *strp"
.Ft bool
.Fn prop_array_add_and_rel "prop_array_t dict" \
"prop_object_t obj"
.Sh DESCRIPTION
The
.Nm prop_array_util
@ -190,6 +194,11 @@ functions do not copy the string that is set or returned.
See
.Xr prop_string 3
for more information.
.Pp
The
.Fn prop_array_add_and_rel
function adds the object to the end of the array and release it.
The object is also released on failure.
.Sh RETURN VALUES
The
.Nm prop_array_util

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_array_util.c,v 1.2 2008/09/11 13:15:13 haad Exp $ */
/* $NetBSD: prop_array_util.c,v 1.3 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -238,3 +238,14 @@ TEMPLATE(,)
TEMPLATE(_nocopy,const)
#undef TEMPLATE
bool
prop_array_add_and_rel(prop_array_t array, prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_array_add(array, po);
prop_object_release(po);
return ret;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: prop_dictionary_util.3,v 1.4 2008/06/02 09:27:04 haad Exp $
.\" $NetBSD: prop_dictionary_util.3,v 1.5 2011/03/24 17:05:39 bouyer Exp $
.\"
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -27,11 +27,12 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd October 25, 2006
.Dd March 12, 2011
.Dt PROP_DICTIONARY_UTIL 3
.Os
.Sh NAME
.Nm prop_dictionary_util ,
.Nm prop_dictionary_get_dict ,
.Nm prop_dictionary_get_bool ,
.Nm prop_dictionary_set_bool ,
.Nm prop_dictionary_get_int8 ,
@ -53,13 +54,17 @@
.Nm prop_dictionary_get_cstring ,
.Nm prop_dictionary_set_cstring ,
.Nm prop_dictionary_get_cstring_nocopy ,
.Nm prop_dictionary_set_cstring_nocopy
.Nm prop_dictionary_set_cstring_nocopy,
.Nm prop_dictionary_set_and_rel
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft bool
.Fn prop_dictionary_get_dict "prop_dictionary_t dict" "const char *key" \
"bool *dictp"
.Ft bool
.Fn prop_dictionary_get_bool "prop_dictionary_t dict" "const char *key" \
"bool *valp"
.Ft bool
@ -131,6 +136,9 @@
.Ft bool
.Fn prop_dictionary_set_cstring_nocopy "prop_dictionary_t dict" \
"const char *key" "const char *strp"
.Ft bool
.Fn prop_dictionary_set_and_rel "prop_dictionary_t dict" \
"const char *key" "prop_object_t obj"
.Sh DESCRIPTION
The
.Nm prop_dictionary_util
@ -158,6 +166,11 @@ functions do not copy the string that is set or returned.
See
.Xr prop_string 3
for more information.
.Pp
The
.Fn prop_dictionary_set_and_rel
function adds the object to the dictionary and release it.
The object is also released on failure.
.Sh RETURN VALUES
The
.Nm prop_dictionary_util

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_dictionary_util.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */
/* $NetBSD: prop_dictionary_util.c,v 1.4 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -41,6 +41,18 @@
#include <prop/proplib.h>
#include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */
bool
prop_dictionary_get_dict(prop_dictionary_t dict, const char *key, prop_dictionary_t *dp)
{
prop_object_t o;
o = prop_dictionary_get(dict, key);
if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY)
return false;
*dp = o;
return true;
}
bool
prop_dictionary_get_bool(prop_dictionary_t dict,
const char *key,
@ -206,3 +218,15 @@ TEMPLATE(,)
TEMPLATE(_nocopy,const)
#undef TEMPLATE
bool
prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_dictionary_set(dict, key, po);
prop_object_release(po);
return ret;
}

View File

@ -0,0 +1,4 @@
# $NetBSD: Makefile.inc,v 1.1 2011/03/24 17:05:39 bouyer Exp $
.PATH.c: ${.PARSEDIR}
SRCS+= quotaprop.c quotasubr.c

View File

@ -1,6 +1,6 @@
/* $NetBSD: quota2_prop.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: quotaprop.c,v 1.1 2011/03/24 17:05:40 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* Copyright (c) 2011 Manuel Bouyer
* All rights reserved.
* This software is distributed under the following condiions
* compliant with the NetBSD foundation policy.
@ -32,90 +32,50 @@
#include <sys/inttypes.h>
#include <sys/errno.h>
#include <ufs/ufs/quota2_prop.h>
const char *quota2_valnames[] = INITQLNAMES;
prop_dictionary_t
prop_dictionary_get_dict(prop_dictionary_t dict, const char *key)
{
prop_object_t o;
o = prop_dictionary_get(dict, key);
if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY)
return NULL;
return o;
}
#include <quota/quotaprop.h>
/*
* update values from value[] using dict entries whose key is stored
* in name[]. Unknown keys are ignored. If update is false,
* a key in name[] but not in dict is an error.
* name[] may have NULL pointers to skip a value[]
*/
int
quota2_dict_get_q2v_limits(prop_dictionary_t dict, struct quota2_val *q2v,
bool update)
quotaprop_dict_get_uint64(prop_dictionary_t dict, uint64_t value[],
const char *name[], int nvalues, bool update)
{
uint64_t vu;
int64_t v;
if (!prop_dictionary_get_uint64(dict, "soft", &vu)) {
if (!update)
return EINVAL;
} else
q2v->q2v_softlimit = vu;
if (!prop_dictionary_get_uint64(dict, "hard", &vu)) {
if (!update)
return EINVAL;
} else
q2v->q2v_hardlimit = vu;
if (!prop_dictionary_get_int64(dict, "grace time", &v)) {
if (!update)
return EINVAL;
} else
q2v->q2v_grace = v;
return 0;
}
int i;
uint64_t v;
int
quota2_dict_update_q2e_limits(prop_dictionary_t data, struct quota2_entry *q2e)
{
int i, error;
prop_dictionary_t val;
for (i = 0; i < N_QL; i++) {
val = prop_dictionary_get_dict(data, quota2_valnames[i]);
if (val == NULL)
for (i = 0; i < nvalues; i++) {
if (name[i] == NULL)
continue;
error = quota2_dict_get_q2v_limits(val, &q2e->q2e_val[i], 1);
if (error)
return error;
if (!prop_dictionary_get_uint64(dict, name[i], &v)) {
if (!update)
return EINVAL;
}
value[i] = v;
}
return 0;
}
/*
* convert a quota entry dictionary to in-memory array of uint64_t's
*/
int
quota2_dict_get_q2v_usage(prop_dictionary_t dict, struct quota2_val *q2v)
{
uint64_t vu;
int64_t v;
int err;
err = quota2_dict_get_q2v_limits(dict, q2v, false);
if (err)
return err;
if (!prop_dictionary_get_uint64(dict, "usage", &vu))
return EINVAL;
q2v->q2v_cur = vu;
if (!prop_dictionary_get_int64(dict, "expire time", &v))
return EINVAL;
q2v->q2v_time = v;
return 0;
}
int
quota2_dict_get_q2e_usage(prop_dictionary_t data, struct quota2_entry *q2e)
proptoquota64(prop_dictionary_t data, uint64_t *values[], const char *valname[],
int nvalues, const char *limname[], int nlimits)
{
int i, error;
prop_dictionary_t val;
for (i = 0; i < N_QL; i++) {
val = prop_dictionary_get_dict(data, quota2_valnames[i]);
if (val == NULL)
for (i = 0; i < nlimits; i++) {
if (limname[i] == NULL)
continue;
if (!prop_dictionary_get_dict(data, limname[i], &val))
return EINVAL;
error = quota2_dict_get_q2v_usage(val, &q2e->q2e_val[i]);
error = quotaprop_dict_get_uint64(val, values[i],
valname, nvalues, false);
if (error)
return error;
}
@ -123,7 +83,7 @@ quota2_dict_get_q2e_usage(prop_dictionary_t data, struct quota2_entry *q2e)
}
int
quota2_get_cmds(prop_dictionary_t qdict, prop_array_t *cmds)
quota_get_cmds(prop_dictionary_t qdict, prop_array_t *cmds)
{
prop_number_t pn;
prop_object_t o;
@ -143,31 +103,9 @@ quota2_get_cmds(prop_dictionary_t qdict, prop_array_t *cmds)
return 0;
}
bool
prop_array_add_and_rel(prop_array_t array, prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_array_add(array, po);
prop_object_release(po);
return ret;
}
bool
prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_dictionary_set(dict, key, po);
prop_object_release(po);
return ret;
}
prop_dictionary_t
quota2_prop_create(void)
quota_prop_create(void)
{
prop_dictionary_t dict = prop_dictionary_create();
@ -184,7 +122,7 @@ err:
}
bool
quota2_prop_add_command(prop_array_t arrcmd, const char *cmd, const char *type,
quota_prop_add_command(prop_array_t arrcmd, const char *cmd, const char *type,
prop_array_t data)
{
prop_dictionary_t dict;
@ -212,36 +150,33 @@ err:
return false;
}
/* construct a dictionary using array of values and corresponding keys */
prop_dictionary_t
q2vtoprop(struct quota2_val *q2v)
limits64toprop(uint64_t value[], const char *name[], int nvalues)
{
int i;
prop_dictionary_t dict1 = prop_dictionary_create();
if (dict1 == NULL)
return NULL;
if (!prop_dictionary_set_uint64(dict1, "hard", q2v->q2v_hardlimit)) {
goto err;
}
if (!prop_dictionary_set_uint64(dict1, "soft", q2v->q2v_softlimit)) {
goto err;
}
if (!prop_dictionary_set_uint64(dict1, "usage", q2v->q2v_cur)) {
goto err;
}
if (!prop_dictionary_set_int64(dict1, "expire time", q2v->q2v_time)) {
goto err;
}
if (!prop_dictionary_set_int64(dict1, "grace time", q2v->q2v_grace)) {
goto err;
}
return dict1;
err:
for (i = 0; i < nvalues; i++) {
if (name[i] == NULL)
continue;
if (!prop_dictionary_set_uint64(dict1, name[i], value[i])) {
prop_object_release(dict1);
return NULL;
}
}
return dict1;
}
/*
* construct a quota entry using provided array of values, array of values
* names
*/
prop_dictionary_t
q2etoprop(struct quota2_entry *q2e, int def)
quota64toprop(uid_t uid, int def, uint64_t *values[], const char *valname[],
int nvalues, const char *limname[], int nlimits)
{
prop_dictionary_t dict1 = prop_dictionary_create();
prop_dictionary_t dict2;
@ -255,15 +190,17 @@ q2etoprop(struct quota2_entry *q2e, int def)
goto err;
}
} else {
if (!prop_dictionary_set_uint32(dict1, "id", q2e->q2e_uid)) {
if (!prop_dictionary_set_uint32(dict1, "id", uid)) {
goto err;
}
}
for (i = 0; i < N_QL; i++) {
dict2 = q2vtoprop(&q2e->q2e_val[i]);
for (i = 0; i < nlimits; i++) {
if (limname[i] == NULL)
continue;
dict2 = limits64toprop(values[i], valname, nvalues);
if (dict2 == NULL)
goto err;
if (!prop_dictionary_set_and_rel(dict1, quota2_valnames[i],
if (!prop_dictionary_set_and_rel(dict1, limname[i],
dict2))
goto err;
}
@ -273,3 +210,7 @@ err:
prop_object_release(dict1);
return NULL;
}
const char *ufs_quota_entry_names[] = UFS_QUOTA_ENTRY_NAMES;
const char *ufs_quota_limit_names[] = QUOTA_LIMIT_NAMES;
const char *ufs_quota_class_names[] = QUOTA_CLASS_NAMES;

View File

@ -1,6 +1,6 @@
/* $NetBSD: quota2_prop.h,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: quotasubr.c,v 1.1 2011/03/24 17:05:40 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* Copyright (c) 2011 Manuel Bouyer
* All rights reserved.
* This software is distributed under the following condiions
* compliant with the NetBSD foundation policy.
@ -27,21 +27,28 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <prop/proplib.h>
#include <ufs/ufs/quota2.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/inttypes.h>
#include <sys/errno.h>
prop_dictionary_t prop_dictionary_get_dict(prop_dictionary_t, const char *);
int quota2_dict_get_q2v_limits(prop_dictionary_t, struct quota2_val *, bool);
int quota2_dict_update_q2e_limits(prop_dictionary_t, struct quota2_entry *);
int quota2_dict_get_q2v_usage(prop_dictionary_t, struct quota2_val *);
int quota2_dict_get_q2e_usage(prop_dictionary_t, struct quota2_entry *);
int quota2_get_cmds(prop_dictionary_t, prop_array_t *);
#include <quota/quota.h>
bool prop_array_add_and_rel(prop_array_t, prop_object_t);
bool prop_dictionary_set_and_rel(prop_dictionary_t, const char *,
prop_object_t);
prop_dictionary_t quota2_prop_create(void);
bool quota2_prop_add_command(prop_array_t, const char *, const char *,
prop_array_t);
prop_dictionary_t q2vtoprop(struct quota2_val *);
prop_dictionary_t q2etoprop(struct quota2_entry *, int);
int
quota_check_limit(uint64_t cur, uint64_t change, uint64_t soft, uint64_t hard,
time_t expire, time_t now)
{
if (cur + change > hard) {
if (cur <= soft)
return (QL_F_CROSS | QL_S_DENY_HARD);
return QL_S_DENY_HARD;
} else if (cur + change > soft) {
if (cur <= soft)
return (QL_F_CROSS | QL_S_ALLOW_SOFT);
if (now > expire) {
return QL_S_DENY_GRACE;
}
return QL_S_ALLOW_SOFT;
}
return QL_S_ALLOW_OK;
}

View File

@ -1,4 +1,4 @@
# $NetBSD: ad.mips64eb,v 1.44 2011/03/12 19:52:45 christos Exp $
# $NetBSD: ad.mips64eb,v 1.45 2011/03/24 17:05:40 bouyer Exp $
./libexec/ld.elf_so-64 base-compat-shlib compat,pic
./libexec/ld.elf_so-o32 base-sysutil-bin compat,pic
./usr/lib/64 base-compat-lib
@ -185,6 +185,8 @@
./usr/lib/64/libpthread_dbg.so.2.0 base-compat-shlib compat,pic
./usr/lib/64/libpuffs.so.2 base-compat-shlib compat,pic
./usr/lib/64/libpuffs.so.2.0 base-compat-shlib compat,pic
./usr/lib/64/libquota.so.0 base-compat-shlib compat,pic
./usr/lib/64/libquota.so.0.0 base-compat-shlib compat,pic
./usr/lib/64/libradius.so.4 base-compat-shlib compat,pic
./usr/lib/64/libradius.so.4.0 base-compat-shlib compat,pic
./usr/lib/64/libresolv.so.2 base-compat-shlib compat,pic
@ -452,6 +454,8 @@
./usr/lib/o32/libpthread_dbg.so.2.0 base-compat-shlib compat,pic
./usr/lib/o32/libpuffs.so.2 base-compat-shlib compat,pic
./usr/lib/o32/libpuffs.so.2.0 base-compat-shlib compat,pic
./usr/lib/o32/libquota.so.0 base-compat-shlib compat,pic
./usr/lib/o32/libquota.so.0.0 base-compat-shlib compat,pic
./usr/lib/o32/libradius.so.4 base-compat-shlib compat,pic
./usr/lib/o32/libradius.so.4.0 base-compat-shlib compat,pic
./usr/lib/o32/libresolv.so.2 base-compat-shlib compat,pic

View File

@ -1,4 +1,4 @@
# $NetBSD: ad.mips64el,v 1.42 2011/03/12 19:52:45 christos Exp $
# $NetBSD: ad.mips64el,v 1.43 2011/03/24 17:05:40 bouyer Exp $
./libexec/ld.elf_so-64 base-compat-shlib compat,pic
./libexec/ld.elf_so-o32 base-sysutil-bin compat,pic
./usr/lib/64 base-compat-lib
@ -185,6 +185,8 @@
./usr/lib/64/libpthread_dbg.so.2.0 base-compat-shlib compat,pic
./usr/lib/64/libpuffs.so.2 base-compat-shlib compat,pic
./usr/lib/64/libpuffs.so.2.0 base-compat-shlib compat,pic
./usr/lib/64/libquota.so.0 base-compat-shlib compat,pic
./usr/lib/64/libquota.so.0.0 base-compat-shlib compat,pic
./usr/lib/64/libradius.so.4 base-compat-shlib compat,pic
./usr/lib/64/libradius.so.4.0 base-compat-shlib compat,pic
./usr/lib/64/libresolv.so.2 base-compat-shlib compat,pic
@ -452,6 +454,8 @@
./usr/lib/o32/libpthread_dbg.so.2.0 base-compat-shlib compat,pic
./usr/lib/o32/libpuffs.so.2 base-compat-shlib compat,pic
./usr/lib/o32/libpuffs.so.2.0 base-compat-shlib compat,pic
./usr/lib/o32/libquota.so.0 base-compat-shlib compat,pic
./usr/lib/o32/libquota.so.0.0 base-compat-shlib compat,pic
./usr/lib/o32/libradius.so.4 base-compat-shlib compat,pic
./usr/lib/o32/libradius.so.4.0 base-compat-shlib compat,pic
./usr/lib/o32/libresolv.so.2 base-compat-shlib compat,pic

View File

@ -1,4 +1,4 @@
# $NetBSD: md.amd64,v 1.117 2011/03/12 19:52:45 christos Exp $
# $NetBSD: md.amd64,v 1.118 2011/03/24 17:05:40 bouyer Exp $
./dev/lms0 base-obsolete obsolete
./dev/mms0 base-obsolete obsolete
./libexec/ld.elf_so-i386 base-sys-shlib compat,pic
@ -189,6 +189,8 @@
./usr/lib/i386/libpthread_dbg.so.2.0 base-compat-shlib compat,pic
./usr/lib/i386/libpuffs.so.2 base-compat-shlib compat,pic
./usr/lib/i386/libpuffs.so.2.0 base-compat-shlib compat,pic
./usr/lib/i386/libquota.so.0 base-compat-shlib compat,pic
./usr/lib/i386/libquota.so.0.0 base-compat-shlib compat,pic
./usr/lib/i386/libradius.so.4 base-compat-shlib compat,pic
./usr/lib/i386/libradius.so.4.0 base-compat-shlib compat,pic
./usr/lib/i386/librefuse.so.2 base-compat-shlib compat,pic

View File

@ -1,4 +1,4 @@
# $NetBSD: md.sparc64,v 1.110 2011/03/12 19:52:45 christos Exp $
# $NetBSD: md.sparc64,v 1.111 2011/03/24 17:05:40 bouyer Exp $
./libexec/ld.elf_so-sparc base-sysutil-bin compat,pic
./sbin/edlabel base-sysutil-root obsolete
./usr/bin/fdformat base-util-bin
@ -186,6 +186,8 @@
./usr/lib/sparc/libpthread_dbg.so.2.0 base-compat-shlib compat,pic
./usr/lib/sparc/libpuffs.so.2 base-compat-shlib compat,pic
./usr/lib/sparc/libpuffs.so.2.0 base-compat-shlib compat,pic
./usr/lib/sparc/libquota.so.0 base-compat-shlib compat,pic
./usr/lib/sparc/libquota.so.0.0 base-compat-shlib compat,pic
./usr/lib/sparc/libradius.so.4 base-compat-shlib compat,pic
./usr/lib/sparc/libradius.so.4.0 base-compat-shlib compat,pic
./usr/lib/sparc/librefuse.so.2 base-compat-shlib compat,pic

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.926 2011/03/17 02:35:27 joerg Exp $
# $NetBSD: mi,v 1.927 2011/03/24 17:05:40 bouyer Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -846,6 +846,7 @@
./usr/include/pcap base-c-usr
./usr/include/prop base-c-usr
./usr/include/protocols base-c-usr
./usr/include/quota base-c-usr
./usr/include/readline base-c-usr
./usr/include/rpc base-c-usr
./usr/include/rpcsvc base-c-usr

View File

@ -1,4 +1,4 @@
# $NetBSD: shl.mi,v 1.578 2011/03/12 19:52:45 christos Exp $
# $NetBSD: shl.mi,v 1.579 2011/03/24 17:05:40 bouyer Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -363,6 +363,9 @@
./usr/lib/libpuffs.so base-puffs-shlib
./usr/lib/libpuffs.so.2 base-puffs-shlib
./usr/lib/libpuffs.so.2.0 base-puffs-shlib
./usr/lib/libquota.so base-sys-shlib
./usr/lib/libquota.so.0 base-sys-shlib
./usr/lib/libquota.so.0.0 base-sys-shlib
./usr/lib/libradius.so base-net-shlib
./usr/lib/libradius.so.4 base-net-shlib
./usr/lib/libradius.so.4.0 base-net-shlib

View File

@ -1,4 +1,4 @@
# $NetBSD: ad.mips64eb,v 1.25 2011/03/12 19:52:46 christos Exp $
# $NetBSD: ad.mips64eb,v 1.26 2011/03/24 17:05:41 bouyer Exp $
./usr/bin/elf2aout comp-obsolete obsolete
./usr/bin/elf2ecoff comp-sysutil-bin
./usr/include/mips comp-c-include
@ -459,6 +459,10 @@
./usr/lib/64/libpuffs.so base-sys-shlib compat,pic
./usr/lib/64/libpuffs_p.a comp-c-proflib compat,profile
./usr/lib/64/libpuffs_pic.a comp-c-piclib compat,pic
./usr/lib/64/libquota.a comp-c-lib compat
./usr/lib/64/libquota.so base-sys-shlib compat,pic
./usr/lib/64/libquota_p.a comp-c-proflib compat,profile
./usr/lib/64/libquota_pic.a comp-c-piclib compat,pic
./usr/lib/64/libradius.a comp-c-lib compat
./usr/lib/64/libradius.so base-sys-shlib compat,pic
./usr/lib/64/libradius_p.a comp-c-proflib compat,profile
@ -989,6 +993,10 @@
./usr/lib/o32/libpuffs.so base-sys-shlib compat,pic
./usr/lib/o32/libpuffs_p.a comp-c-proflib compat,profile
./usr/lib/o32/libpuffs_pic.a comp-c-piclib compat,pic
./usr/lib/o32/libquota.a comp-c-lib compat
./usr/lib/o32/libquota.so base-sys-shlib compat,pic
./usr/lib/o32/libquota_p.a comp-c-proflib compat,profile
./usr/lib/o32/libquota_pic.a comp-c-piclib compat,pic
./usr/lib/o32/libradius.a comp-c-lib compat
./usr/lib/o32/libradius.so base-sys-shlib compat,pic
./usr/lib/o32/libradius_p.a comp-c-proflib compat,profile
@ -1217,6 +1225,7 @@
./usr/libdata/debug/usr/lib/64/libpthread.so.1.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/64/libpthread_dbg.so.2.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/64/libpuffs.so.2.0.debug comp-puffs-debug debug,compat
./usr/libdata/debug/usr/lib/64/libquota.so.0.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/64/libradius.so.4.0.debug comp-net-debug debug,compat
./usr/libdata/debug/usr/lib/64/librefuse.so.2.0.debug comp-refuse-debug debug,compat
./usr/libdata/debug/usr/lib/64/libresolv.so.2.0.debug comp-net-debug debug,compat
@ -1409,6 +1418,7 @@
./usr/libdata/debug/usr/lib/o32/libpthread.so.1.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libpthread_dbg.so.2.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libpuffs.so.2.0.debug comp-puffs-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libquota.so.0.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libradius.so.4.0.debug comp-net-debug debug,compat
./usr/libdata/debug/usr/lib/o32/librefuse.so.2.0.debug comp-refuse-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libresolv.so.2.0.debug comp-net-debug debug,compat

View File

@ -1,4 +1,4 @@
# $NetBSD: ad.mips64el,v 1.25 2011/03/12 19:52:46 christos Exp $
# $NetBSD: ad.mips64el,v 1.26 2011/03/24 17:05:41 bouyer Exp $
./usr/bin/elf2aout comp-obsolete obsolete
./usr/bin/elf2ecoff comp-sysutil-bin
./usr/include/mips comp-c-include
@ -459,6 +459,10 @@
./usr/lib/64/libpuffs.so base-sys-shlib compat,pic
./usr/lib/64/libpuffs_p.a comp-c-proflib compat,profile
./usr/lib/64/libpuffs_pic.a comp-c-piclib compat,pic
./usr/lib/64/libquota.a comp-c-lib compat
./usr/lib/64/libquota.so base-sys-shlib compat,pic
./usr/lib/64/libquota_p.a comp-c-proflib compat,profile
./usr/lib/64/libquota_pic.a comp-c-piclib compat,pic
./usr/lib/64/libradius.a comp-c-lib compat
./usr/lib/64/libradius.so base-sys-shlib compat,pic
./usr/lib/64/libradius_p.a comp-c-proflib compat,profile
@ -989,6 +993,10 @@
./usr/lib/o32/libpuffs.so base-sys-shlib compat,pic
./usr/lib/o32/libpuffs_p.a comp-c-proflib compat,profile
./usr/lib/o32/libpuffs_pic.a comp-c-piclib compat,pic
./usr/lib/o32/libquota.a comp-c-lib compat
./usr/lib/o32/libquota.so base-sys-shlib compat,pic
./usr/lib/o32/libquota_p.a comp-c-proflib compat,profile
./usr/lib/o32/libquota_pic.a comp-c-piclib compat,pic
./usr/lib/o32/libradius.a comp-c-lib compat
./usr/lib/o32/libradius.so base-sys-shlib compat,pic
./usr/lib/o32/libradius_p.a comp-c-proflib compat,profile
@ -1217,6 +1225,7 @@
./usr/libdata/debug/usr/lib/64/libpthread.so.1.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/64/libpthread_dbg.so.2.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/64/libpuffs.so.2.0.debug comp-puffs-debug debug,compat
./usr/libdata/debug/usr/lib/64/libquota.so.0.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/64/libradius.so.4.0.debug comp-net-debug debug,compat
./usr/libdata/debug/usr/lib/64/librefuse.so.2.0.debug comp-refuse-debug debug,compat
./usr/libdata/debug/usr/lib/64/libresolv.so.2.0.debug comp-net-debug debug,compat
@ -1409,6 +1418,7 @@
./usr/libdata/debug/usr/lib/o32/libpthread.so.1.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libpthread_dbg.so.2.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libpuffs.so.2.0.debug comp-puffs-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libquota.so.0.0.debug comp-sys-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libradius.so.4.0.debug comp-net-debug debug,compat
./usr/libdata/debug/usr/lib/o32/librefuse.so.2.0.debug comp-refuse-debug debug,compat
./usr/libdata/debug/usr/lib/o32/libresolv.so.2.0.debug comp-net-debug debug,compat

View File

@ -1,4 +1,4 @@
# $NetBSD: md.amd64,v 1.103 2011/03/12 19:52:46 christos Exp $
# $NetBSD: md.amd64,v 1.104 2011/03/24 17:05:41 bouyer Exp $
./usr/include/amd64 comp-c-include
./usr/include/amd64/ansi.h comp-c-include
./usr/include/amd64/aout_machdep.h comp-c-include
@ -735,6 +735,11 @@
./usr/lib/i386/libpuffs_g.a comp-c-proflib compat,debuglib
./usr/lib/i386/libpuffs_p.a comp-c-proflib compat,profile
./usr/lib/i386/libpuffs_pic.a comp-c-piclib compat,pic
./usr/lib/i386/libquota.a comp-c-lib compat
./usr/lib/i386/libquota.so comp-sys-shlib compat,pic
./usr/lib/i386/libquota_g.a comp-c-proflib compat,debuglib
./usr/lib/i386/libquota_p.a comp-c-proflib compat,profile
./usr/lib/i386/libquota_pic.a comp-c-proflib compat,profile
./usr/lib/i386/libradius.a comp-c-lib compat
./usr/lib/i386/libradius.so comp-sys-shlib compat,pic
./usr/lib/i386/libradius_g.a comp-c-proflib compat,debuglib
@ -992,6 +997,7 @@
./usr/libdata/debug/usr/lib/i386/libpthread.so.1.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/i386/libpthread_dbg.so.2.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/i386/libpuffs.so.2.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/i386/libquota.so.0.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/i386/libradius.so.4.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/i386/librefuse.so.2.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/i386/libresolv.so.2.0.debug comp-compat-shlib compat,pic,debug

View File

@ -1,4 +1,4 @@
# $NetBSD: md.sparc64,v 1.89 2011/03/12 19:52:46 christos Exp $
# $NetBSD: md.sparc64,v 1.90 2011/03/24 17:05:41 bouyer Exp $
./usr/include/ieeefp.h comp-c-include
./usr/include/sparc comp-c-include
./usr/include/sparc/_G_config.h comp-obsolete obsolete
@ -530,6 +530,10 @@
./usr/lib/sparc/libpuffs.so base-sys-shlib compat,pic
./usr/lib/sparc/libpuffs_p.a comp-c-proflib compat,profile
./usr/lib/sparc/libpuffs_pic.a comp-c-piclib compat,pic
./usr/lib/sparc/libquota.a comp-c-lib compat
./usr/lib/sparc/libquota.so base-sys-shlib compat,pic
./usr/lib/sparc/libquota_p.a comp-c-proflib compat,profile
./usr/lib/sparc/libquota_pic.a comp-c-piclib compat,pic
./usr/lib/sparc/libradius.a comp-c-lib compat
./usr/lib/sparc/libradius.so base-sys-shlib compat,pic
./usr/lib/sparc/libradius_p.a comp-c-proflib compat,profile
@ -752,6 +756,7 @@
./usr/libdata/debug/usr/lib/sparc/libpthread.so.1.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/sparc/libpthread_dbg.so.2.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/sparc/libpuffs.so.2.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/sparc/libquota.so.2.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/sparc/libradius.so.4.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/sparc/librefuse.so.2.0.debug comp-compat-shlib compat,pic,debug
./usr/libdata/debug/usr/lib/sparc/libresolv.so.2.0.debug comp-compat-shlib compat,pic,debug

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1602 2011/03/19 04:59:43 jruoho Exp $
# $NetBSD: mi,v 1.1603 2011/03/24 17:05:41 bouyer Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -1869,6 +1869,8 @@
./usr/include/puffs.h comp-puffs-include
./usr/include/puffsdump.h comp-puffs-include
./usr/include/pwd.h comp-c-include
./usr/include/quota/quota.h comp-c-include
./usr/include/quota/quotaprop.h comp-c-include
./usr/include/radlib.h comp-c-include
./usr/include/radlib_vs.h comp-c-include
./usr/include/randomid.h comp-c-include
@ -2623,6 +2625,9 @@
./usr/lib/libpuffs.a comp-puffs-lib
./usr/lib/libpuffs_g.a -unknown- debuglib
./usr/lib/libpuffs_p.a comp-puffs-proflib profile
./usr/lib/libquota.a comp-c-lib
./usr/lib/libquota_g.a -unknown- debuglib
./usr/lib/libquota_p.a comp-c-proflib profile
./usr/lib/libradius.a comp-c-lib
./usr/lib/libradius_g.a -unknown- debuglib
./usr/lib/libradius_p.a comp-c-proflib profile
@ -3960,6 +3965,7 @@
./usr/libdata/lint/llib-lpthread_dbg.ln comp-c-lintlib lint
./usr/libdata/lint/llib-lpuffs.ln comp-puffs-lintlib lint
./usr/libdata/lint/llib-lradius.ln comp-c-lintlib lint
./usr/libdata/lint/llib-lquota.ln comp-c-lintlib lint
./usr/libdata/lint/llib-lrefuse.ln comp-refuse-lintlib lint
./usr/libdata/lint/llib-lresolv.ln comp-c-lintlib lint
./usr/libdata/lint/llib-lrmt.ln comp-c-lintlib lint

View File

@ -1,4 +1,4 @@
# $NetBSD: shl.mi,v 1.163 2011/03/12 19:52:47 christos Exp $
# $NetBSD: shl.mi,v 1.164 2011/03/24 17:05:42 bouyer Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -91,6 +91,7 @@
./usr/lib/libpthread_dbg_pic.a comp-c-piclib
./usr/lib/libpthread_pic.a comp-c-piclib
./usr/lib/libpuffs_pic.a comp-puffs-piclib
./usr/lib/libquota_pic.a comp-c-piclib
./usr/lib/libradius_pic.a comp-c-piclib
./usr/lib/librefuse_pic.a comp-refuse-piclib
./usr/lib/libresolv_pic.a comp-c-piclib
@ -288,6 +289,7 @@
./usr/libdata/debug/usr/lib/libpthread.so.1.0.debug comp-sys-debug debug
./usr/libdata/debug/usr/lib/libpthread_dbg.so.2.0.debug comp-sys-debug debug
./usr/libdata/debug/usr/lib/libpuffs.so.2.0.debug comp-puffs-debug debug
./usr/libdata/debug/usr/lib/libquota.so.0.0.debug comp-sys-debug debug
./usr/libdata/debug/usr/lib/libradius.so.4.0.debug comp-net-debug debug
./usr/libdata/debug/usr/lib/librefuse.so.2.0.debug comp-refuse-debug debug
./usr/libdata/debug/usr/lib/libresolv.so.2.0.debug comp-net-debug debug

View File

@ -1,4 +1,4 @@
# $NetBSD: NetBSD.dist.base,v 1.78 2011/03/10 13:16:58 jmmv Exp $
# $NetBSD: NetBSD.dist.base,v 1.79 2011/03/24 17:05:42 bouyer Exp $
# @(#)4.4BSD.dist 8.1 (Berkeley) 6/13/93
# Do not customize this file as it may be overwritten on upgrades.
@ -164,6 +164,7 @@
./usr/include/pcap
./usr/include/prop
./usr/include/protocols
./usr/include/quota
./usr/include/readline
./usr/include/rpc
./usr/include/rpcsvc

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.133 2010/07/31 21:47:53 joerg Exp $
# $NetBSD: Makefile,v 1.134 2011/03/24 17:05:42 bouyer Exp $
# @(#)Makefile 8.2 (Berkeley) 1/4/94
# Doing a make includes builds /usr/include
@ -44,6 +44,7 @@ INCSDIR= /usr/include
SUBDIR= rpc
SUBDIR+= ../common/include/prop
SUBDIR+= ../common/include/quota
.include <bsd.prog.mk>
.include <bsd.subdir.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.164 2011/02/12 22:24:40 matt Exp $
# $NetBSD: Makefile,v 1.165 2011/03/24 17:05:43 bouyer Exp $
# from: @(#)Makefile 5.25.1.1 (Berkeley) 5/7/91
.include <bsd.own.mk>
@ -87,6 +87,7 @@ SUBDIR+= libroken # depends on libutil, libcrypt
SUBDIR+= libcurses # depends on libterminfo
SUBDIR+= libdm # depends on libprop
SUBDIR+= libedit # depends on libterminfo
SUBDIR+= libquota # depends on libprop and librpcsvc
SUBDIR+= librefuse # depends on libpuffs
SUBDIR+= librumpuser # depends on libpthread

17
lib/libquota/Makefile Normal file
View File

@ -0,0 +1,17 @@
# $NetBSD: Makefile,v 1.1 2011/03/24 17:05:43 bouyer Exp $
# @(#)Makefile 8.1 (Berkeley) 6/4/93
.include <bsd.own.mk>
.include "${NETBSDSRCDIR}/common/lib/libquota/Makefile.inc"
WARNS= 4
LIB= quota
LIBDPLIBS+= prop ${.CURDIR}/../libprop
LIBDPLIBS+= rpcsvc ${.CURDIR}/../librpcsvc
SRCS+= getfsquota.c getnfsquota.c getufsquota.c
MAN=
.include <bsd.lib.mk>

67
lib/libquota/getfsquota.c Normal file
View File

@ -0,0 +1,67 @@
/* $NetBSD: getfsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $ */
/*-
* Copyright (c) 2011 Manuel Bouyer
* All rights reserved.
* This software is distributed under the following condiions
* compliant with the NetBSD foundation policy.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION OR CONTRIBUTORS
* 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: getfsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $");
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <err.h>
#include <string.h>
#include <sys/types.h>
#include <sys/statvfs.h>
#include <quota/quotaprop.h>
#include <quota/quota.h>
/* retrieve quotas with ufs semantics from vfs, for the given user id */
int
getfsquota(const char *path, struct ufs_quota_entry *qv, uid_t id,
const char *class)
{
struct statvfs v;
if (statvfs(path, &v) < 0) {
return -1;
}
if (strcmp(v.f_fstypename, "nfs") == 0)
return getnfsquota(v.f_mntfromname, qv, id, class);
else {
if ((v.f_flag & ST_QUOTA) == 0)
return 0;
/*
* assume all quota-enabled local filesystems have UFS
* semantic for now
*/
return getufsquota(v.f_mntonname, qv, id, class);
}
}

209
lib/libquota/getnfsquota.c Normal file
View File

@ -0,0 +1,209 @@
/* $NetBSD: getnfsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Robert Elz at The University of Melbourne.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: getnfsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $");
#endif
#endif /* not lint */
/*
* Disk quota reporting program.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <quota/quota.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpcsvc/rquota.h>
/* convert a rquota limit to our semantic */
static uint64_t
rqlim2qlim(uint32_t lim)
{
if (lim == 0)
return UQUAD_MAX;
else
return (lim - 1);
}
static int
callaurpc(const char *host, rpcprog_t prognum, rpcvers_t versnum,
rpcproc_t procnum, xdrproc_t inproc, void *in, xdrproc_t outproc, void *out)
{
struct sockaddr_in server_addr;
enum clnt_stat clnt_stat;
struct hostent *hp;
struct timeval timeout, tottimeout;
CLIENT *client = NULL;
int sock = RPC_ANYSOCK;
if ((hp = gethostbyname(host)) == NULL)
return (int) RPC_UNKNOWNHOST;
timeout.tv_usec = 0;
timeout.tv_sec = 6;
memmove(&server_addr.sin_addr, hp->h_addr, hp->h_length);
server_addr.sin_family = AF_INET;
server_addr.sin_port = 0;
if ((client = clntudp_create(&server_addr, prognum,
versnum, timeout, &sock)) == NULL)
return (int) rpc_createerr.cf_stat;
client->cl_auth = authunix_create_default();
tottimeout.tv_sec = 25;
tottimeout.tv_usec = 0;
clnt_stat = clnt_call(client, procnum, inproc, in,
outproc, out, tottimeout);
return (int) clnt_stat;
}
int
getnfsquota(const char *mp, struct ufs_quota_entry *qv,
uint32_t id, const char *class)
{
struct getquota_args gq_args;
struct ext_getquota_args ext_gq_args;
struct getquota_rslt gq_rslt;
struct timeval tv;
char *host, *path;
int ret, rpcqtype;
if (strcmp(class, QUOTADICT_CLASS_USER) == 0)
rpcqtype = RQUOTA_USRQUOTA;
else if (strcmp(class, QUOTADICT_CLASS_GROUP) == 0)
rpcqtype = RQUOTA_GRPQUOTA;
else {
errno = EINVAL;
return -1;
}
/*
* must be some form of "hostname:/path"
*/
path = strdup(mp);
if (path == NULL) {
errno = ENOMEM;
return -1;
}
host = strsep(&path, ":");
if (path == NULL) {
free(host);
errno = EINVAL;
return -1;
}
ext_gq_args.gqa_pathp = path;
ext_gq_args.gqa_id = id;
ext_gq_args.gqa_type = rpcqtype;
ret = callaurpc(host, RQUOTAPROG, EXT_RQUOTAVERS,
RQUOTAPROC_GETQUOTA, xdr_ext_getquota_args, &ext_gq_args,
xdr_getquota_rslt, &gq_rslt);
if (ret == RPC_PROGVERSMISMATCH && rpcqtype == RQUOTA_USRQUOTA) {
/* try RQUOTAVERS */
gq_args.gqa_pathp = path;
gq_args.gqa_uid = id;
ret = callaurpc(host, RQUOTAPROG, RQUOTAVERS,
RQUOTAPROC_GETQUOTA, xdr_getquota_args, &gq_args,
xdr_getquota_rslt, &gq_rslt);
}
free(host);
if (ret != RPC_SUCCESS) {
return 0;
}
switch (gq_rslt.status) {
case Q_NOQUOTA:
break;
case Q_EPERM:
errno = EACCES;
return -1;
case Q_OK:
gettimeofday(&tv, NULL);
/* blocks*/
qv[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit = rqlim2qlim(
gq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit *
(gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE));
qv[QUOTA_LIMIT_BLOCK].ufsqe_softlimit = rqlim2qlim(
gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit *
(gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE));
qv[QUOTA_LIMIT_BLOCK].ufsqe_cur =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks *
(gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
qv[QUOTA_LIMIT_BLOCK].ufsqe_time = (tv.tv_sec +
gq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft);
/* inodes */
qv[QUOTA_LIMIT_FILE].ufsqe_hardlimit = rqlim2qlim(
gq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit);
qv[QUOTA_LIMIT_FILE].ufsqe_softlimit = rqlim2qlim(
gq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit);
qv[QUOTA_LIMIT_FILE].ufsqe_cur =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles;
qv[QUOTA_LIMIT_FILE].ufsqe_time = (int)(tv.tv_sec +
gq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft);
qv[QUOTA_LIMIT_BLOCK].ufsqe_grace =
qv[QUOTA_LIMIT_FILE].ufsqe_grace = 0;
return 1;
default:
/* XXX sert errno and return -1 ? */
break;
}
return 0;
}

180
lib/libquota/getufsquota.c Normal file
View File

@ -0,0 +1,180 @@
/* $NetBSD: getufsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $ */
/*-
* Copyright (c) 2011 Manuel Bouyer
* All rights reserved.
* This software is distributed under the following condiions
* compliant with the NetBSD foundation policy.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION OR CONTRIBUTORS
* 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: getufsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $");
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <err.h>
#include <string.h>
#include <sys/types.h>
#include <quota/quotaprop.h>
#include <quota/quota.h>
/* retrieve quotas with ufs semantics from vfs, for the given user id */
int
getufsquota(const char *mp, struct ufs_quota_entry *qv, uid_t id,
const char *class)
{
prop_dictionary_t dict, data, cmd;
prop_array_t cmds, datas;
struct plistref pref;
int8_t error8;
int retval;
const char *cmdstr;
dict = quota_prop_create();
if (dict == NULL) {
errno = ENOMEM;
goto end_dict;
}
cmds = prop_array_create();
if (cmds == NULL) {
errno = ENOMEM;
goto end_cmds;
}
datas = prop_array_create();
if (datas == NULL) {
errno = ENOMEM;
goto end_datas;
}
data = prop_dictionary_create();
if (data == NULL) {
errno = ENOMEM;
goto end_data;
}
if (!prop_dictionary_set_uint32(data, "id", id)) {
errno = ENOMEM;
goto end_data;
}
if (!prop_array_add_and_rel(datas, data)) {
errno = ENOMEM;
goto end_datas;
}
if (!quota_prop_add_command(cmds, "get", class, datas)) {
errno = ENOMEM;
goto end_cmds;
}
if (!prop_dictionary_set(dict, "commands", cmds)) {
errno = ENOMEM;
goto end_dict;
}
if (!prop_dictionary_send_syscall(dict, &pref))
goto end_dict;
prop_object_release(dict);
if (quotactl(mp, &pref) != 0)
return -1;
if ((errno = prop_dictionary_recv_syscall(&pref, &dict)) != 0)
return -1;
if ((errno = quota_get_cmds(dict, &cmds)) != 0)
goto end_dict;
/* only one command, no need to iter */
cmd = prop_array_get(cmds, 0);
if (cmd == NULL) {
errno = EINVAL;
goto end_dict;
}
if (!prop_dictionary_get_cstring_nocopy(cmd, "command",
&cmdstr)) {
errno = EINVAL;
goto end_dict;
}
if (strcmp("get", cmdstr) != 0) {
errno = EINVAL;
goto end_dict;
}
if (!prop_dictionary_get_int8(cmd, "return", &error8)) {
errno = EINVAL;
goto end_dict;
}
if (error8) {
prop_object_release(dict);
if (error8 != ENOENT && error8 != ENODEV) {
errno = error8;
return -1;
}
return 0;
}
datas = prop_dictionary_get(cmd, "data");
if (datas == NULL) {
errno = EINVAL;
goto end_dict;
}
/* only one data, no need to iter */
if (prop_array_count(datas) > 0) {
uint64_t *values[QUOTA_NLIMITS];
data = prop_array_get(datas, 0);
if (data == NULL) {
errno = EINVAL;
goto end_dict;
}
values[QUOTA_LIMIT_BLOCK] =
&qv[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
values[QUOTA_LIMIT_FILE] =
&qv[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
errno = proptoquota64(data, values, ufs_quota_entry_names,
UFS_QUOTA_NENTRIES, ufs_quota_limit_names, QUOTA_NLIMITS);
if (errno)
goto end_dict;
retval = 1;
} else {
retval = 0;
}
prop_object_release(dict);
return retval;
end_data:
prop_object_release(data);
end_datas:
prop_object_release(datas);
end_cmds:
prop_object_release(cmds);
end_dict:
prop_object_release(dict);
return -1;
}

View File

@ -0,0 +1,5 @@
# $NetBSD: shlib_version,v 1.1 2011/03/24 17:05:43 bouyer Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
major=0
minor=0

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.7 2011/03/06 17:08:16 bouyer Exp $
# $NetBSD: Makefile,v 1.8 2011/03/24 17:05:43 bouyer Exp $
.include <bsd.own.mk>
PROG = rpc.rquotad
@ -6,14 +6,7 @@ SRCS = rquotad.c
MAN = rpc.rquotad.8
MLINKS = rpc.rquotad.8 rquotad.8
CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
DPADD= ${LIBRPCSVC} ${LIBPROP}
LDADD= -lrpcsvc -lprop
.PATH: ${NETBSDSRCDIR}/usr.bin/quota
SRCS+= getvfsquota.c
.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs
SRCS+= quota2_prop.c quota1_subr.c
DPADD= ${LIBQUOTA} ${LIBRPCSVC} ${LIBPROP}
LDADD= -lquota -lrpcsvc -lprop
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: rquotad.c,v 1.26 2011/03/12 12:30:39 bouyer Exp $ */
/* $NetBSD: rquotad.c,v 1.27 2011/03/24 17:05:43 bouyer Exp $ */
/*
* by Manuel Bouyer (bouyer@ensta.fr). Public domain.
@ -6,7 +6,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: rquotad.c,v 1.26 2011/03/12 12:30:39 bouyer Exp $");
__RCSID("$NetBSD: rquotad.c,v 1.27 2011/03/24 17:05:43 bouyer Exp $");
#endif
#include <sys/param.h>
@ -29,16 +29,12 @@ __RCSID("$NetBSD: rquotad.c,v 1.26 2011/03/12 12:30:39 bouyer Exp $");
#include <syslog.h>
#include <ufs/ufs/quota2_prop.h>
#include <ufs/ufs/quota1.h>
#include <quota/quotaprop.h>
#include <quota/quota.h>
#include <rpc/rpc.h>
#include <rpcsvc/rquota.h>
#include <arpa/inet.h>
#include <getvfsquota.h>
const char *qfextension[MAXQUOTAS] = INITQFNAMES;
void rquota_service(struct svc_req *request, SVCXPRT *transp);
void ext_rquota_service(struct svc_req *request, SVCXPRT *transp);
void sendquota(struct svc_req *request, int vers, SVCXPRT *transp);
@ -47,6 +43,15 @@ int main(int, char *[]);
int from_inetd = 1;
static uint32_t
qlim2rqlim(uint64_t lim)
{
if (lim == UQUAD_MAX)
return 0;
else
return (lim + 1);
}
void
cleanup(int dummy)
{
@ -166,10 +171,8 @@ sendquota(struct svc_req *request, int vers, SVCXPRT *transp)
struct getquota_args getq_args;
struct ext_getquota_args ext_getq_args;
struct getquota_rslt getq_rslt;
struct quota2_entry q2e;
struct dqblk dqblk;
int type;
int8_t version;
struct ufs_quota_entry qe[QUOTA_NLIMITS];
const char *class;
struct timeval timev;
memset((char *)&getq_args, 0, sizeof(getq_args));
@ -195,10 +198,10 @@ sendquota(struct svc_req *request, int vers, SVCXPRT *transp)
}
switch (ext_getq_args.gqa_type) {
case RQUOTA_USRQUOTA:
type = USRQUOTA;
class = QUOTADICT_CLASS_USER;
break;
case RQUOTA_GRPQUOTA:
type = GRPQUOTA;
class = QUOTADICT_CLASS_GROUP;
break;
default:
getq_rslt.status = Q_NOQUOTA;
@ -207,31 +210,31 @@ sendquota(struct svc_req *request, int vers, SVCXPRT *transp)
if (request->rq_cred.oa_flavor != AUTH_UNIX) {
/* bad auth */
getq_rslt.status = Q_EPERM;
} else if (!getvfsquota(ext_getq_args.gqa_pathp, &q2e, &version, ext_getq_args.gqa_id, ext_getq_args.gqa_type, 0, 0)) {
} else if (!getufsquota(ext_getq_args.gqa_pathp, qe,
ext_getq_args.gqa_id, class)) {
/* failed, return noquota */
getq_rslt.status = Q_NOQUOTA;
} else {
q2e2dqblk(&q2e, &dqblk);
gettimeofday(&timev, NULL);
getq_rslt.status = Q_OK;
getq_rslt.getquota_rslt_u.gqr_rquota.rq_active = TRUE;
getq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize = DEV_BSIZE;
getq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit =
dqblk.dqb_bhardlimit;
qlim2rqlim(qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit);
getq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit =
dqblk.dqb_bsoftlimit;
qlim2rqlim(qe[QUOTA_LIMIT_BLOCK].ufsqe_softlimit);
getq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks =
dqblk.dqb_curblocks;
qe[QUOTA_LIMIT_BLOCK].ufsqe_cur;
getq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit =
dqblk.dqb_ihardlimit;
qlim2rqlim(qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit);
getq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit =
dqblk.dqb_isoftlimit;
qlim2rqlim(qe[QUOTA_LIMIT_FILE].ufsqe_softlimit);
getq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles =
dqblk.dqb_curinodes;
qe[QUOTA_LIMIT_FILE].ufsqe_cur;
getq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft =
dqblk.dqb_btime;
qe[QUOTA_LIMIT_BLOCK].ufsqe_time - timev.tv_sec;
getq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft =
dqblk.dqb_itime;
qe[QUOTA_LIMIT_FILE].ufsqe_time - timev.tv_sec;
}
out:
if (!svc_sendreply(transp, xdr_getquota_rslt, (char *)&getq_rslt))

View File

@ -1,4 +1,4 @@
# $NetBSD: bsd.README,v 1.279 2011/02/20 20:16:01 jmmv Exp $
# $NetBSD: bsd.README,v 1.280 2011/03/24 17:05:44 bouyer Exp $
# @(#)bsd.README 8.2 (Berkeley) 4/2/94
This is the README file for the make "include" files for the NetBSD
@ -1362,6 +1362,7 @@ DPADD Additional dependencies for the program. Usually used for
LIBPCI?= ${DESTDIR}/usr/lib/libpci.a
LIBPMC?= ${DESTDIR}/usr/lib/libpmc.a
LIBPOSIX?= ${DESTDIR}/usr/lib/libposix.a
LIBQUOTA?= ${DESTDIR}/usr/lib/libquota.a
LIBPTHREAD?= ${DESTDIR}/usr/lib/libpthread.a
LIBPTHREAD_DBG?=${DESTDIR}/usr/lib/libpthread_dbg.a
LIBRADIUS?= ${DESTDIR}/usr/lib/libradius.a

View File

@ -1,4 +1,4 @@
# $NetBSD: bsd.hostprog.mk,v 1.61 2011/02/20 20:16:01 jmmv Exp $
# $NetBSD: bsd.hostprog.mk,v 1.62 2011/03/24 17:05:44 bouyer Exp $
# @(#)bsd.prog.mk 8.2 (Berkeley) 4/2/94
.include <bsd.init.mk>
@ -44,6 +44,7 @@ LIBPCI?= /usr/lib/libpci.a
LIBPLOT?= /usr/lib/libplot.a
LIBPOSIX?= /usr/lib/libposix.a
LIBPUFFS?= /usr/lib/libpuffs.a
LIBQUOTA?= /usr/lib/libquota.a
LIBRESOLV?= /usr/lib/libresolv.a
LIBRPCSVC?= /usr/lib/librpcsvc.a
LIBRUMP?= /usr/lib/librump.a

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_syscalls_50.c,v 1.7 2011/03/06 17:08:33 bouyer Exp $ */
/* $NetBSD: vfs_syscalls_50.c,v 1.8 2011/03/24 17:05:44 bouyer Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -36,7 +36,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_50.c,v 1.7 2011/03/06 17:08:33 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_50.c,v 1.8 2011/03/24 17:05:44 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -314,7 +314,7 @@ compat_50_sys_mknod(struct lwp *l,
}
#include <ufs/ufs/quota1.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
/* ARGSUSED */
int
@ -335,8 +335,11 @@ compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *
prop_array_t cmds, datas;
char *bufpath;
struct dqblk dqblk;
struct quota2_entry q2e;
static const char *quotatypes[MAXQUOTAS] = INITQFNAMES;
struct ufs_quota_entry qe[QUOTA_NLIMITS];
uint64_t *values[QUOTA_NLIMITS];
values[QUOTA_LIMIT_BLOCK] = &qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
values[QUOTA_LIMIT_FILE] = &qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
error = namei_simple_user(SCARG(uap, path),
NSM_FOLLOW_TRYEMULROOT, &vp);
@ -344,7 +347,7 @@ compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *
return (error);
error = ENOMEM;
mp = vp->v_mount;
if ((dict = quota2_prop_create()) == NULL)
if ((dict = quota_prop_create()) == NULL)
goto out;
if ((cmds = prop_array_create()) == NULL)
goto out_dict;
@ -372,15 +375,17 @@ compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *
error = ENOMEM;
if (!prop_array_add_and_rel(datas, data))
goto out_datas;
if (!quota2_prop_add_command(cmds, "quotaon",
quotatypes[q1cmd & SUBCMDMASK], datas))
if (!quota_prop_add_command(cmds, "quotaon",
ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
datas))
goto out_cmds;
goto do_quotaonoff;
case Q_QUOTAOFF:
error = ENOMEM;
if (!quota2_prop_add_command(cmds, "quotaoff",
quotatypes[q1cmd & SUBCMDMASK], datas))
if (!quota_prop_add_command(cmds, "quotaoff",
ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
datas))
goto out_cmds;
do_quotaonoff:
if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
@ -388,7 +393,7 @@ do_quotaonoff:
error = VFS_QUOTACTL(mp, dict);
if (error)
goto out_dict;
if ((error = quota2_get_cmds(dict, &cmds)) != 0)
if ((error = quota_get_cmds(dict, &cmds)) != 0)
goto out_dict;
cmd = prop_array_get(cmds, 0);
if (cmd == NULL) {
@ -411,15 +416,16 @@ do_quotaonoff:
goto out_data;
if (!prop_array_add_and_rel(datas, data))
goto out_datas;
if (!quota2_prop_add_command(cmds, "get",
quotatypes[q1cmd & SUBCMDMASK], datas))
if (!quota_prop_add_command(cmds, "get",
ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
datas))
goto out_cmds;
if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
goto out_dict;
error = VFS_QUOTACTL(mp, dict);
if (error)
goto out_dict;
if ((error = quota2_get_cmds(dict, &cmds)) != 0)
if ((error = quota_get_cmds(dict, &cmds)) != 0)
goto out_dict;
cmd = prop_array_get(cmds, 0);
if (cmd == NULL) {
@ -440,10 +446,12 @@ do_quotaonoff:
data = prop_array_get(datas, 0);
if (data == NULL)
goto out_dict;
error = quota2_dict_get_q2e_usage(data, &q2e);
error = proptoquota64(data, values,
ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (error)
goto out_dict;
q2e2dqblk(&q2e, &dqblk);
ufsqe2dqblk(qe, &dqblk);
error = copyout(&dqblk, SCARG(uap, arg), sizeof(dqblk));
goto out_dict;
@ -451,24 +459,26 @@ do_quotaonoff:
error = copyin(SCARG(uap, arg), &dqblk, sizeof(dqblk));
if (error)
goto out_datas;
dqblk2q2e(&dqblk, &q2e);
q2e.q2e_uid = SCARG(uap, uid);
dqblk2ufsqe(&dqblk, qe);
error = ENOMEM;
data = q2etoprop(&q2e, 0);
data = quota64toprop(SCARG(uap, uid), 0, values,
ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (data == NULL)
goto out_data;
if (!prop_array_add_and_rel(datas, data))
goto out_datas;
if (!quota2_prop_add_command(cmds, "set",
quotatypes[q1cmd & SUBCMDMASK], datas))
if (!quota_prop_add_command(cmds, "set",
ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
datas))
goto out_cmds;
if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
goto out_dict;
error = VFS_QUOTACTL(mp, dict);
if (error)
goto out_dict;
if ((error = quota2_get_cmds(dict, &cmds)) != 0)
if ((error = quota_get_cmds(dict, &cmds)) != 0)
goto out_dict;
cmd = prop_array_get(cmds, 0);
if (cmd == NULL) {
@ -488,15 +498,16 @@ do_quotaonoff:
* emulate with a "get version"
*/
error = ENOMEM;
if (!quota2_prop_add_command(cmds, "get version",
quotatypes[q1cmd & SUBCMDMASK], datas))
if (!quota_prop_add_command(cmds, "get version",
ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
datas))
goto out_cmds;
if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
goto out_dict;
error = VFS_QUOTACTL(mp, dict);
if (error)
goto out_dict;
if ((error = quota2_get_cmds(dict, &cmds)) != 0)
if ((error = quota_get_cmds(dict, &cmds)) != 0)
goto out_dict;
cmd = prop_array_get(cmds, 0);
if (cmd == NULL) {

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.libkern,v 1.12 2011/02/26 18:17:55 jakllsch Exp $
# $NetBSD: Makefile.libkern,v 1.13 2011/03/24 17:05:44 bouyer Exp $
#
# Variable definitions for libkern.
@ -32,6 +32,7 @@ CPPFLAGS+= -I$M ${KERNCPPFLAGS} ${KERNMISCCPPFLAGS}
.include "${.PARSEDIR}/../../../common/lib/libc/Makefile.inc"
.include "${.PARSEDIR}/../../../common/lib/libutil/Makefile.inc"
.include "${.PARSEDIR}/../../../common/lib/libprop/Makefile.inc"
.include "${.PARSEDIR}/../../../common/lib/libquota/Makefile.inc"
CPPFLAGS+= -I${KERNDIR}/../../../common/include

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.rumpvfs,v 1.29 2011/03/06 17:08:37 bouyer Exp $
# $NetBSD: Makefile.rumpvfs,v 1.30 2011/03/24 17:05:44 bouyer Exp $
#
.include "${RUMPTOP}/Makefile.rump"
@ -51,7 +51,7 @@ SRCS+= subr_bufq.c bufq_disksort.c bufq_fcfs.c bufq_priocscan.c \
SRCS+= mfs_miniroot.c
#quota2 plists
SRCS+= quota1_subr.c quota2_prop.c
SRCS+= quota1_subr.c
# dev
# firmload is technically part of rumpdev, but it's pure vfs in nature.

View File

@ -1,4 +1,4 @@
/* $NetBSD: quota.h,v 1.2 2011/03/06 17:08:38 bouyer Exp $ */
/* $NetBSD: quota.h,v 1.3 2011/03/24 17:05:45 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
@ -30,9 +30,25 @@
#ifndef _SYS_QUOTA_H_
#define _SYS_QUOTA_H_
#ifndef _KERNEL
#if !defined(_KERNEL) && !defined(_STANDALONE)
__BEGIN_DECLS
int quotactl(const char *, struct plistref *) __RENAME(__quotactl50);
__END_DECLS
#endif
/* strings used in dictionary for the different quota class */
#define QUOTADICT_CLASS_USER "user"
#define QUOTADICT_CLASS_GROUP "group"
/* strings used in dictionary for the different limit types */
#define QUOTADICT_LTYPE_BLOCK "block"
#define QUOTADICT_LTYPE_FILE "file"
/* strings used in dictionary for the different limit and usage values */
#define QUOTADICT_LIMIT_SOFT "soft"
#define QUOTADICT_LIMIT_HARD "hard"
#define QUOTADICT_LIMIT_GTIME "grace time"
#define QUOTADICT_LIMIT_USAGE "usage"
#define QUOTADICT_LIMIT_ETIME "expire time"
#endif /* _SYS_QUOTA_H_ */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.ufs,v 1.25 2011/03/06 17:08:38 bouyer Exp $
# $NetBSD: files.ufs,v 1.26 2011/03/24 17:05:45 bouyer Exp $
deffs FFS
deffs EXT2FS
@ -64,7 +64,6 @@ file ufs/ufs/ufs_quota1.c quota & (ffs | lfs | mfs | ext2fs)
file ufs/ufs/ufs_quota2.c quota2 & (ffs | lfs | mfs | ext2fs)
file ufs/ufs/quota1_subr.c
file ufs/ufs/quota2_subr.c quota2 & (ffs | lfs | mfs | ext2fs)
file ufs/ufs/quota2_prop.c
file ufs/ufs/ufs_vfsops.c ffs | lfs | mfs | ext2fs
file ufs/ufs/ufs_vnops.c ffs | lfs | mfs | ext2fs
file ufs/ufs/ufs_wapbl.c ffs & wapbl

View File

@ -1,4 +1,4 @@
/* $NetBSD: quota.h,v 1.26 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: quota.h,v 1.27 2011/03/24 17:05:45 bouyer Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -36,6 +36,7 @@
#ifndef _UFS_UFS_QUOTA_H_
#define _UFS_UFS_QUOTA_H_
#include <quota/quotaprop.h>
/*
* These definitions are common to the original disk quota implementation
@ -53,22 +54,32 @@
#define USRQUOTA 0 /* element used for user quotas */
#define GRPQUOTA 1 /* element used for group quotas */
/*
* Definitions for the default names of the quotas files/quota types.
*/
#define INITQFNAMES { \
"user", /* USRQUOTA */ \
"group", /* GRPQUOTA */ \
__inline static int __unused
ufsclass2qtype(int class)
{
switch(class) {
case QUOTA_CLASS_USER:
return USRQUOTA;
case QUOTA_CLASS_GROUP:
return GRPQUOTA;
default:
return -1;
}
}
/* definition of limits types for each quota */
#define QL_BLOCK 0
#define QL_FILE 1
#define N_QL 2
#define INITQLNAMES {"block", "file", "undefined" }
static __inline int __unused
qtype2ufsclass(int type)
{
switch(type) {
case USRQUOTA:
return QUOTA_CLASS_USER;
case GRPQUOTA:
return QUOTA_CLASS_GROUP;
default:
return -1;
}
}
#ifdef _KERNEL

View File

@ -1,4 +1,4 @@
/* $NetBSD: quota1.h,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: quota1.h,v 1.3 2011/03/24 17:05:45 bouyer Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -43,6 +43,15 @@
* is deprecated. the newer implementation is defined in quota2.h
* and friends
*/
/*
* Definitions for the default names of the quotas files/quota types.
*/
#define INITQFNAMES { \
"user", /* USRQUOTA */ \
"group", /* GRPQUOTA */ \
}
/*
* Definitions for disk quotas imposed on the average user
* (big brother finally hits UNIX).
@ -94,7 +103,6 @@ struct dqblk {
/* quota1_subr.c */
struct quota2_entry;
void dqblk2q2e(const struct dqblk *, struct quota2_entry *);
void q2e2dqblk(const struct quota2_entry *, struct dqblk *);
void dqblk2ufsqe(const struct dqblk *, struct ufs_quota_entry *);
void ufsqe2dqblk(const struct ufs_quota_entry *, struct dqblk *);
#endif /* !_UFS_UFS_QUOTA1_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: quota1_subr.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: quota1_subr.c,v 1.3 2011/03/24 17:05:45 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
@ -28,12 +28,12 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: quota1_subr.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: quota1_subr.c,v 1.3 2011/03/24 17:05:45 bouyer Exp $");
#include <sys/types.h>
#include <machine/limits.h>
#include <ufs/ufs/quota2.h>
#include <quota/quotaprop.h>
#include <ufs/ufs/quota1.h>
static uint64_t
@ -55,37 +55,38 @@ q2e2dqblk_limit(uint64_t lim)
}
void
dqblk2q2e(const struct dqblk *dqblk, struct quota2_entry *q2e)
dqblk2ufsqe(const struct dqblk *dqblk, struct ufs_quota_entry *qe)
{
q2e->q2e_val[QL_BLOCK].q2v_hardlimit =
qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit =
dqblk2q2e_limit(dqblk->dqb_bhardlimit);
q2e->q2e_val[QL_BLOCK].q2v_softlimit =
qe[QUOTA_LIMIT_BLOCK].ufsqe_softlimit =
dqblk2q2e_limit(dqblk->dqb_bsoftlimit);
q2e->q2e_val[QL_BLOCK].q2v_cur = dqblk->dqb_curblocks;
q2e->q2e_val[QL_BLOCK].q2v_time = dqblk->dqb_btime;
qe[QUOTA_LIMIT_BLOCK].ufsqe_cur = dqblk->dqb_curblocks;
qe[QUOTA_LIMIT_BLOCK].ufsqe_time = dqblk->dqb_btime;
q2e->q2e_val[QL_FILE].q2v_hardlimit =
qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit =
dqblk2q2e_limit(dqblk->dqb_ihardlimit);
q2e->q2e_val[QL_FILE].q2v_softlimit =
qe[QUOTA_LIMIT_FILE].ufsqe_softlimit =
dqblk2q2e_limit(dqblk->dqb_isoftlimit);
q2e->q2e_val[QL_FILE].q2v_cur = dqblk->dqb_curinodes;
q2e->q2e_val[QL_FILE].q2v_time = dqblk->dqb_itime;
qe[QUOTA_LIMIT_FILE].ufsqe_cur = dqblk->dqb_curinodes;
qe[QUOTA_LIMIT_FILE].ufsqe_time = dqblk->dqb_itime;
}
void
q2e2dqblk(const struct quota2_entry *q2e, struct dqblk *dqblk)
ufsqe2dqblk(const struct ufs_quota_entry *qe, struct dqblk *dqblk)
{
dqblk->dqb_bhardlimit =
q2e2dqblk_limit(q2e->q2e_val[QL_BLOCK].q2v_hardlimit);
q2e2dqblk_limit(qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit);
dqblk->dqb_bsoftlimit =
q2e2dqblk_limit(q2e->q2e_val[QL_BLOCK].q2v_softlimit);
dqblk->dqb_curblocks = q2e->q2e_val[QL_BLOCK].q2v_cur;
dqblk->dqb_btime = q2e->q2e_val[QL_BLOCK].q2v_time;
q2e2dqblk_limit(qe[QUOTA_LIMIT_BLOCK].ufsqe_softlimit);
dqblk->dqb_curblocks = qe[QUOTA_LIMIT_BLOCK].ufsqe_cur;
dqblk->dqb_btime = qe[QUOTA_LIMIT_BLOCK].ufsqe_time;
dqblk->dqb_ihardlimit =
q2e2dqblk_limit(q2e->q2e_val[QL_FILE].q2v_hardlimit);
q2e2dqblk_limit(qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit);
dqblk->dqb_isoftlimit =
q2e2dqblk_limit(q2e->q2e_val[QL_FILE].q2v_softlimit);
dqblk->dqb_curinodes = q2e->q2e_val[QL_FILE].q2v_cur;
dqblk->dqb_itime = q2e->q2e_val[QL_FILE].q2v_time;
q2e2dqblk_limit(qe[QUOTA_LIMIT_FILE].ufsqe_softlimit);
dqblk->dqb_curinodes = qe[QUOTA_LIMIT_FILE].ufsqe_cur;
dqblk->dqb_itime = qe[QUOTA_LIMIT_FILE].ufsqe_time;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: quota2.h,v 1.3 2011/03/09 18:12:04 dholland Exp $ */
/* $NetBSD: quota2.h,v 1.4 2011/03/24 17:05:45 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
@ -30,6 +30,7 @@
#ifndef _UFS_UFS_QUOTA2_H_
#define _UFS_UFS_QUOTA2_H_
#include <ufs/ufs/quota.h>
#include <quota/quota.h>
/* New disk quota implementation. In this implementation, the quota datas
@ -56,12 +57,34 @@ struct quota2_val {
int64_t q2v_grace; /* allowed time for softlimit overflow */
};
/* NAMES for the above in the plist */
#define INITQVNAMES_ALL { \
QUOTADICT_LIMIT_HARD, \
QUOTADICT_LIMIT_SOFT, \
QUOTADICT_LIMIT_USAGE, \
QUOTADICT_LIMIT_ETIME, \
QUOTADICT_LIMIT_GTIME \
}
#define INITQVNAMES_LIMITSONLY { \
QUOTADICT_LIMIT_HARD, \
QUOTADICT_LIMIT_SOFT, \
NULL, \
NULL, \
QUOTADICT_LIMIT_GTIME \
}
#define N_QV 5
/*
* On-disk description of a user or group quota
* These entries are keept as linked list, either in one of the hash HEAD,
* or in the free list.
*/
#define N_QL 2
#define QL_BLOCK 0
#define QL_FILE 1
#define INITQLNAMES {QUOTADICT_LTYPE_BLOCK, QUOTADICT_LTYPE_FILE}
struct quota2_entry {
/* block & inode limits and status */
struct quota2_val q2e_val[N_QL];
@ -101,15 +124,10 @@ void quota2_create_blk0(uint64_t, void *bp, int, int, int);
void quota2_ufs_rwq2v(const struct quota2_val *, struct quota2_val *, int);
void quota2_ufs_rwq2e(const struct quota2_entry *, struct quota2_entry *, int);
int quota2_check_limit(struct quota2_val *, uint64_t, time_t);
#define QL_S_ALLOW_OK 0x00 /* below soft limit */
#define QL_S_ALLOW_SOFT 0x01 /* over soft limit */
#define QL_S_DENY_GRACE 0x02 /* over soft limit, grace time expired */
#define QL_S_DENY_HARD 0x03 /* over hard limit */
#define QL_F_CROSS 0x80 /* crossing soft limit */
#define QL_STATUS(x) ((x) & 0x0f)
#define QL_FLAGS(x) ((x) & 0xf0)
__inline static int __unused
quota2_check_limit(struct quota2_val *q2v, uint64_t change, time_t now)
{
return quota_check_limit(q2v->q2v_cur, change, q2v->q2v_softlimit,
q2v->q2v_hardlimit, q2v->q2v_time, now);
}
#endif /* _UFS_UFS_QUOTA2_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: quota2_subr.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: quota2_subr.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: quota2_subr.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: quota2_subr.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $");
#include <sys/param.h>
#include <sys/time.h>
@ -108,21 +108,3 @@ int needswap)
needswap);
d->q2e_uid = ufs_rw32(s->q2e_uid, needswap);
}
int
quota2_check_limit(struct quota2_val *q2v, uint64_t change, time_t now)
{
if (q2v->q2v_cur + change > q2v->q2v_hardlimit) {
if (q2v->q2v_cur <= q2v->q2v_softlimit)
return (QL_F_CROSS | QL_S_DENY_HARD);
return QL_S_DENY_HARD;
} else if (q2v->q2v_cur + change > q2v->q2v_softlimit) {
if (q2v->q2v_cur <= q2v->q2v_softlimit)
return (QL_F_CROSS | QL_S_ALLOW_SOFT);
if (now > q2v->q2v_time) {
return QL_S_DENY_GRACE;
}
return QL_S_ALLOW_SOFT;
}
return QL_S_ALLOW_OK;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_quota.c,v 1.69 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: ufs_quota.c,v 1.70 2011/03/24 17:05:46 bouyer Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993, 1995
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.69 2011/03/06 17:08:39 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.70 2011/03/24 17:05:46 bouyer Exp $");
#if defined(_KERNEL_OPT)
#include "opt_quota.h"
@ -55,13 +55,11 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.69 2011/03/06 17:08:39 bouyer Exp $"
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/ufs_extern.h>
#include <ufs/ufs/ufs_quota.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
kmutex_t dqlock;
kcondvar_t dqcv;
const char *quotatypes[MAXQUOTAS] = INITQFNAMES;
/*
* Code pertaining to management of the in-core dquot data structures.
*/
@ -165,9 +163,9 @@ quota_handle_cmd(struct mount *mp, struct lwp *l, prop_dictionary_t cmddict)
return EINVAL;
if (!prop_dictionary_get_cstring_nocopy(cmddict, "type", &type))
return EINVAL;
if (!strcmp(type, "user")) {
if (!strcmp(type, QUOTADICT_CLASS_USER)) {
q2type = USRQUOTA;
} else if (!strcmp(type, "group")) {
} else if (!strcmp(type, QUOTADICT_CLASS_GROUP)) {
q2type = GRPQUOTA;
} else
return EOPNOTSUPP;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_quota1.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: ufs_quota1.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993, 1995
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -47,7 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $"
#include <sys/mount.h>
#include <sys/kauth.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
#include <ufs/ufs/quota1.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufsmount.h>
@ -501,9 +501,13 @@ quota1_handle_cmd_get(struct ufsmount *ump, int type, int id,
int defaultq, prop_array_t replies)
{
struct dquot *dq;
struct quota2_entry q2e;
struct ufs_quota_entry qe[QUOTA_NLIMITS];
prop_dictionary_t dict;
int error;
uint64_t *valuesp[QUOTA_NLIMITS];
valuesp[QUOTA_LIMIT_BLOCK] = &qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
valuesp[QUOTA_LIMIT_FILE] = &qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
if (ump->um_quotas[type] == NULLVP)
return ENODEV;
@ -511,25 +515,28 @@ quota1_handle_cmd_get(struct ufsmount *ump, int type, int id,
if (defaultq) { /* we want the grace period of id 0 */
if ((error = dqget(NULLVP, 0, ump, type, &dq)) != 0)
return error;
} else {
if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0)
return error;
}
dqblk2q2e(&dq->dq_un.dq1_dqb, &q2e);
dqblk2ufsqe(&dq->dq_un.dq1_dqb, qe);
dqrele(NULLVP, dq);
if (defaultq) {
if (q2e.q2e_val[QL_BLOCK].q2v_time > 0)
q2e.q2e_val[QL_BLOCK].q2v_grace =
q2e.q2e_val[QL_BLOCK].q2v_time;
if (qe[QUOTA_LIMIT_BLOCK].ufsqe_time > 0)
qe[QUOTA_LIMIT_BLOCK].ufsqe_grace =
qe[QUOTA_LIMIT_BLOCK].ufsqe_time;
else
q2e.q2e_val[QL_BLOCK].q2v_grace = MAX_DQ_TIME;
if (q2e.q2e_val[QL_FILE].q2v_time > 0)
q2e.q2e_val[QL_FILE].q2v_grace =
q2e.q2e_val[QL_FILE].q2v_time;
qe[QUOTA_LIMIT_BLOCK].ufsqe_grace = MAX_DQ_TIME;
if (qe[QUOTA_LIMIT_FILE].ufsqe_time > 0)
qe[QUOTA_LIMIT_FILE].ufsqe_grace =
qe[QUOTA_LIMIT_FILE].ufsqe_time;
else
q2e.q2e_val[QL_FILE].q2v_grace = MAX_DQ_TIME;
qe[QUOTA_LIMIT_FILE].ufsqe_grace = MAX_DQ_TIME;
}
dict = q2etoprop(&q2e, defaultq);
dict = quota64toprop(id, defaultq, valuesp,
ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (dict == NULL)
return ENOMEM;
if (!prop_array_add_and_rel(replies, dict))
@ -542,35 +549,48 @@ quota1_handle_cmd_set(struct ufsmount *ump, int type, int id,
int defaultq, prop_dictionary_t data)
{
struct dquot *dq;
struct quota2_entry q2e;
struct dqblk dqb;
int error;
uint64_t bval[2];
uint64_t ival[2];
const char *val_limitsonly_grace[] = {QUOTADICT_LIMIT_GTIME};
#define Q1_GTIME 0
const char *val_limitsonly_softhard[] =
{QUOTADICT_LIMIT_SOFT, QUOTADICT_LIMIT_HARD};
#define Q1_SOFT 0
#define Q1_HARD 1
uint64_t *valuesp[QUOTA_NLIMITS];
valuesp[QUOTA_LIMIT_BLOCK] = bval;
valuesp[QUOTA_LIMIT_FILE] = ival;
if (ump->um_quotas[type] == NULLVP)
return ENODEV;
error = quota2_dict_update_q2e_limits(data, &q2e);
if (error)
return error;
if (defaultq) {
/* just update grace times */
error = proptoquota64(data, valuesp, val_limitsonly_grace, 1,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (error)
return error;
if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0)
return error;
mutex_enter(&dq->dq_interlock);
if (q2e.q2e_val[QL_BLOCK].q2v_grace > 0)
if (bval[Q1_GTIME] > 0)
ump->umq1_btime[type] = dq->dq_btime =
q2e.q2e_val[QL_BLOCK].q2v_grace;
if (q2e.q2e_val[QL_FILE].q2v_grace > 0)
bval[Q1_GTIME];
if (ival[Q1_GTIME] > 0)
ump->umq1_itime[type] = dq->dq_itime =
q2e.q2e_val[QL_FILE].q2v_grace;
ival[Q1_GTIME];
mutex_exit(&dq->dq_interlock);
dq->dq_flags |= DQ_MOD;
dqrele(NULLVP, dq);
return 0;
}
q2e2dqblk(&q2e, &dqb);
error = proptoquota64(data, valuesp, val_limitsonly_softhard, 2,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (error)
return error;
if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0)
return (error);
@ -582,9 +602,23 @@ quota1_handle_cmd_set(struct ufsmount *ump, int type, int id,
*/
dqb.dqb_curblocks = dq->dq_curblocks;
dqb.dqb_curinodes = dq->dq_curinodes;
if (dq->dq_id != 0) {
dqb.dqb_btime = dq->dq_btime;
dqb.dqb_itime = dq->dq_itime;
dqb.dqb_bsoftlimit = (bval[Q1_SOFT] == UQUAD_MAX) ? 0 : bval[Q1_SOFT];
dqb.dqb_bhardlimit = (bval[Q1_HARD] == UQUAD_MAX) ? 0 : bval[Q1_HARD];
dqb.dqb_isoftlimit = (ival[Q1_SOFT] == UQUAD_MAX) ? 0 : ival[Q1_SOFT];
dqb.dqb_ihardlimit = (ival[Q1_HARD] == UQUAD_MAX) ? 0 : ival[Q1_HARD];
if (dq->dq_id == 0) {
/* also update grace time if available */
if (proptoquota64(data, valuesp, val_limitsonly_grace, 1,
ufs_quota_limit_names, QUOTA_NLIMITS) == 0) {
if (bval[Q1_GTIME] > 0)
ump->umq1_btime[type] = dqb.dqb_btime =
bval[Q1_GTIME];
if (ival[Q1_GTIME] > 0)
ump->umq1_itime[type] = dqb.dqb_itime =
ival[Q1_GTIME];
}
}
if (dqb.dqb_bsoftlimit &&
dq->dq_curblocks >= dqb.dqb_bsoftlimit &&

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_quota2.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: ufs_quota2.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $");
#include <sys/buf.h>
#include <sys/param.h>
@ -51,7 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $"
#include <ufs/ufs/ufs_extern.h>
#include <ufs/ufs/ufs_quota.h>
#include <ufs/ufs/ufs_wapbl.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
/*
* LOCKING:
@ -75,7 +75,68 @@ static int quota2_walk_list(struct ufsmount *, struct buf *, int,
int (*func)(struct ufsmount *, uint64_t *, struct quota2_entry *,
uint64_t, void *));
static const char *valtypes[] = INITQLNAMES;
static int quota2_dict_update_q2e_limits(prop_dictionary_t,
struct quota2_entry *);
static prop_dictionary_t q2etoprop(struct quota2_entry *, int);
static const char *limnames[] = INITQLNAMES;
static int
quota2_dict_update_q2e_limits(prop_dictionary_t data,
struct quota2_entry *q2e)
{
const char *val_limitsonly_names[] = INITQVNAMES_LIMITSONLY;
int i, error;
prop_dictionary_t val;
for (i = 0; i < N_QL; i++) {
if (!prop_dictionary_get_dict(data, limnames[i], &val))
return EINVAL;
error = quotaprop_dict_get_uint64(val,
&q2e->q2e_val[i].q2v_hardlimit,
val_limitsonly_names, N_QV, true);
if (error)
return error;
}
return 0;
}
static prop_dictionary_t
q2etoprop(struct quota2_entry *q2e, int def)
{
const char *val_names[] = INITQVNAMES_ALL;
prop_dictionary_t dict1 = prop_dictionary_create();
prop_dictionary_t dict2;
int i;
if (dict1 == NULL)
return NULL;
if (def) {
if (!prop_dictionary_set_cstring_nocopy(dict1, "id",
"default")) {
goto err;
}
} else {
if (!prop_dictionary_set_uint32(dict1, "id", q2e->q2e_uid)) {
goto err;
}
}
for (i = 0; i < N_QL; i++) {
dict2 = limits64toprop(&q2e->q2e_val[i].q2v_hardlimit,
val_names, N_QV);
if (dict2 == NULL)
goto err;
if (!prop_dictionary_set_and_rel(dict1, limnames[i], dict2))
goto err;
}
return dict1;
err:
prop_object_release(dict1);
return NULL;
}
static int
quota2_bwrite(struct mount *mp, struct buf *bp)
@ -457,7 +518,7 @@ quota2_check(struct inode *ip, int vtype, int64_t change, kauth_cred_t cred,
uprintf("\n%s: write failed, %s %s "
"limit reached\n",
mp->mnt_stat.f_mntonname,
quotatypes[i], valtypes[vtype]);
quotatypes[i], limnames[vtype]);
dq->dq_flags |= DQ_WARN(vtype);
}
error = EDQUOT;
@ -467,7 +528,7 @@ quota2_check(struct inode *ip, int vtype, int64_t change, kauth_cred_t cred,
uprintf("\n%s: write failed, %s %s "
"limit reached\n",
mp->mnt_stat.f_mntonname,
quotatypes[i], valtypes[vtype]);
quotatypes[i], limnames[vtype]);
dq->dq_flags |= DQ_WARN(vtype);
}
error = EDQUOT;
@ -477,7 +538,7 @@ quota2_check(struct inode *ip, int vtype, int64_t change, kauth_cred_t cred,
uprintf("\n%s: warning, %s %s "
"quota exceeded\n",
mp->mnt_stat.f_mntonname,
quotatypes[i], valtypes[vtype]);
quotatypes[i], limnames[vtype]);
dq->dq_flags |= DQ_WARN(vtype);
}
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_vfsops.c,v 1.41 2011/03/06 17:08:39 bouyer Exp $ */
/* $NetBSD: ufs_vfsops.c,v 1.42 2011/03/24 17:05:46 bouyer Exp $ */
/*
* Copyright (c) 1991, 1993, 1994
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.41 2011/03/06 17:08:39 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.42 2011/03/24 17:05:46 bouyer Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -62,7 +62,7 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.41 2011/03/06 17:08:39 bouyer Exp $
#ifdef UFS_DIRHASH
#include <ufs/ufs/dirhash.h>
#endif
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
/* how many times ufs_init() was called */
static int ufs_initcount = 0;
@ -120,7 +120,7 @@ ufs_quotactl(struct mount *mp, prop_dictionary_t dict)
if (error)
return (error);
error = quota2_get_cmds(dict, &commands);
error = quota_get_cmds(dict, &commands);
if (error)
goto out_vfs;
iter = prop_array_iterator(commands);

View File

@ -1,15 +1,13 @@
# $NetBSD: Makefile,v 1.9 2011/03/06 22:36:07 christos Exp $
# $NetBSD: Makefile,v 1.10 2011/03/24 17:05:46 bouyer Exp $
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
WARNS ?= 4
.include <bsd.own.mk>
PROG= quota
SRCS= quota.c printquota.c getvfsquota.c quotautil.c
SRCS= quota.c printquota.c getvfsquota.c
CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
DPADD= ${LIBRPCSVC} ${LIBPROP}
LDADD= -lrpcsvc -lprop
CPPFLAGS+= -I${NETBSDSRCDIR}/usr.bin/quota
DPADD= ${LIBQUOTA} ${LIBRPCSVC} ${LIBPROP}
LDADD= -lquota -lrpcsvc -lprop
.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs
SRCS+= quota2_prop.c quota2_subr.c quota1_subr.c
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $ */
/* $NetBSD: getvfsquota.c,v 1.6 2011/03/24 17:05:46 bouyer Exp $ */
/*-
* Copyright (c) 2011 Manuel Bouyer
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $");
__RCSID("$NetBSD: getvfsquota.c,v 1.6 2011/03/24 17:05:46 bouyer Exp $");
#include <stdio.h>
#include <stdlib.h>
@ -39,14 +39,14 @@ __RCSID("$NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $");
#include <sys/types.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
#include <sys/quota.h>
#include "getvfsquota.h"
/* retrieve quotas from vfs, for the given user id */
/* private version of getufsquota() */
int
getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
getvfsquota(const char *mp, struct ufs_quota_entry *qv, int8_t *versp,
uint32_t id, int type, int defaultq, int debug)
{
prop_dictionary_t dict, data, cmd;
@ -57,7 +57,7 @@ getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
bool ret;
int retval = 0;
dict = quota2_prop_create();
dict = quota_prop_create();
cmds = prop_array_create();
datas = prop_array_create();
data = prop_dictionary_create();
@ -74,9 +74,11 @@ getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
if (!prop_array_add_and_rel(datas, data))
err(1, "prop_array_add(data)");
if (!quota2_prop_add_command(cmds, "get", qfextension[type], datas))
if (!quota_prop_add_command(cmds, "get",
ufs_quota_class_names[type], datas))
err(1, "prop_add_command");
if (!quota2_prop_add_command(cmds, "get version", qfextension[type],
if (!quota_prop_add_command(cmds, "get version",
ufs_quota_class_names[type],
prop_array_create()))
err(1, "prop_add_command");
if (!prop_dictionary_set(dict, "commands", cmds))
@ -97,8 +99,8 @@ getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
if (debug)
printf("reply from kernel:\n%s\n",
prop_dictionary_externalize(dict));
if ((errno = quota2_get_cmds(dict, &cmds)) != 0)
err(1, "quota2_get_cmds");
if ((errno = quota_get_cmds(dict, &cmds)) != 0)
err(1, "quota_get_cmds");
iter = prop_array_iterator(cmds);
if (iter == NULL)
@ -117,10 +119,10 @@ getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
errno = error8;
if (defaultq) {
warn("get default %s quota",
qfextension[type]);
ufs_quota_class_names[type]);
} else {
warn("get %s quota for %u",
qfextension[type], id);
ufs_quota_class_names[type], id);
}
}
prop_object_release(dict);
@ -143,13 +145,21 @@ getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
/* only one data, no need to iter */
if (prop_array_count(datas) > 0) {
uint64_t *values[QUOTA_NLIMITS];
data = prop_array_get(datas, 0);
if (data == NULL)
err(1, "prop_array_get(data)");
errno = quota2_dict_get_q2e_usage(data, q2e);
values[QUOTA_LIMIT_BLOCK] =
&qv[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
values[QUOTA_LIMIT_FILE] =
&qv[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
errno = proptoquota64(data, values,
ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (errno)
err(1, "quota2_dict_get_q2e_usage");
err(1, "proptoquota64");
retval = 1;
}
}

View File

@ -1,6 +1,4 @@
/* $NetBSD: getvfsquota.h,v 1.3 2011/03/06 20:47:59 christos Exp $ */
/* $NetBSD: getvfsquota.h,v 1.4 2011/03/24 17:05:46 bouyer Exp $ */
int getvfsquota(const char *, struct quota2_entry *, int8_t *,
int getvfsquota(const char *, struct ufs_quota_entry *, int8_t *,
uint32_t, int, int, int);
extern const char *qfextension[];

View File

@ -1,4 +1,4 @@
/* $NetBSD: printquota.c,v 1.5 2011/03/07 11:46:55 bouyer Exp $ */
/* $NetBSD: printquota.c,v 1.6 2011/03/24 17:05:46 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
#if 0
static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: printquota.c,v 1.5 2011/03/07 11:46:55 bouyer Exp $");
__RCSID("$NetBSD: printquota.c,v 1.6 2011/03/24 17:05:46 bouyer Exp $");
#endif
#endif /* not lint */
@ -271,3 +271,16 @@ intrd(char *str, uint64_t *val, u_int flags)
*val = btodb(*val);
return ret;
}
int
alldigits(const char *s)
{
unsigned char c;
c = *s++;
do {
if (!isdigit(c))
return 0;
} while ((c = *s++) != 0);
return 1;
}

View File

@ -1,7 +1,8 @@
/* $NetBSD: printquota.h,v 1.4 2011/03/06 22:36:07 christos Exp $ */
/* $NetBSD: printquota.h,v 1.5 2011/03/24 17:05:46 bouyer Exp $ */
const char *intprt(char *, size_t, uint64_t, int, int);
const char *timeprt(char *, size_t, time_t, time_t);
const char *timepprt(char *, size_t, time_t, int);
int timeprd(const char *, time_t *);
int intrd(char *str, uint64_t *val, u_int);
int alldigits(const char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: quota.c,v 1.36 2011/03/06 22:36:07 christos Exp $ */
/* $NetBSD: quota.c,v 1.37 2011/03/24 17:05:46 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
#if 0
static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: quota.c,v 1.36 2011/03/06 22:36:07 christos Exp $");
__RCSID("$NetBSD: quota.c,v 1.37 2011/03/24 17:05:46 bouyer Exp $");
#endif
#endif /* not lint */
@ -69,29 +69,22 @@ __RCSID("$NetBSD: quota.c,v 1.36 2011/03/06 22:36:07 christos Exp $");
#include <time.h>
#include <unistd.h>
#include <ufs/ufs/quota2.h>
#include <ufs/ufs/quota1.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpcsvc/rquota.h>
#include <quota/quotaprop.h>
#include <quota/quota.h>
#include "printquota.h"
#include "quotautil.h"
#include "getvfsquota.h"
struct quotause {
struct quotause *next;
long flags;
struct quota2_entry q2e;
uid_t id;
struct ufs_quota_entry qe[QUOTA_NLIMITS];
char fsname[MAXPATHLEN + 1];
};
#define FOUND 0x01
#define QUOTA2 0x02
static int callaurpc(const char *, rpcprog_t, rpcvers_t, rpcproc_t,
xdrproc_t, void *, xdrproc_t, void *);
static int getnfsquota(struct statvfs *, struct quotause *, uint32_t, int);
static struct quotause *getprivs(uint32_t, int);
static void heading(int, uint32_t, const char *, const char *);
static void showgid(gid_t);
@ -154,9 +147,9 @@ main(int argc, char *argv[])
errx(1, "-d: permission denied");
#endif
if (uflag)
showquotas(USRQUOTA, 0, "");
showquotas(QUOTA_CLASS_USER, 0, "");
if (gflag)
showquotas(GRPQUOTA, 0, "");
showquotas(QUOTA_CLASS_GROUP, 0, "");
return 0;
}
if (argc == 0) {
@ -230,7 +223,7 @@ showuid(uid_t uid)
warnx("%s (uid %d): permission denied", name, uid);
return;
}
showquotas(USRQUOTA, uid, name);
showquotas(QUOTA_CLASS_USER, uid, name);
}
/*
@ -249,7 +242,7 @@ showusrname(const char *name)
warnx("%s (uid %d): permission denied", name, pwd->pw_uid);
return;
}
showquotas(USRQUOTA, pwd->pw_uid, name);
showquotas(QUOTA_CLASS_USER, pwd->pw_uid, name);
}
/*
@ -283,7 +276,7 @@ showgid(gid_t gid)
return;
}
}
showquotas(GRPQUOTA, gid, name);
showquotas(QUOTA_CLASS_GROUP, gid, name);
}
/*
@ -317,7 +310,7 @@ showgrpname(const char *name)
return;
}
}
showquotas(GRPQUOTA, grp->gr_gid, name);
showquotas(QUOTA_CLASS_GROUP, grp->gr_gid, name);
}
static void
@ -335,14 +328,17 @@ showquotas(int type, uint32_t id, const char *name)
quplist = getprivs(id, type);
for (qup = quplist; qup; qup = qup->next) {
int ql_stat;
struct quota2_val *q = qup->q2e.q2e_val;
struct ufs_quota_entry *q = qup->qe;
if (!vflag &&
q[QL_BLOCK].q2v_softlimit == UQUAD_MAX &&
q[QL_BLOCK].q2v_hardlimit == UQUAD_MAX &&
q[QL_FILE].q2v_softlimit == UQUAD_MAX &&
q[QL_FILE].q2v_hardlimit == UQUAD_MAX)
q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit == UQUAD_MAX &&
q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit == UQUAD_MAX &&
q[QUOTA_LIMIT_FILE].ufsqe_softlimit == UQUAD_MAX &&
q[QUOTA_LIMIT_FILE].ufsqe_hardlimit == UQUAD_MAX)
continue;
ql_stat = quota2_check_limit(&q[QL_FILE], 1, now);
ql_stat = quota_check_limit(q[QUOTA_LIMIT_FILE].ufsqe_cur, 1,
q[QUOTA_LIMIT_FILE].ufsqe_softlimit,
q[QUOTA_LIMIT_FILE].ufsqe_hardlimit,
q[QUOTA_LIMIT_FILE].ufsqe_time, now);
switch(QL_STATUS(ql_stat)) {
case QL_S_DENY_HARD:
msgi = "File limit reached on";
@ -356,7 +352,10 @@ showquotas(int type, uint32_t id, const char *name)
default:
msgi = NULL;
}
ql_stat = quota2_check_limit(&q[QL_BLOCK], 1, now);
ql_stat = quota_check_limit(q[QUOTA_LIMIT_BLOCK].ufsqe_cur, 1,
q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
q[QUOTA_LIMIT_BLOCK].ufsqe_time, now);
switch(QL_STATUS(ql_stat)) {
case QL_S_DENY_HARD:
msgb = "Block limit reached on";
@ -380,8 +379,9 @@ showquotas(int type, uint32_t id, const char *name)
printf("\t%s %s\n", msgb, qup->fsname);
continue;
}
if (vflag || dflag || msgi || msgb || q[QL_BLOCK].q2v_cur ||
q[QL_FILE].q2v_cur) {
if (vflag || dflag || msgi || msgb ||
q[QUOTA_LIMIT_BLOCK].ufsqe_cur ||
q[QUOTA_LIMIT_FILE].ufsqe_cur) {
if (lines++ == 0)
heading(type, id, name, "");
nam = qup->fsname;
@ -391,38 +391,41 @@ showquotas(int type, uint32_t id, const char *name)
}
if (msgb)
timemsg = timeprt(b0, 9, now,
q[QL_BLOCK].q2v_time);
q[QUOTA_LIMIT_BLOCK].ufsqe_time);
else if ((qup->flags & QUOTA2) != 0 && vflag)
timemsg = timeprt(b0, 9, 0,
q[QL_BLOCK].q2v_grace);
q[QUOTA_LIMIT_BLOCK].ufsqe_grace);
else
timemsg = "";
printf("%12s%9s%c%8s%9s%8s",
nam,
intprt(b1, 9, q[QL_BLOCK].q2v_cur,
intprt(b1, 9, q[QUOTA_LIMIT_BLOCK].ufsqe_cur,
HN_B, hflag),
(msgb == NULL) ? ' ' : '*',
intprt(b2, 9, q[QL_BLOCK].q2v_softlimit,
intprt(b2, 9, q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
HN_B, hflag),
intprt(b3, 9, q[QL_BLOCK].q2v_hardlimit,
intprt(b3, 9, q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
HN_B, hflag),
timemsg);
if (msgi)
timemsg = timeprt(b0, 9, now,
q[QL_FILE].q2v_time);
q[QUOTA_LIMIT_FILE].ufsqe_time);
else if ((qup->flags & QUOTA2) != 0 && vflag)
timemsg = timeprt(b0, 9, 0,
q[QL_FILE].q2v_grace);
q[QUOTA_LIMIT_FILE].ufsqe_grace);
else
timemsg = "";
printf("%8s%c%7s%8s%8s\n",
intprt(b1, 8, q[QL_FILE].q2v_cur, 0, hflag),
intprt(b1, 8, q[QUOTA_LIMIT_FILE].ufsqe_cur, 0,
hflag),
(msgi == NULL) ? ' ' : '*',
intprt(b2, 8, q[QL_FILE].q2v_softlimit, 0, hflag),
intprt(b3, 8, q[QL_FILE].q2v_hardlimit, 0, hflag),
intprt(b2, 8, q[QUOTA_LIMIT_FILE].ufsqe_softlimit,
0, hflag),
intprt(b3, 8, q[QUOTA_LIMIT_FILE].ufsqe_hardlimit,
0, hflag),
timemsg);
continue;
}
@ -436,11 +439,11 @@ heading(int type, uint32_t id, const char *name, const char *tag)
{
if (dflag)
printf("Default %s disk quotas: %s\n",
qfextension[type], tag);
ufs_quota_class_names[type], tag);
else
printf("Disk quotas for %s %s (%cid %u): %s\n",
qfextension[type], name, *qfextension[type],
id, tag);
ufs_quota_class_names[type], name,
*ufs_quota_class_names[type], id, tag);
if (!qflag && tag[0] == '\0') {
printf("%12s%9s %8s%9s%8s%8s %7s%8s%8s\n"
@ -482,11 +485,12 @@ getprivs(uint32_t id, int quotatype)
if (strncmp(fst[i].f_fstypename, "nfs",
sizeof(fst[i].f_fstypename)) == 0) {
version = 0;
if (getnfsquota(&fst[i], qup, id, quotatype) == 0)
if (getnfsquota(fst[i].f_mntfromname,
qup->qe, id, ufs_quota_class_names[quotatype]) != 1)
continue;
} else if ((fst[i].f_flag & ST_QUOTA) != 0) {
if (getvfsquota(fst[i].f_mntonname, &qup->q2e, &version,
id, quotatype, dflag, Dflag) == 0)
if (getvfsquota(fst[i].f_mntonname, qup->qe, &version,
id, quotatype, dflag, Dflag) != 1)
continue;
} else
continue;
@ -505,136 +509,3 @@ getprivs(uint32_t id, int quotatype)
free(qup);
return quphead;
}
static int
getnfsquota(struct statvfs *fst, struct quotause *qup,
uint32_t id, int quotatype)
{
struct getquota_args gq_args;
struct ext_getquota_args ext_gq_args;
struct getquota_rslt gq_rslt;
struct quota2_entry *q2e = &qup->q2e;
struct dqblk dqblk;
struct timeval tv;
char *cp;
int ret;
if (fst->f_flag & MNT_LOCAL)
return 0;
/*
* must be some form of "hostname:/path"
*/
cp = strchr(fst->f_mntfromname, ':');
if (cp == NULL) {
warnx("cannot find hostname for %s", fst->f_mntfromname);
return 0;
}
*cp = '\0';
if (*(cp+1) != '/') {
*cp = ':';
return 0;
}
ext_gq_args.gqa_pathp = cp + 1;
ext_gq_args.gqa_id = id;
ext_gq_args.gqa_type =
(quotatype == USRQUOTA) ? RQUOTA_USRQUOTA : RQUOTA_GRPQUOTA;
ret = callaurpc(fst->f_mntfromname, RQUOTAPROG, EXT_RQUOTAVERS,
RQUOTAPROC_GETQUOTA, xdr_ext_getquota_args, &ext_gq_args,
xdr_getquota_rslt, &gq_rslt);
if (ret == RPC_PROGVERSMISMATCH) {
if (quotatype != USRQUOTA) {
*cp = ':';
return 0;
}
/* try RQUOTAVERS */
gq_args.gqa_pathp = cp + 1;
gq_args.gqa_uid = id;
ret = callaurpc(fst->f_mntfromname, RQUOTAPROG, RQUOTAVERS,
RQUOTAPROC_GETQUOTA, xdr_getquota_args, &gq_args,
xdr_getquota_rslt, &gq_rslt);
}
if (ret != RPC_SUCCESS) {
*cp = ':';
return 0;
}
switch (gq_rslt.status) {
case Q_NOQUOTA:
break;
case Q_EPERM:
warnx("quota permission error, host: %s", fst->f_mntfromname);
break;
case Q_OK:
gettimeofday(&tv, NULL);
/* blocks*/
q2e->q2e_val[QL_BLOCK].q2v_hardlimit =
dqblk.dqb_bhardlimit =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit *
(gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
dqblk.dqb_bsoftlimit =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit *
(gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
dqblk.dqb_curblocks =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks *
(gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
/* inodes */
dqblk.dqb_ihardlimit =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit;
dqblk.dqb_isoftlimit =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit;
dqblk.dqb_curinodes =
gq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles;
/* grace times */
dqblk.dqb_btime = (int)(tv.tv_sec +
gq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft);
dqblk.dqb_itime = (int)(tv.tv_sec +
gq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft);
dqblk2q2e(&dqblk, q2e);
*cp = ':';
return 1;
default:
warnx("bad rpc result, host: %s", fst->f_mntfromname);
break;
}
*cp = ':';
return 0;
}
static int
callaurpc(const char *host, rpcprog_t prognum, rpcvers_t versnum,
rpcproc_t procnum, xdrproc_t inproc, void *in, xdrproc_t outproc, void *out)
{
struct sockaddr_in server_addr;
enum clnt_stat clnt_stat;
struct hostent *hp;
struct timeval timeout, tottimeout;
CLIENT *client = NULL;
int sock = RPC_ANYSOCK;
if ((hp = gethostbyname(host)) == NULL)
return (int) RPC_UNKNOWNHOST;
timeout.tv_usec = 0;
timeout.tv_sec = 6;
memmove(&server_addr.sin_addr, hp->h_addr, hp->h_length);
server_addr.sin_family = AF_INET;
server_addr.sin_port = 0;
if ((client = clntudp_create(&server_addr, prognum,
versnum, timeout, &sock)) == NULL)
return (int) rpc_createerr.cf_stat;
client->cl_auth = authunix_create_default();
tottimeout.tv_sec = 25;
tottimeout.tv_usec = 0;
clnt_stat = clnt_call(client, procnum, inproc, in,
outproc, out, tottimeout);
return (int) clnt_stat;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: quotautil.c,v 1.2 2011/03/06 23:26:05 christos Exp $ */
/* $NetBSD: quotautil.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
#if 0
static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: quotautil.c,v 1.2 2011/03/06 23:26:05 christos Exp $");
__RCSID("$NetBSD: quotautil.c,v 1.3 2011/03/24 17:05:46 bouyer Exp $");
#endif
#endif /* not lint */
@ -60,13 +60,13 @@ __RCSID("$NetBSD: quotautil.c,v 1.2 2011/03/06 23:26:05 christos Exp $");
#include <limits.h>
#include <inttypes.h>
#include <ufs/ufs/quota2.h>
#include <quota/quotaprop.h>
#include <ufs/ufs/quota1.h>
#include "quotautil.h"
const char *qfextension[MAXQUOTAS] = INITQFNAMES;
const char *qfname = QUOTAFILENAME;
const char *qfextension[] = INITQFNAMES;
const char *qfnamep = QUOTAFILENAME;
/*
* Check to see if a particular quota is to be enabled.
@ -105,19 +105,6 @@ hasquota(char *buf, size_t len, struct fstab *fs, int type)
return 1;
}
int
alldigits(const char *s)
{
unsigned char c;
c = *s++;
do {
if (!isdigit(c))
return 0;
} while ((c = *s++) != 0);
return 1;
}
/*
* Check to see if target appears in list of size cnt.
*/

View File

@ -1,8 +1,7 @@
/* $NetBSD: quotautil.h,v 1.2 2011/03/06 23:26:16 christos Exp $ */
/* $NetBSD: quotautil.h,v 1.3 2011/03/24 17:05:46 bouyer Exp $ */
const char *qfextension[MAXQUOTAS];
const char *qfname;
struct fstab;
int hasquota(char *, size_t, struct fstab *, int);
int alldigits(const char *);
int oneof(const char *, char *[], int);

View File

@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
# $NetBSD: Makefile,v 1.7 2011/03/06 22:34:57 christos Exp $
# $NetBSD: Makefile,v 1.8 2011/03/24 17:05:47 bouyer Exp $
.include <bsd.own.mk>
@ -9,12 +9,12 @@ SRCS= edquota.c
MAN= edquota.8
CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
DPADD= ${LIBPROP}
LDADD= -lprop
DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
LDADD= -lquota -lprop -lrpcsvc
.PATH: ${NETBSDSRCDIR}/usr.bin/quota
SRCS+= getvfsquota.c printquota.c quotautil.c
.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs
SRCS+= quota2_prop.c quota1_subr.c
SRCS+= quota1_subr.c
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: edquota.c,v 1.31 2011/03/06 22:34:57 christos Exp $ */
/* $NetBSD: edquota.c,v 1.32 2011/03/24 17:05:47 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
* The Regents of the University of California. All rights reserved.
@ -41,7 +41,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
#if 0
static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95";
#else
__RCSID("$NetBSD: edquota.c,v 1.31 2011/03/06 22:34:57 christos Exp $");
__RCSID("$NetBSD: edquota.c,v 1.32 2011/03/24 17:05:47 bouyer Exp $");
#endif
#endif /* not lint */
@ -56,7 +56,8 @@ __RCSID("$NetBSD: edquota.c,v 1.31 2011/03/06 22:34:57 christos Exp $");
#include <sys/types.h>
#include <sys/statvfs.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
#include <quota/quota.h>
#include <ufs/ufs/quota1.h>
#include <sys/quota.h>
@ -85,7 +86,7 @@ static char tmpfil[] = _PATH_TMP;
struct quotause {
struct quotause *next;
long flags;
struct quota2_entry q2e;
struct ufs_quota_entry qe[QUOTA_NLIMITS];
char fsname[MAXPATHLEN + 1];
char *qfname;
};
@ -114,12 +115,16 @@ static int Hflag = 0;
static int Dflag = 0;
static int dflag = 0;
/* more compact form of constants */
#define QL_BLK QUOTA_LIMIT_BLOCK
#define QL_FL QUOTA_LIMIT_FILE
int
main(int argc, char *argv[])
{
struct quotause *qup, *protoprivs, *curprivs;
long id, protoid;
int quotatype, tmpfd;
int quotaclass, tmpfd;
char *protoname;
char *soft = NULL, *hard = NULL, *grace = NULL;
char *fs = NULL;
@ -132,7 +137,7 @@ main(int argc, char *argv[])
if (getuid())
errx(1, "permission denied");
protoname = NULL;
quotatype = USRQUOTA;
quotaclass = QUOTA_CLASS_USER;
while ((ch = getopt(argc, argv, "DHcdugp:s:h:t:f:")) != -1) {
switch(ch) {
case 'D':
@ -152,10 +157,10 @@ main(int argc, char *argv[])
pflag++;
break;
case 'g':
quotatype = GRPQUOTA;
quotaclass = QUOTA_CLASS_GROUP;
break;
case 'u':
quotatype = USRQUOTA;
quotaclass = QUOTA_CLASS_USER;
break;
case 's':
soft = optarg;
@ -179,17 +184,17 @@ main(int argc, char *argv[])
if (pflag) {
if (soft || hard || grace || dflag || cflag)
usage();
if ((protoid = getentry(protoname, quotatype)) == -1)
if ((protoid = getentry(protoname, quotaclass)) == -1)
return 1;
protoprivs = getprivs(protoid, quotatype, fs, 0);
protoprivs = getprivs(protoid, quotaclass, fs, 0);
for (qup = protoprivs; qup; qup = qup->next) {
qup->q2e.q2e_val[QL_BLOCK].q2v_time = 0;
qup->q2e.q2e_val[QL_FILE].q2v_time = 0;
qup->qe[QL_BLK].ufsqe_time = 0;
qup->qe[QL_FL].ufsqe_time = 0;
}
while (argc-- > 0) {
if ((id = getentry(*argv++, quotatype)) < 0)
if ((id = getentry(*argv++, quotaclass)) < 0)
continue;
putprivs(id, quotatype, protoprivs);
putprivs(id, quotaclass, protoprivs);
}
return 0;
}
@ -232,58 +237,58 @@ main(int argc, char *argv[])
errx(1, "%s: bad number", grace);
}
if (dflag) {
curprivs = getprivs(0, quotatype, fs, 1);
curprivs = getprivs(0, quotaclass, fs, 1);
for (lqup = curprivs; lqup; lqup = lqup->next) {
struct quota2_val *q = lqup->q2e.q2e_val;
struct ufs_quota_entry *q = lqup->qe;
if (soft) {
q[QL_BLOCK].q2v_softlimit = softb;
q[QL_FILE].q2v_softlimit = softi;
q[QL_BLK].ufsqe_softlimit = softb;
q[QL_FL].ufsqe_softlimit = softi;
}
if (hard) {
q[QL_BLOCK].q2v_hardlimit = hardb;
q[QL_FILE].q2v_hardlimit = hardi;
q[QL_BLK].ufsqe_hardlimit = hardb;
q[QL_FL].ufsqe_hardlimit = hardi;
}
if (grace) {
q[QL_BLOCK].q2v_grace = graceb;
q[QL_FILE].q2v_grace = gracei;
q[QL_BLK].ufsqe_grace = graceb;
q[QL_FL].ufsqe_grace = gracei;
}
}
putprivs(0, quotatype, curprivs);
putprivs(0, quotaclass, curprivs);
freeprivs(curprivs);
return 0;
}
for ( ; argc > 0; argc--, argv++) {
if ((id = getentry(*argv, quotatype)) == -1)
if ((id = getentry(*argv, quotaclass)) == -1)
continue;
curprivs = getprivs(id, quotatype, fs, 0);
curprivs = getprivs(id, quotaclass, fs, 0);
for (lqup = curprivs; lqup; lqup = lqup->next) {
struct quota2_val *q = lqup->q2e.q2e_val;
struct ufs_quota_entry *q = lqup->qe;
if (soft) {
if (softb &&
q[QL_BLOCK].q2v_cur >= softb &&
(q[QL_BLOCK].q2v_softlimit == 0 ||
q[QL_BLOCK].q2v_cur <
q[QL_BLOCK].q2v_softlimit))
q[QL_BLOCK].q2v_time = 0;
q[QL_BLK].ufsqe_cur >= softb &&
(q[QL_BLK].ufsqe_softlimit == 0 ||
q[QL_BLK].ufsqe_cur <
q[QL_BLK].ufsqe_softlimit))
q[QL_BLK].ufsqe_time = 0;
if (softi &&
q[QL_FILE].q2v_cur >= softb &&
(q[QL_FILE].q2v_softlimit == 0 ||
q[QL_FILE].q2v_cur <
q[QL_FILE].q2v_softlimit))
q[QL_FILE].q2v_time = 0;
q[QL_BLOCK].q2v_softlimit = softb;
q[QL_FILE].q2v_softlimit = softi;
q[QL_FL].ufsqe_cur >= softb &&
(q[QL_FL].ufsqe_softlimit == 0 ||
q[QL_FL].ufsqe_cur <
q[QL_FL].ufsqe_softlimit))
q[QL_FL].ufsqe_time = 0;
q[QL_BLK].ufsqe_softlimit = softb;
q[QL_FL].ufsqe_softlimit = softi;
}
if (hard) {
q[QL_BLOCK].q2v_hardlimit = hardb;
q[QL_FILE].q2v_hardlimit = hardi;
q[QL_BLK].ufsqe_hardlimit = hardb;
q[QL_FL].ufsqe_hardlimit = hardi;
}
if (grace) {
q[QL_BLOCK].q2v_grace = graceb;
q[QL_FILE].q2v_grace = gracei;
q[QL_BLK].ufsqe_grace = graceb;
q[QL_FL].ufsqe_grace = gracei;
}
}
putprivs(id, quotatype, curprivs);
putprivs(id, quotaclass, curprivs);
freeprivs(curprivs);
}
return 0;
@ -291,26 +296,26 @@ main(int argc, char *argv[])
if (cflag) {
if (dflag)
usage();
clearpriv(argc, argv, fs, quotatype);
clearpriv(argc, argv, fs, quotaclass);
return 0;
}
tmpfd = mkstemp(tmpfil);
fchown(tmpfd, getuid(), getgid());
if (dflag) {
curprivs = getprivs(0, quotatype, fs, 1);
if (writeprivs(curprivs, tmpfd, NULL, quotatype) &&
curprivs = getprivs(0, quotaclass, fs, 1);
if (writeprivs(curprivs, tmpfd, NULL, quotaclass) &&
editit(tmpfil) && readprivs(curprivs, tmpfd))
putprivs(0, quotatype, curprivs);
putprivs(0, quotaclass, curprivs);
freeprivs(curprivs);
}
for ( ; argc > 0; argc--, argv++) {
if ((id = getentry(*argv, quotatype)) == -1)
if ((id = getentry(*argv, quotaclass)) == -1)
continue;
curprivs = getprivs(id, quotatype, fs, 0);
if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)
curprivs = getprivs(id, quotaclass, fs, 0);
if (writeprivs(curprivs, tmpfd, *argv, quotaclass) == 0)
continue;
if (editit(tmpfil) && readprivs(curprivs, tmpfd))
putprivs(id, quotatype, curprivs);
putprivs(id, quotaclass, curprivs);
freeprivs(curprivs);
}
close(tmpfd);
@ -343,26 +348,26 @@ usage(void)
* getinoquota as to the interpretation of quota types.
*/
static int
getentry(const char *name, int quotatype)
getentry(const char *name, int quotaclass)
{
struct passwd *pw;
struct group *gr;
if (alldigits(name))
return atoi(name);
switch(quotatype) {
case USRQUOTA:
switch(quotaclass) {
case QUOTA_CLASS_USER:
if ((pw = getpwnam(name)) != NULL)
return pw->pw_uid;
warnx("%s: no such user", name);
break;
case GRPQUOTA:
case QUOTA_CLASS_GROUP:
if ((gr = getgrnam(name)) != NULL)
return gr->gr_gid;
warnx("%s: no such group", name);
break;
default:
warnx("%d: unknown quota type", quotatype);
warnx("%d: unknown quota type", quotaclass);
break;
}
sleep(1);
@ -373,7 +378,7 @@ getentry(const char *name, int quotatype)
* Collect the requested quota information.
*/
static struct quotause *
getprivs(long id, int quotatype, const char *filesys, int defaultq)
getprivs(long id, int quotaclass, const char *filesys, int defaultq)
{
struct statvfs *fst;
int nfst, i;
@ -390,7 +395,7 @@ getprivs(long id, int quotatype, const char *filesys, int defaultq)
if (filesys && strcmp(fst[i].f_mntonname, filesys) != 0 &&
strcmp(fst[i].f_mntfromname, filesys) != 0)
continue;
qup = getprivs2(id, quotatype, fst[i].f_mntonname, defaultq);
qup = getprivs2(id, quotaclass, fst[i].f_mntonname, defaultq);
if (qup == NULL)
return NULL;
if (quphead == NULL)
@ -405,7 +410,7 @@ getprivs(long id, int quotatype, const char *filesys, int defaultq)
if (defaultq)
errx(1, "no default quota for version 1");
/* if we get there, filesys is not mounted. try the old way */
qup = getprivs1(id, quotatype, filesys);
qup = getprivs1(id, quotaclass, filesys);
if (qup == NULL)
return NULL;
if (quphead == NULL)
@ -419,7 +424,7 @@ getprivs(long id, int quotatype, const char *filesys, int defaultq)
}
static struct quotause *
getprivs2(long id, int quotatype, const char *filesys, int defaultq)
getprivs2(long id, int quotaclass, const char *filesys, int defaultq)
{
struct quotause *qup;
int8_t version;
@ -430,23 +435,22 @@ getprivs2(long id, int quotatype, const char *filesys, int defaultq)
strcpy(qup->fsname, filesys);
if (defaultq)
qup->flags |= DEFAULT;
if (!getvfsquota(filesys, &qup->q2e, &version,
id, quotatype, defaultq, Dflag)) {
if (!getvfsquota(filesys, qup->qe, &version,
id, quotaclass, defaultq, Dflag)) {
/* no entry, get default entry */
if (!getvfsquota(filesys, &qup->q2e, &version,
id, quotatype, 1, Dflag)) {
if (!getvfsquota(filesys, qup->qe, &version,
id, quotaclass, 1, Dflag)) {
free(qup);
return NULL;
}
}
if (version == 2)
qup->flags |= QUOTA2;
qup->q2e.q2e_uid = id;
return qup;
}
static struct quotause *
getprivs1(long id, int quotatype, const char *filesys)
getprivs1(long id, int quotaclass, const char *filesys)
{
struct fstab *fs;
char qfpathname[MAXPATHLEN];
@ -465,7 +469,8 @@ getprivs1(long id, int quotatype, const char *filesys)
if (fs == NULL)
return NULL;
if (!hasquota(qfpathname, sizeof(qfpathname), fs, quotatype))
if (!hasquota(qfpathname, sizeof(qfpathname), fs,
ufsclass2qtype(quotaclass)))
return NULL;
if ((qup = malloc(sizeof(*qup))) == NULL)
err(1, "out of memory");
@ -479,7 +484,8 @@ getprivs1(long id, int quotatype, const char *filesys)
}
warnx("Creating quota file %s", qfpathname);
sleep(3);
(void)fchown(fd, getuid(), getentry(quotagroup, GRPQUOTA));
(void)fchown(fd, getuid(),
getentry(quotagroup, QUOTA_CLASS_GROUP));
(void)fchmod(fd, 0640);
}
(void)lseek(fd, (off_t)(id * sizeof(struct dqblk)),
@ -505,7 +511,7 @@ getprivs1(long id, int quotatype, const char *filesys)
close(fd);
qup->qfname = qfpathname;
endfsent();
dqblk2q2e(&dqblk, &qup->q2e);
dqblk2ufsqe(&dqblk, qup->qe);
return qup;
}
@ -513,34 +519,41 @@ getprivs1(long id, int quotatype, const char *filesys)
* Store the requested quota information.
*/
void
putprivs(uint32_t id, int quotatype, struct quotause *quplist)
putprivs(uint32_t id, int quotaclass, struct quotause *quplist)
{
struct quotause *qup;
for (qup = quplist; qup; qup = qup->next) {
if (qup->qfname == NULL)
putprivs2(id, quotatype, qup);
putprivs2(id, quotaclass, qup);
else
putprivs1(id, quotatype, qup);
putprivs1(id, quotaclass, qup);
}
}
static void
putprivs2(uint32_t id, int quotatype, struct quotause *qup)
putprivs2(uint32_t id, int quotaclass, struct quotause *qup)
{
prop_dictionary_t dict, data, cmd;
prop_array_t cmds, datas;
struct plistref pref;
int8_t error8;
uint64_t *valuesp[QUOTA_NLIMITS];
qup->q2e.q2e_uid = id;
data = q2etoprop(&qup->q2e, (qup->flags & DEFAULT) ? 1 : 0);
valuesp[QL_BLK] =
&qup->qe[QL_BLK].ufsqe_hardlimit;
valuesp[QL_FL] =
&qup->qe[QL_FL].ufsqe_hardlimit;
data = quota64toprop(id, (qup->flags & DEFAULT) ? 1 : 0,
valuesp, ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (data == NULL)
err(1, "q2etoprop(id)");
err(1, "quota64toprop(id)");
dict = quota2_prop_create();
dict = quota_prop_create();
cmds = prop_array_create();
datas = prop_array_create();
@ -551,8 +564,8 @@ putprivs2(uint32_t id, int quotatype, struct quotause *qup)
if (!prop_array_add_and_rel(datas, data))
err(1, "prop_array_add(data)");
if (!quota2_prop_add_command(cmds, "set",
qfextension[quotatype], datas))
if (!quota_prop_add_command(cmds, "set",
ufs_quota_class_names[quotaclass], datas))
err(1, "prop_add_command");
if (!prop_dictionary_set(dict, "commands", cmds))
err(1, "prop_dictionary_set(command)");
@ -575,8 +588,8 @@ putprivs2(uint32_t id, int quotatype, struct quotause *qup)
printf("reply from kernel:\n%s\n",
prop_dictionary_externalize(dict));
if ((errno = quota2_get_cmds(dict, &cmds)) != 0) {
err(1, "quota2_get_cmds");
if ((errno = quota_get_cmds(dict, &cmds)) != 0) {
err(1, "quota_get_cmds");
}
/* only one command, no need to iter */
cmd = prop_array_get(cmds, 0);
@ -589,20 +602,22 @@ putprivs2(uint32_t id, int quotatype, struct quotause *qup)
if (error8) {
errno = error8;
if (qup->flags & DEFAULT)
warn("set default %s quota", qfextension[quotatype]);
warn("set default %s quota",
ufs_quota_class_names[quotaclass]);
else
warn("set %s quota for %u", qfextension[quotatype], id);
warn("set %s quota for %u",
ufs_quota_class_names[quotaclass], id);
}
prop_object_release(dict);
}
static void
putprivs1(uint32_t id, int quotatype, struct quotause *qup)
putprivs1(uint32_t id, int quotaclass, struct quotause *qup)
{
struct dqblk dqblk;
int fd;
q2e2dqblk(&qup->q2e, &dqblk);
ufsqe2dqblk(qup->qe, &dqblk);
assert((qup->flags & DEFAULT) == 0);
if ((fd = open(qup->qfname, O_WRONLY)) < 0) {
@ -678,7 +693,7 @@ top:
*/
static int
writeprivs(struct quotause *quplist, int outfd, const char *name,
int quotatype)
int quotaclass)
{
struct quotause *qup;
FILE *fd;
@ -689,23 +704,24 @@ writeprivs(struct quotause *quplist, int outfd, const char *name,
if ((fd = fdopen(dup(outfd), "w")) == NULL)
errx(1, "fdopen `%s'", tmpfil);
if (dflag) {
fprintf(fd, "Default %s quotas:\n", qfextension[quotatype]);
fprintf(fd, "Default %s quotas:\n",
ufs_quota_class_names[quotaclass]);
} else {
fprintf(fd, "Quotas for %s %s:\n",
qfextension[quotatype], name);
ufs_quota_class_names[quotaclass], name);
}
for (qup = quplist; qup; qup = qup->next) {
struct quota2_val *q = qup->q2e.q2e_val;
struct ufs_quota_entry *q = qup->qe;
fprintf(fd, "%s (version %d):\n",
qup->fsname, (qup->flags & QUOTA2) ? 2 : 1);
if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) {
fprintf(fd, "\tblocks in use: %s, "
"limits (soft = %s, hard = %s",
intprt(b1, 21, q[QL_BLOCK].q2v_cur,
intprt(b1, 21, q[QL_BLK].ufsqe_cur,
HN_NOSPACE | HN_B, Hflag),
intprt(b2, 21, q[QL_BLOCK].q2v_softlimit,
intprt(b2, 21, q[QL_BLK].ufsqe_softlimit,
HN_NOSPACE | HN_B, Hflag),
intprt(b3, 21, q[QL_BLOCK].q2v_hardlimit,
intprt(b3, 21, q[QL_BLK].ufsqe_hardlimit,
HN_NOSPACE | HN_B, Hflag));
if (qup->flags & QUOTA2)
fprintf(fd, ", ");
@ -714,17 +730,17 @@ writeprivs(struct quotause *quplist, int outfd, const char *name,
if (qup->flags & (QUOTA2|DEFAULT)) {
fprintf(fd, "grace = %s",
timepprt(b0, 21, q[QL_BLOCK].q2v_grace, Hflag));
timepprt(b0, 21, q[QL_BLK].ufsqe_grace, Hflag));
}
fprintf(fd, ")\n");
if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) {
fprintf(fd, "\tinodes in use: %s, "
"limits (soft = %s, hard = %s",
intprt(b1, 21, q[QL_FILE].q2v_cur,
intprt(b1, 21, q[QL_FL].ufsqe_cur,
HN_NOSPACE, Hflag),
intprt(b2, 21, q[QL_FILE].q2v_softlimit,
intprt(b2, 21, q[QL_FL].ufsqe_softlimit,
HN_NOSPACE, Hflag),
intprt(b3, 21, q[QL_FILE].q2v_hardlimit,
intprt(b3, 21, q[QL_FL].ufsqe_hardlimit,
HN_NOSPACE, Hflag));
if (qup->flags & QUOTA2)
fprintf(fd, ", ");
@ -733,7 +749,7 @@ writeprivs(struct quotause *quplist, int outfd, const char *name,
if (qup->flags & (QUOTA2|DEFAULT)) {
fprintf(fd, "grace = %s",
timepprt(b0, 21, q[QL_FILE].q2v_grace, Hflag));
timepprt(b0, 21, q[QL_FL].ufsqe_grace, Hflag));
}
fprintf(fd, ")\n");
}
@ -913,21 +929,21 @@ readprivs(struct quotause *quplist, int infd)
}
}
for (qup = quplist; qup; qup = qup->next) {
struct quota2_val *q = qup->q2e.q2e_val;
struct ufs_quota_entry *q = qup->qe;
char b1[32], b2[32];
if (strcmp(fsp, qup->fsname))
continue;
if (version == 1 && dflag) {
q[QL_BLOCK].q2v_grace = graceb;
q[QL_FILE].q2v_grace = gracei;
q[QL_BLK].ufsqe_grace = graceb;
q[QL_FL].ufsqe_grace = gracei;
qup->flags |= FOUND;
continue;
}
if (strcmp(intprt(b1, 21, q[QL_BLOCK].q2v_cur,
if (strcmp(intprt(b1, 21, q[QL_BLK].ufsqe_cur,
HN_NOSPACE | HN_B, Hflag),
scurb) != 0 ||
strcmp(intprt(b2, 21, q[QL_FILE].q2v_cur,
strcmp(intprt(b2, 21, q[QL_FL].ufsqe_cur,
HN_NOSPACE, Hflag),
scuri) != 0) {
warnx("%s: cannot change current allocation",
@ -940,24 +956,24 @@ readprivs(struct quotause *quplist, int infd)
* or were under it, but now have a soft limit
* and are over it.
*/
if (q[QL_BLOCK].q2v_cur &&
q[QL_BLOCK].q2v_cur >= softb &&
(q[QL_BLOCK].q2v_softlimit == 0 ||
q[QL_BLOCK].q2v_cur < q[QL_BLOCK].q2v_softlimit))
q[QL_BLOCK].q2v_time = 0;
if (q[QL_FILE].q2v_cur &&
q[QL_FILE].q2v_cur >= softi &&
(q[QL_FILE].q2v_softlimit == 0 ||
q[QL_FILE].q2v_cur < q[QL_FILE].q2v_softlimit))
q[QL_FILE].q2v_time = 0;
q[QL_BLOCK].q2v_softlimit = softb;
q[QL_BLOCK].q2v_hardlimit = hardb;
if (q[QL_BLK].ufsqe_cur &&
q[QL_BLK].ufsqe_cur >= softb &&
(q[QL_BLK].ufsqe_softlimit == 0 ||
q[QL_BLK].ufsqe_cur < q[QL_BLK].ufsqe_softlimit))
q[QL_BLK].ufsqe_time = 0;
if (q[QL_FL].ufsqe_cur &&
q[QL_FL].ufsqe_cur >= softi &&
(q[QL_FL].ufsqe_softlimit == 0 ||
q[QL_FL].ufsqe_cur < q[QL_FL].ufsqe_softlimit))
q[QL_FL].ufsqe_time = 0;
q[QL_BLK].ufsqe_softlimit = softb;
q[QL_BLK].ufsqe_hardlimit = hardb;
if (version == 2)
q[QL_BLOCK].q2v_grace = graceb;
q[QL_FILE].q2v_softlimit = softi;
q[QL_FILE].q2v_hardlimit = hardi;
q[QL_BLK].ufsqe_grace = graceb;
q[QL_FL].ufsqe_softlimit = softi;
q[QL_FL].ufsqe_hardlimit = hardi;
if (version == 2)
q[QL_FILE].q2v_grace = gracei;
q[QL_FL].ufsqe_grace = gracei;
qup->flags |= FOUND;
}
}
@ -967,17 +983,17 @@ out:
* Disable quotas for any filesystems that have not been found.
*/
for (qup = quplist; qup; qup = qup->next) {
struct quota2_val *q = qup->q2e.q2e_val;
struct ufs_quota_entry *q = qup->qe;
if (qup->flags & FOUND) {
qup->flags &= ~FOUND;
continue;
}
q[QL_BLOCK].q2v_softlimit = UQUAD_MAX;
q[QL_BLOCK].q2v_hardlimit = UQUAD_MAX;
q[QL_BLOCK].q2v_grace = 0;
q[QL_FILE].q2v_softlimit = UQUAD_MAX;
q[QL_FILE].q2v_hardlimit = UQUAD_MAX;
q[QL_FILE].q2v_grace = 0;
q[QL_BLK].ufsqe_softlimit = UQUAD_MAX;
q[QL_BLK].ufsqe_hardlimit = UQUAD_MAX;
q[QL_BLK].ufsqe_grace = 0;
q[QL_FL].ufsqe_softlimit = UQUAD_MAX;
q[QL_FL].ufsqe_hardlimit = UQUAD_MAX;
q[QL_FL].ufsqe_grace = 0;
}
return 1;
}
@ -1007,7 +1023,7 @@ freeprivs(struct quotause *quplist)
}
static void
clearpriv(int argc, char **argv, const char *filesys, int quotatype)
clearpriv(int argc, char **argv, const char *filesys, int quotaclass)
{
prop_array_t cmds, datas;
prop_dictionary_t protodict, dict, data, cmd;
@ -1019,7 +1035,7 @@ clearpriv(int argc, char **argv, const char *filesys, int quotatype)
int id;
/* build a generic command */
protodict = quota2_prop_create();
protodict = quota_prop_create();
cmds = prop_array_create();
datas = prop_array_create();
if (protodict == NULL || cmds == NULL || datas == NULL) {
@ -1027,7 +1043,7 @@ clearpriv(int argc, char **argv, const char *filesys, int quotatype)
}
for ( ; argc > 0; argc--, argv++) {
if ((id = getentry(*argv, quotatype)) == -1)
if ((id = getentry(*argv, quotaclass)) == -1)
continue;
data = prop_dictionary_create();
if (data == NULL)
@ -1039,8 +1055,8 @@ clearpriv(int argc, char **argv, const char *filesys, int quotatype)
if (!prop_array_add_and_rel(datas, data))
err(1, "prop_array_add(data)");
}
if (!quota2_prop_add_command(cmds, "clear", qfextension[quotatype],
datas))
if (!quota_prop_add_command(cmds, "clear",
ufs_quota_class_names[quotaclass], datas))
err(1, "prop_add_command");
if (!prop_dictionary_set(protodict, "commands", cmds))
@ -1077,8 +1093,8 @@ clearpriv(int argc, char **argv, const char *filesys, int quotatype)
fst[i].f_mntonname,
prop_dictionary_externalize(dict));
}
if ((errno = quota2_get_cmds(dict, &cmds)) != 0) {
err(1, "quota2_get_cmds");
if ((errno = quota_get_cmds(dict, &cmds)) != 0) {
err(1, "quota_get_cmds");
}
/* only one command, no need to iter */
cmd = prop_array_get(cmds, 0);
@ -1090,7 +1106,8 @@ clearpriv(int argc, char **argv, const char *filesys, int quotatype)
if (error8) {
errno = error8;
warn("clear %s quota entries on %s",
qfextension[quotatype], fst[i].f_mntonname);
ufs_quota_class_names[quotaclass],
fst[i].f_mntonname);
}
prop_object_release(dict);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: quotactl.c,v 1.2 2011/03/06 17:08:43 bouyer Exp $ */
/* $NetBSD: quotactl.c,v 1.3 2011/03/24 17:05:47 bouyer Exp $ */
/*-
* Copyright (c) 2011 Manuel Bouyer
* All rights reserved.
@ -29,7 +29,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: quotactl.c,v 1.2 2011/03/06 17:08:43 bouyer Exp $");
__RCSID("$NetBSD: quotactl.c,v 1.3 2011/03/24 17:05:47 bouyer Exp $");
#endif /* not lint */
/*
@ -48,7 +48,7 @@ __RCSID("$NetBSD: quotactl.c,v 1.2 2011/03/06 17:08:43 bouyer Exp $");
#include <string.h>
#include <unistd.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
void usage(void);
@ -146,7 +146,7 @@ main(int argc, char * const argv[])
exit(0);
}
/* parse the reply, looking for errors */
if ((error = quota2_get_cmds(qdict, &cmds)) != 0) {
if ((error = quota_get_cmds(qdict, &cmds)) != 0) {
errx(1, "error parsing reply from kernel: %s\n",
strerror(error));
}

View File

@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
# $NetBSD: Makefile,v 1.7 2011/03/06 23:24:33 christos Exp $
# $NetBSD: Makefile,v 1.8 2011/03/24 17:05:47 bouyer Exp $
.include <bsd.own.mk>
WARNS ?= 4
@ -13,12 +13,9 @@ LINKS= ${BINDIR}/quotaon ${BINDIR}/quotaoff
.PATH: ${NETBSDSRCDIR}/usr.bin/quota
SRCS+= quotautil.c
CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/quota
CPPFLAGS+=-I${NETBSDSRCDIR}/sys
DPADD= ${LIBPROP}
LDADD= -lprop
.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs
SRCS+= quota2_prop.c
DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
LDADD= -lquota -lprop -lrpcsvc
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: quotaon.c,v 1.25 2011/03/06 23:24:33 christos Exp $ */
/* $NetBSD: quotaon.c,v 1.26 2011/03/24 17:05:47 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
#if 0
static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: quotaon.c,v 1.25 2011/03/06 23:24:33 christos Exp $");
__RCSID("$NetBSD: quotaon.c,v 1.26 2011/03/24 17:05:47 bouyer Exp $");
#endif
#endif /* not lint */
@ -53,7 +53,7 @@ __RCSID("$NetBSD: quotaon.c,v 1.25 2011/03/06 23:24:33 christos Exp $");
#include <sys/file.h>
#include <sys/mount.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
#include <ufs/ufs/quota1.h>
#include <sys/quota.h>
@ -167,7 +167,7 @@ quotaonoff( struct fstab *fs, int offmode, int type, const char *qfpathname)
struct plistref pref;
int8_t error8;
dict = quota2_prop_create();
dict = quota_prop_create();
cmds = prop_array_create();
datas = prop_array_create();
@ -178,7 +178,7 @@ quotaonoff( struct fstab *fs, int offmode, int type, const char *qfpathname)
errx(1, "can't allocate proplist");
if (offmode) {
if (!quota2_prop_add_command(cmds, "quotaoff",
if (!quota_prop_add_command(cmds, "quotaoff",
qfextension[type], datas))
err(1, "prop_add_command");
} else {
@ -190,7 +190,7 @@ quotaonoff( struct fstab *fs, int offmode, int type, const char *qfpathname)
err(1, "prop_dictionary_set(quotafile)");
if (!prop_array_add_and_rel(datas, data))
err(1, "prop_array_add(data)");
if (!quota2_prop_add_command(cmds, "quotaon",
if (!quota_prop_add_command(cmds, "quotaon",
qfextension[type], datas))
err(1, "prop_add_command");
}
@ -209,8 +209,8 @@ quotaonoff( struct fstab *fs, int offmode, int type, const char *qfpathname)
if ((errno = prop_dictionary_recv_syscall(&pref, &dict)) != 0)
err(1, "prop_dictionary_recv_syscall");
if ((errno = quota2_get_cmds(dict, &cmds)) != 0)
err(1, "quota2_get_cmds");
if ((errno = quota_get_cmds(dict, &cmds)) != 0)
err(1, "quota_get_cmds");
/* only one command, no need to iter */
cmd = prop_array_get(cmds, 0);

View File

@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
# $NetBSD: Makefile,v 1.7 2011/03/06 22:33:55 christos Exp $
# $NetBSD: Makefile,v 1.8 2011/03/24 17:05:47 bouyer Exp $
WARNS ?= 4
.include <bsd.own.mk>
@ -8,12 +8,12 @@ SRCS= repquota.c
MAN= repquota.8
CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
DPADD= ${LIBPROP}
LDADD= -lprop
DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
LDADD= -lquota -lprop -lrpcsvc
.PATH: ${NETBSDSRCDIR}/usr.bin/quota
SRCS+= printquota.c quotautil.c
.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs
SRCS+= quota2_prop.c quota2_subr.c quota1_subr.c
SRCS+= quota1_subr.c
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: repquota.c,v 1.29 2011/03/07 11:56:31 bouyer Exp $ */
/* $NetBSD: repquota.c,v 1.30 2011/03/24 17:05:47 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
#if 0
static char sccsid[] = "@(#)repquota.c 8.2 (Berkeley) 11/22/94";
#else
__RCSID("$NetBSD: repquota.c,v 1.29 2011/03/07 11:56:31 bouyer Exp $");
__RCSID("$NetBSD: repquota.c,v 1.30 2011/03/24 17:05:47 bouyer Exp $");
#endif
#endif /* not lint */
@ -53,8 +53,6 @@ __RCSID("$NetBSD: repquota.c,v 1.29 2011/03/07 11:56:31 bouyer Exp $");
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/statvfs.h>
#include <prop/proplib.h>
#include <sys/quota.h>
#include <errno.h>
#include <err.h>
@ -66,24 +64,26 @@ __RCSID("$NetBSD: repquota.c,v 1.29 2011/03/07 11:56:31 bouyer Exp $");
#include <string.h>
#include <unistd.h>
#include <ufs/ufs/quota2_prop.h>
#include <quota/quotaprop.h>
#include <quota/quota.h>
#include <ufs/ufs/quota1.h>
#include <sys/quota.h>
#include "printquota.h"
#include "quotautil.h"
struct fileusage {
struct fileusage *fu_next;
struct quota2_entry fu_q2e;
struct ufs_quota_entry fu_qe[QUOTA_NLIMITS];
uint32_t fu_id;
char fu_name[1];
/* actually bigger */
};
#define FUHASH 1024 /* must be power of two */
static struct fileusage *fuhead[MAXQUOTAS][FUHASH];
static uint32_t highid[MAXQUOTAS]; /* highest addid()'ed identifier per type */
int valid[MAXQUOTAS];
static struct quota2_entry defaultq2e[MAXQUOTAS];
static struct fileusage *fuhead[QUOTA_NCLASS][FUHASH];
static uint32_t highid[QUOTA_NCLASS]; /* highest addid()'ed identifier per class */
int valid[QUOTA_NCLASS];
static struct ufs_quota_entry defaultqe[QUOTA_NCLASS][QUOTA_NLIMITS];
static int vflag = 0; /* verbose */
static int aflag = 0; /* all file systems */
@ -158,18 +158,18 @@ main(int argc, char **argv)
continue;
if (aflag) {
if (gflag)
errs += repquota(&fst[i], GRPQUOTA);
errs += repquota(&fst[i], QUOTA_CLASS_GROUP);
if (uflag)
errs += repquota(&fst[i], USRQUOTA);
errs += repquota(&fst[i], QUOTA_CLASS_USER);
continue;
}
if ((argnum = oneof(fst[i].f_mntonname, argv, argc)) >= 0 ||
(argnum = oneof(fst[i].f_mntfromname, argv, argc)) >= 0) {
done |= 1U << argnum;
if (gflag)
errs += repquota(&fst[i], GRPQUOTA);
errs += repquota(&fst[i], QUOTA_CLASS_GROUP);
if (uflag)
errs += repquota(&fst[i], USRQUOTA);
errs += repquota(&fst[i], QUOTA_CLASS_USER);
}
}
if (xflag)
@ -191,36 +191,38 @@ usage(void)
}
static int
repquota(const struct statvfs *vfs, int type)
repquota(const struct statvfs *vfs, int class)
{
if (repquota2(vfs, type) != 0)
return repquota1(vfs, type);
if (repquota2(vfs, class) != 0)
return repquota1(vfs, class);
return 0;
}
static int
repquota2(const struct statvfs *vfs, int type)
repquota2(const struct statvfs *vfs, int class)
{
prop_dictionary_t dict, data, cmd;
prop_array_t cmds, datas;
struct plistref pref;
int8_t error8, version = 0;
prop_object_iterator_t cmditer, dataiter;
struct quota2_entry *q2ep;
struct ufs_quota_entry *qep;
struct fileusage *fup;
const char *strid;
uint32_t id;
uint64_t *values[QUOTA_NLIMITS];
dict = quota2_prop_create();
dict = quota_prop_create();
cmds = prop_array_create();
datas = prop_array_create();
if (dict == NULL || cmds == NULL || datas == NULL)
errx(1, "can't allocate proplist");
if (!quota2_prop_add_command(cmds, "getall", qfextension[type], datas))
if (!quota_prop_add_command(cmds, "getall",
ufs_quota_class_names[class], datas))
err(1, "prop_add_command");
if (!quota2_prop_add_command(cmds, "get version", qfextension[type],
prop_array_create()))
if (!quota_prop_add_command(cmds, "get version",
ufs_quota_class_names[class], prop_array_create()))
err(1, "prop_add_command");
if (!prop_dictionary_set(dict, "commands", cmds))
err(1, "prop_dictionary_set(command)");
@ -240,8 +242,8 @@ repquota2(const struct statvfs *vfs, int type)
if (Dflag)
printf("reply from kernel:\n%s\n",
prop_dictionary_externalize(dict));
if ((errno = quota2_get_cmds(dict, &cmds)) != 0) {
err(1, "quota2_get_cmds");
if ((errno = quota_get_cmds(dict, &cmds)) != 0) {
err(1, "quota_get_cmds");
}
cmditer = prop_array_iterator(cmds);
if (cmditer == NULL)
@ -260,7 +262,8 @@ repquota2(const struct statvfs *vfs, int type)
prop_object_release(dict);
if (error8 != EOPNOTSUPP) {
errno = error8;
warn("get %s quotas", qfextension[type]);
warn("get %s quotas",
ufs_quota_class_names[class]);
}
return error8;
}
@ -281,7 +284,7 @@ repquota2(const struct statvfs *vfs, int type)
if (dataiter == NULL)
err(1, "prop_array_iterator");
valid[type] = 1;
valid[class] = 1;
while ((data = prop_object_iterator_next(dataiter)) != NULL) {
strid = NULL;
if (!prop_dictionary_get_uint32(data, "id", &id)) {
@ -293,29 +296,34 @@ repquota2(const struct statvfs *vfs, int type)
"wrong id string %s in quota entry",
strid);
}
q2ep = &defaultq2e[type];
qep = defaultqe[class];
} else {
if ((fup = lookup(id, type)) == 0)
fup = addid(id, type, (char *)0);
q2ep = &fup->fu_q2e;
q2ep->q2e_uid = id;
if ((fup = lookup(id, class)) == 0)
fup = addid(id, class, (char *)0);
qep = fup->fu_qe;
}
values[QUOTA_LIMIT_BLOCK] =
&qep[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
values[QUOTA_LIMIT_FILE] =
&qep[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
errno = quota2_dict_get_q2e_usage(data, q2ep);
errno = proptoquota64(data, values,
ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (errno)
err(1, "quota2_dict_get_q2e_usage");
err(1, "proptoquota64");
}
prop_object_iterator_release(dataiter);
}
prop_object_iterator_release(cmditer);
prop_object_release(dict);
if (xflag == 0)
printquotas(type, vfs, version);
printquotas(class, vfs, version);
return 0;
}
static int
repquota1(const struct statvfs *vfs, int type)
repquota1(const struct statvfs *vfs, int class)
{
char qfpathname[MAXPATHLEN];
struct fstab *fs;
@ -324,6 +332,7 @@ repquota1(const struct statvfs *vfs, int type)
uint32_t id;
struct dqblk dqbuf;
time_t bgrace = MAX_DQ_TIME, igrace = MAX_DQ_TIME;
int type = ufsclass2qtype(class);
setfsent();
while ((fs = getfsent()) != NULL) {
@ -357,59 +366,59 @@ repquota1(const struct statvfs *vfs, int type)
dqbuf.dqb_bsoftlimit == 0 && dqbuf.dqb_bhardlimit == 0 &&
dqbuf.dqb_isoftlimit == 0 && dqbuf.dqb_ihardlimit == 0)
continue;
if ((fup = lookup(id, type)) == 0)
fup = addid(id, type, (char *)0);
dqblk2q2e(&dqbuf, &fup->fu_q2e);
fup->fu_q2e.q2e_val[QL_BLOCK].q2v_grace = bgrace;
fup->fu_q2e.q2e_val[QL_FILE].q2v_grace = igrace;
if ((fup = lookup(id, class)) == 0)
fup = addid(id, class, (char *)0);
dqblk2ufsqe(&dqbuf, fup->fu_qe);
fup->fu_qe[QUOTA_LIMIT_BLOCK].ufsqe_grace = bgrace;
fup->fu_qe[QUOTA_LIMIT_FILE].ufsqe_grace = igrace;
}
defaultq2e[type].q2e_val[QL_BLOCK].q2v_grace = bgrace;
defaultq2e[type].q2e_val[QL_FILE].q2v_grace = igrace;
defaultq2e[type].q2e_val[QL_BLOCK].q2v_softlimit =
defaultq2e[type].q2e_val[QL_BLOCK].q2v_hardlimit =
defaultq2e[type].q2e_val[QL_FILE].q2v_softlimit =
defaultq2e[type].q2e_val[QL_FILE].q2v_hardlimit = UQUAD_MAX;
defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_grace = bgrace;
defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_grace = igrace;
defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_softlimit =
defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_hardlimit =
defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_softlimit =
defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_hardlimit = UQUAD_MAX;
fclose(qf);
valid[type] = 1;
valid[class] = 1;
if (xflag == 0)
printquotas(type, vfs, 1);
printquotas(class, vfs, 1);
return 0;
}
static void
printquotas(int type, const struct statvfs *vfs, int version)
printquotas(int class, const struct statvfs *vfs, int version)
{
static int multiple = 0;
uint32_t id;
int i;
struct fileusage *fup;
struct quota2_val *q;
const char *timemsg[N_QL];
char overchar[N_QL];
struct ufs_quota_entry *q;
const char *timemsg[QUOTA_NLIMITS];
char overchar[QUOTA_NLIMITS];
time_t now;
char b0[2][20], b1[20], b2[20], b3[20];
switch(type) {
case GRPQUOTA:
switch(class) {
case QUOTA_CLASS_GROUP:
{
struct group *gr;
setgrent();
while ((gr = getgrent()) != 0)
(void)addid(gr->gr_gid, GRPQUOTA, gr->gr_name);
(void)addid(gr->gr_gid, QUOTA_CLASS_GROUP, gr->gr_name);
endgrent();
break;
}
case USRQUOTA:
case QUOTA_CLASS_USER:
{
struct passwd *pw;
setpwent();
while ((pw = getpwent()) != 0)
(void)addid(pw->pw_uid, USRQUOTA, pw->pw_name);
(void)addid(pw->pw_uid, QUOTA_CLASS_USER, pw->pw_name);
endpwent();
break;
}
default:
errx(1, "unknown quota type %d", type);
errx(1, "unknown quota class %d", class);
}
time(&now);
@ -418,54 +427,62 @@ printquotas(int type, const struct statvfs *vfs, int version)
printf("\n");
if (vflag)
printf("*** Report for %s quotas on %s (%s, version %d)\n",
qfextension[type], vfs->f_mntonname, vfs->f_mntfromname,
version);
ufs_quota_class_names[class], vfs->f_mntonname,
vfs->f_mntfromname, version);
printf(" Block limits "
"File limits\n");
printf(type == USRQUOTA ? "User " : "Group");
printf(class == QUOTA_CLASS_USER ? "User " : "Group");
printf(" used soft hard grace used"
"soft hard grace\n");
for (id = 0; id <= highid[type]; id++) {
fup = qremove(id, type);
q = fup->fu_q2e.q2e_val;
for (id = 0; id <= highid[class]; id++) {
fup = qremove(id, class);
q = fup->fu_qe;
if (fup == 0)
continue;
for (i = 0; i < N_QL; i++) {
switch (QL_STATUS(quota2_check_limit(&q[i], 1, now))) {
for (i = 0; i < QUOTA_NLIMITS; i++) {
switch (QL_STATUS(quota_check_limit(q[i].ufsqe_cur, 1,
q[i].ufsqe_softlimit, q[i].ufsqe_hardlimit,
q[i].ufsqe_time, now))) {
case QL_S_DENY_HARD:
case QL_S_DENY_GRACE:
case QL_S_ALLOW_SOFT:
timemsg[i] = timeprt(b0[i], 8, now,
q[i].q2v_time);
q[i].ufsqe_time);
overchar[i] = '+';
break;
default:
timemsg[i] = (vflag && version == 2) ?
timeprt(b0[i], 8, 0, q[i].q2v_grace) : "";
timeprt(b0[i], 8, 0, q[i].ufsqe_grace) : "";
overchar[i] = '-';
break;
}
}
if (q[QL_BLOCK].q2v_cur == 0 &&
q[QL_FILE].q2v_cur == 0 && vflag == 0 &&
overchar[QL_BLOCK] == '-' && overchar[QL_FILE] == '-')
if (q[QUOTA_LIMIT_BLOCK].ufsqe_cur == 0 &&
q[QUOTA_LIMIT_FILE].ufsqe_cur == 0 && vflag == 0 &&
overchar[QUOTA_LIMIT_BLOCK] == '-' &&
overchar[QUOTA_LIMIT_FILE] == '-')
continue;
if (strlen(fup->fu_name) > 9)
printf("%s ", fup->fu_name);
else
printf("%-10s", fup->fu_name);
printf("%c%c%9s%9s%9s%7s",
overchar[QL_BLOCK], overchar[QL_FILE],
intprt(b1, 10, q[QL_BLOCK].q2v_cur, HN_B, hflag),
intprt(b2, 10, q[QL_BLOCK].q2v_softlimit, HN_B, hflag),
intprt(b3, 10, q[QL_BLOCK].q2v_hardlimit, HN_B, hflag),
timemsg[QL_BLOCK]);
overchar[QUOTA_LIMIT_BLOCK], overchar[QUOTA_LIMIT_FILE],
intprt(b1, 10, q[QUOTA_LIMIT_BLOCK].ufsqe_cur,
HN_B, hflag),
intprt(b2, 10, q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
HN_B, hflag),
intprt(b3, 10, q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
HN_B, hflag),
timemsg[QUOTA_LIMIT_BLOCK]);
printf(" %8s%8s%8s%7s\n",
intprt(b1, 9, q[QL_FILE].q2v_cur, 0, hflag),
intprt(b2, 9, q[QL_FILE].q2v_softlimit, 0, hflag),
intprt(b3, 9, q[QL_FILE].q2v_hardlimit, 0, hflag),
timemsg[QL_FILE]);
intprt(b1, 9, q[QUOTA_LIMIT_FILE].ufsqe_cur, 0, hflag),
intprt(b2, 9, q[QUOTA_LIMIT_FILE].ufsqe_softlimit,
0, hflag),
intprt(b3, 9, q[QUOTA_LIMIT_FILE].ufsqe_hardlimit,
0, hflag),
timemsg[QUOTA_LIMIT_FILE]);
free(fup);
}
}
@ -477,9 +494,10 @@ exportquotas(void)
struct fileusage *fup;
prop_dictionary_t dict, data;
prop_array_t cmds, datas;
int type;
int class;
uint64_t *valuesp[QUOTA_NLIMITS];
dict = quota2_prop_create();
dict = quota_prop_create();
cmds = prop_array_create();
if (dict == NULL || cmds == NULL) {
@ -487,33 +505,44 @@ exportquotas(void)
}
for (type = 0; type < MAXQUOTAS; type++) {
if (valid[type] == 0)
for (class = 0; class < QUOTA_NCLASS; class++) {
if (valid[class] == 0)
continue;
datas = prop_array_create();
if (datas == NULL)
errx(1, "can't allocate proplist");
data = q2etoprop(&defaultq2e[type], 1);
valuesp[QUOTA_LIMIT_BLOCK] =
&defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
valuesp[QUOTA_LIMIT_FILE] =
&defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_hardlimit;
data = quota64toprop(0, 1, valuesp,
ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (data == NULL)
err(1, "q2etoprop(default)");
err(1, "quota64toprop(default)");
if (!prop_array_add_and_rel(datas, data))
err(1, "prop_array_add(data)");
for (id = 0; id <= highid[type]; id++) {
fup = qremove(id, type);
for (id = 0; id <= highid[class]; id++) {
fup = qremove(id, class);
if (fup == 0)
continue;
fup->fu_q2e.q2e_uid = id;
data = q2etoprop(&fup->fu_q2e, 0);
valuesp[QUOTA_LIMIT_BLOCK] =
&fup->fu_qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
valuesp[QUOTA_LIMIT_FILE] =
&fup->fu_qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
data = quota64toprop(id, 0, valuesp,
ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
ufs_quota_limit_names, QUOTA_NLIMITS);
if (data == NULL)
err(1, "q2etoprop(default)");
err(1, "quota64toprop(id)");
if (!prop_array_add_and_rel(datas, data))
err(1, "prop_array_add(data)");
free(fup);
}
if (!quota2_prop_add_command(cmds, "set",
qfextension[type], datas))
if (!quota_prop_add_command(cmds, "set",
ufs_quota_class_names[class], datas))
err(1, "prop_add_command");
}
@ -527,27 +556,27 @@ exportquotas(void)
/*
* Routines to manage the file usage table.
*
* Lookup an id of a specific type.
* Lookup an id of a specific class.
*/
struct fileusage *
lookup(uint32_t id, int type)
lookup(uint32_t id, int class)
{
struct fileusage *fup;
for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
for (fup = fuhead[class][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
if (fup->fu_id == id)
return fup;
return NULL;
}
/*
* Lookup and remove an id of a specific type.
* Lookup and remove an id of a specific class.
*/
static struct fileusage *
qremove(uint32_t id, int type)
qremove(uint32_t id, int class)
{
struct fileusage *fup, **fupp;
for (fupp = &fuhead[type][id & (FUHASH-1)]; *fupp != 0;) {
for (fupp = &fuhead[class][id & (FUHASH-1)]; *fupp != 0;) {
fup = *fupp;
if (fup->fu_id == id) {
*fupp = fup->fu_next;
@ -562,31 +591,31 @@ qremove(uint32_t id, int type)
* Add a new file usage id if it does not already exist.
*/
static struct fileusage *
addid(uint32_t id, int type, const char *name)
addid(uint32_t id, int class, const char *name)
{
struct fileusage *fup, **fhp;
struct group *gr = NULL;
struct passwd *pw = NULL;
size_t len;
if ((fup = lookup(id, type)) != NULL) {
if ((fup = lookup(id, class)) != NULL) {
return fup;
}
if (name == NULL) {
switch(type) {
case GRPQUOTA:
switch(class) {
case QUOTA_CLASS_GROUP:
gr = getgrgid(id);
if (gr != NULL)
name = gr->gr_name;
break;
case USRQUOTA:
case QUOTA_CLASS_USER:
pw = getpwuid(id);
if (pw)
name = pw->pw_name;
break;
default:
errx(1, "unknown quota type %d\n", type);
errx(1, "unknown quota class %d\n", class);
}
}
@ -596,17 +625,18 @@ addid(uint32_t id, int type, const char *name)
len = 10;
if ((fup = calloc(1, sizeof(*fup) + len)) == NULL)
err(1, "out of memory for fileusage structures");
fhp = &fuhead[type][id & (FUHASH - 1)];
fhp = &fuhead[class][id & (FUHASH - 1)];
fup->fu_next = *fhp;
*fhp = fup;
fup->fu_id = id;
if (id > highid[type])
highid[type] = id;
if (id > highid[class])
highid[class] = id;
if (name) {
memmove(fup->fu_name, name, len + 1);
} else {
snprintf(fup->fu_name, len + 1, "%u", id);
}
fup->fu_q2e = defaultq2e[type];
fup->fu_qe[QUOTA_LIMIT_BLOCK] = defaultqe[class][QUOTA_LIMIT_BLOCK];
fup->fu_qe[QUOTA_LIMIT_FILE] = defaultqe[class][QUOTA_LIMIT_FILE];
return fup;
}