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:
parent
c37993815d
commit
d9210c2405
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
6
common/include/quota/Makefile
Normal file
6
common/include/quota/Makefile
Normal 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>
|
61
common/include/quota/quota.h
Normal file
61
common/include/quota/quota.h
Normal 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 */
|
83
common/include/quota/quotaprop.h
Normal file
83
common/include/quota/quotaprop.h
Normal 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 */
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
4
common/lib/libquota/Makefile.inc
Normal file
4
common/lib/libquota/Makefile.inc
Normal 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
|
@ -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;
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
17
lib/libquota/Makefile
Normal 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
67
lib/libquota/getfsquota.c
Normal 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
209
lib/libquota/getnfsquota.c
Normal 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
180
lib/libquota/getufsquota.c
Normal 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;
|
||||
}
|
5
lib/libquota/shlib_version
Normal file
5
lib/libquota/shlib_version
Normal 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
|
@ -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>
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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[];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user