From d9210c2405d8caa2f8d10c6e40446d0d400e93db Mon Sep 17 00:00:00 2001 From: bouyer Date: Thu, 24 Mar 2011 17:05:39 +0000 Subject: [PATCH] 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 ...) --- common/include/prop/prop_array.h | 4 +- common/include/prop/prop_dictionary.h | 8 +- common/include/quota/Makefile | 6 + common/include/quota/quota.h | 61 ++++ common/include/quota/quotaprop.h | 83 +++++ common/lib/libprop/prop_array_util.3 | 15 +- common/lib/libprop/prop_array_util.c | 13 +- common/lib/libprop/prop_dictionary_util.3 | 19 +- common/lib/libprop/prop_dictionary_util.c | 26 +- common/lib/libquota/Makefile.inc | 4 + .../lib/libquota/quotaprop.c | 183 ++++------- .../lib/libquota/quotasubr.c | 43 +-- distrib/sets/lists/base/ad.mips64eb | 6 +- distrib/sets/lists/base/ad.mips64el | 6 +- distrib/sets/lists/base/md.amd64 | 4 +- distrib/sets/lists/base/md.sparc64 | 4 +- distrib/sets/lists/base/mi | 3 +- distrib/sets/lists/base/shl.mi | 5 +- distrib/sets/lists/comp/ad.mips64eb | 12 +- distrib/sets/lists/comp/ad.mips64el | 12 +- distrib/sets/lists/comp/md.amd64 | 8 +- distrib/sets/lists/comp/md.sparc64 | 7 +- distrib/sets/lists/comp/mi | 8 +- distrib/sets/lists/comp/shl.mi | 4 +- etc/mtree/NetBSD.dist.base | 3 +- include/Makefile | 3 +- lib/Makefile | 3 +- lib/libquota/Makefile | 17 ++ lib/libquota/getfsquota.c | 67 +++++ lib/libquota/getnfsquota.c | 209 +++++++++++++ lib/libquota/getufsquota.c | 180 +++++++++++ lib/libquota/shlib_version | 5 + libexec/rpc.rquotad/Makefile | 13 +- libexec/rpc.rquotad/rquotad.c | 51 ++-- share/mk/bsd.README | 3 +- share/mk/bsd.hostprog.mk | 3 +- sys/compat/common/vfs_syscalls_50.c | 61 ++-- sys/lib/libkern/Makefile.libkern | 3 +- sys/rump/librump/rumpvfs/Makefile.rumpvfs | 4 +- sys/sys/quota.h | 20 +- sys/ufs/files.ufs | 3 +- sys/ufs/ufs/quota.h | 41 ++- sys/ufs/ufs/quota1.h | 16 +- sys/ufs/ufs/quota1_subr.c | 43 +-- sys/ufs/ufs/quota2.h | 42 ++- sys/ufs/ufs/quota2_subr.c | 22 +- sys/ufs/ufs/ufs_quota.c | 12 +- sys/ufs/ufs/ufs_quota1.c | 90 ++++-- sys/ufs/ufs/ufs_quota2.c | 75 ++++- sys/ufs/ufs/ufs_vfsops.c | 8 +- usr.bin/quota/Makefile | 12 +- usr.bin/quota/getvfsquota.c | 38 ++- usr.bin/quota/getvfsquota.h | 6 +- usr.bin/quota/printquota.c | 17 +- usr.bin/quota/printquota.h | 3 +- usr.bin/quota/quota.c | 225 +++----------- usr.bin/quota/quotautil.c | 23 +- usr.bin/quota/quotautil.h | 3 +- usr.sbin/edquota/Makefile | 8 +- usr.sbin/edquota/edquota.c | 283 ++++++++++-------- usr.sbin/quotactl/quotactl.c | 8 +- usr.sbin/quotaon/Makefile | 9 +- usr.sbin/quotaon/quotaon.c | 16 +- usr.sbin/repquota/Makefile | 8 +- usr.sbin/repquota/repquota.c | 250 +++++++++------- 65 files changed, 1606 insertions(+), 844 deletions(-) create mode 100644 common/include/quota/Makefile create mode 100644 common/include/quota/quota.h create mode 100644 common/include/quota/quotaprop.h create mode 100644 common/lib/libquota/Makefile.inc rename sys/ufs/ufs/quota2_prop.c => common/lib/libquota/quotaprop.c (51%) rename sys/ufs/ufs/quota2_prop.h => common/lib/libquota/quotasubr.c (60%) create mode 100644 lib/libquota/Makefile create mode 100644 lib/libquota/getfsquota.c create mode 100644 lib/libquota/getnfsquota.c create mode 100644 lib/libquota/getufsquota.c create mode 100644 lib/libquota/shlib_version diff --git a/common/include/prop/prop_array.h b/common/include/prop/prop_array.h index 357021939196..b60d65f52c3b 100644 --- a/common/include/prop/prop_array.h +++ b/common/include/prop/prop_array.h @@ -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_ */ diff --git a/common/include/prop/prop_dictionary.h b/common/include/prop/prop_dictionary.h index 3b8672f63879..0779f75b131f 100644 --- a/common/include/prop/prop_dictionary.h +++ b/common/include/prop/prop_dictionary.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_ */ diff --git a/common/include/quota/Makefile b/common/include/quota/Makefile new file mode 100644 index 000000000000..921bcba30e6f --- /dev/null +++ b/common/include/quota/Makefile @@ -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 diff --git a/common/include/quota/quota.h b/common/include/quota/quota.h new file mode 100644 index 000000000000..e3f8066a2681 --- /dev/null +++ b/common/include/quota/quota.h @@ -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 +#include + +/* 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 */ diff --git a/common/include/quota/quotaprop.h b/common/include/quota/quotaprop.h new file mode 100644 index 000000000000..5e464542f44b --- /dev/null +++ b/common/include/quota/quotaprop.h @@ -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 +#include + +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 */ diff --git a/common/lib/libprop/prop_array_util.3 b/common/lib/libprop/prop_array_util.3 index 480489e67fcb..61e4c56f2b9c 100644 --- a/common/lib/libprop/prop_array_util.3 +++ b/common/lib/libprop/prop_array_util.3 @@ -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 diff --git a/common/lib/libprop/prop_array_util.c b/common/lib/libprop/prop_array_util.c index c7951cca04a1..8515bd5d3e2a 100644 --- a/common/lib/libprop/prop_array_util.c +++ b/common/lib/libprop/prop_array_util.c @@ -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; +} diff --git a/common/lib/libprop/prop_dictionary_util.3 b/common/lib/libprop/prop_dictionary_util.3 index 2eb76947b3b1..23d13f528827 100644 --- a/common/lib/libprop/prop_dictionary_util.3 +++ b/common/lib/libprop/prop_dictionary_util.3 @@ -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 diff --git a/common/lib/libprop/prop_dictionary_util.c b/common/lib/libprop/prop_dictionary_util.c index a26443e4bdcb..65baf73cc6c9 100644 --- a/common/lib/libprop/prop_dictionary_util.c +++ b/common/lib/libprop/prop_dictionary_util.c @@ -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 #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; +} diff --git a/common/lib/libquota/Makefile.inc b/common/lib/libquota/Makefile.inc new file mode 100644 index 000000000000..948811a983f7 --- /dev/null +++ b/common/lib/libquota/Makefile.inc @@ -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 diff --git a/sys/ufs/ufs/quota2_prop.c b/common/lib/libquota/quotaprop.c similarity index 51% rename from sys/ufs/ufs/quota2_prop.c rename to common/lib/libquota/quotaprop.c index 0d87dbf21481..03ba65af0c25 100644 --- a/sys/ufs/ufs/quota2_prop.c +++ b/common/lib/libquota/quotaprop.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 #include -#include - -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 +/* + * 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; + + 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; -err: - prop_object_release(dict1); - return NULL; } +/* + * 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; diff --git a/sys/ufs/ufs/quota2_prop.h b/common/lib/libquota/quotasubr.c similarity index 60% rename from sys/ufs/ufs/quota2_prop.h rename to common/lib/libquota/quotasubr.c index d13042d8bca1..e4108bd22e0c 100644 --- a/sys/ufs/ufs/quota2_prop.h +++ b/common/lib/libquota/quotasubr.c @@ -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 -#include +#include +#include +#include +#include -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 -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; +} diff --git a/distrib/sets/lists/base/ad.mips64eb b/distrib/sets/lists/base/ad.mips64eb index fee423fbb7c8..413b011874c2 100644 --- a/distrib/sets/lists/base/ad.mips64eb +++ b/distrib/sets/lists/base/ad.mips64eb @@ -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 diff --git a/distrib/sets/lists/base/ad.mips64el b/distrib/sets/lists/base/ad.mips64el index fc8a8e6ba703..d531d882b2df 100644 --- a/distrib/sets/lists/base/ad.mips64el +++ b/distrib/sets/lists/base/ad.mips64el @@ -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 diff --git a/distrib/sets/lists/base/md.amd64 b/distrib/sets/lists/base/md.amd64 index 574f51539b4e..b9c6961c256a 100644 --- a/distrib/sets/lists/base/md.amd64 +++ b/distrib/sets/lists/base/md.amd64 @@ -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 diff --git a/distrib/sets/lists/base/md.sparc64 b/distrib/sets/lists/base/md.sparc64 index 68aaec2a4703..16283d2865bd 100644 --- a/distrib/sets/lists/base/md.sparc64 +++ b/distrib/sets/lists/base/md.sparc64 @@ -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 diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi index 23d68f6abb1f..92051589527e 100644 --- a/distrib/sets/lists/base/mi +++ b/distrib/sets/lists/base/mi @@ -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 diff --git a/distrib/sets/lists/base/shl.mi b/distrib/sets/lists/base/shl.mi index 75a3e7147321..a55998949b0e 100644 --- a/distrib/sets/lists/base/shl.mi +++ b/distrib/sets/lists/base/shl.mi @@ -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 diff --git a/distrib/sets/lists/comp/ad.mips64eb b/distrib/sets/lists/comp/ad.mips64eb index 0e037da869b9..d0d6820d9a6e 100644 --- a/distrib/sets/lists/comp/ad.mips64eb +++ b/distrib/sets/lists/comp/ad.mips64eb @@ -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 diff --git a/distrib/sets/lists/comp/ad.mips64el b/distrib/sets/lists/comp/ad.mips64el index c08bafd83afc..47d15231c986 100644 --- a/distrib/sets/lists/comp/ad.mips64el +++ b/distrib/sets/lists/comp/ad.mips64el @@ -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 diff --git a/distrib/sets/lists/comp/md.amd64 b/distrib/sets/lists/comp/md.amd64 index 47112f2840e5..afc8ca2dee60 100644 --- a/distrib/sets/lists/comp/md.amd64 +++ b/distrib/sets/lists/comp/md.amd64 @@ -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 diff --git a/distrib/sets/lists/comp/md.sparc64 b/distrib/sets/lists/comp/md.sparc64 index 4ed66d907494..63def16b2515 100644 --- a/distrib/sets/lists/comp/md.sparc64 +++ b/distrib/sets/lists/comp/md.sparc64 @@ -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 diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index bb738747a88b..8170a349ccc3 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -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 diff --git a/distrib/sets/lists/comp/shl.mi b/distrib/sets/lists/comp/shl.mi index 659d71449897..f9a9220d3127 100644 --- a/distrib/sets/lists/comp/shl.mi +++ b/distrib/sets/lists/comp/shl.mi @@ -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 diff --git a/etc/mtree/NetBSD.dist.base b/etc/mtree/NetBSD.dist.base index 04ebf425128d..412dbbd1128b 100644 --- a/etc/mtree/NetBSD.dist.base +++ b/etc/mtree/NetBSD.dist.base @@ -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 diff --git a/include/Makefile b/include/Makefile index bb2f8ca6d41d..dd9ee69cab53 100644 --- a/include/Makefile +++ b/include/Makefile @@ -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 .include diff --git a/lib/Makefile b/lib/Makefile index 92445625a99d..7250dd8ab40a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -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 @@ -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 diff --git a/lib/libquota/Makefile b/lib/libquota/Makefile new file mode 100644 index 000000000000..c83c6bbf23d6 --- /dev/null +++ b/lib/libquota/Makefile @@ -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 + +.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 diff --git a/lib/libquota/getfsquota.c b/lib/libquota/getfsquota.c new file mode 100644 index 000000000000..3e4499eea4eb --- /dev/null +++ b/lib/libquota/getfsquota.c @@ -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 +__RCSID("$NetBSD: getfsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $"); + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* 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); + } +} diff --git a/lib/libquota/getnfsquota.c b/lib/libquota/getnfsquota.c new file mode 100644 index 000000000000..6bead0f57566 --- /dev/null +++ b/lib/libquota/getnfsquota.c @@ -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 +#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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +/* 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; +} diff --git a/lib/libquota/getufsquota.c b/lib/libquota/getufsquota.c new file mode 100644 index 000000000000..fba08c7b558b --- /dev/null +++ b/lib/libquota/getufsquota.c @@ -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 +__RCSID("$NetBSD: getufsquota.c,v 1.1 2011/03/24 17:05:43 bouyer Exp $"); + +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* 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; +} diff --git a/lib/libquota/shlib_version b/lib/libquota/shlib_version new file mode 100644 index 000000000000..dd347673670a --- /dev/null +++ b/lib/libquota/shlib_version @@ -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 diff --git a/libexec/rpc.rquotad/Makefile b/libexec/rpc.rquotad/Makefile index 96afe028da5f..11bcf3baab98 100644 --- a/libexec/rpc.rquotad/Makefile +++ b/libexec/rpc.rquotad/Makefile @@ -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 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 diff --git a/libexec/rpc.rquotad/rquotad.c b/libexec/rpc.rquotad/rquotad.c index 4be0f85a3026..7414d4f71173 100644 --- a/libexec/rpc.rquotad/rquotad.c +++ b/libexec/rpc.rquotad/rquotad.c @@ -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 #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 @@ -29,16 +29,12 @@ __RCSID("$NetBSD: rquotad.c,v 1.26 2011/03/12 12:30:39 bouyer Exp $"); #include -#include -#include +#include +#include #include #include #include -#include - -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)) diff --git a/share/mk/bsd.README b/share/mk/bsd.README index a2d88fc52462..821c9d34eb3e 100644 --- a/share/mk/bsd.README +++ b/share/mk/bsd.README @@ -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 diff --git a/share/mk/bsd.hostprog.mk b/share/mk/bsd.hostprog.mk index 1f13157e88b0..74a1b921d4d5 100644 --- a/share/mk/bsd.hostprog.mk +++ b/share/mk/bsd.hostprog.mk @@ -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 @@ -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 diff --git a/sys/compat/common/vfs_syscalls_50.c b/sys/compat/common/vfs_syscalls_50.c index a80db9655094..93190400421a 100644 --- a/sys/compat/common/vfs_syscalls_50.c +++ b/sys/compat/common/vfs_syscalls_50.c @@ -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 -__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 #include @@ -314,7 +314,7 @@ compat_50_sys_mknod(struct lwp *l, } #include -#include +#include /* 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) { diff --git a/sys/lib/libkern/Makefile.libkern b/sys/lib/libkern/Makefile.libkern index de46f00d5cdb..a76c5826f385 100644 --- a/sys/lib/libkern/Makefile.libkern +++ b/sys/lib/libkern/Makefile.libkern @@ -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 diff --git a/sys/rump/librump/rumpvfs/Makefile.rumpvfs b/sys/rump/librump/rumpvfs/Makefile.rumpvfs index f93432a6519b..385227d999d2 100644 --- a/sys/rump/librump/rumpvfs/Makefile.rumpvfs +++ b/sys/rump/librump/rumpvfs/Makefile.rumpvfs @@ -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. diff --git a/sys/sys/quota.h b/sys/sys/quota.h index 47560407b7a3..f3805e0f3593 100644 --- a/sys/sys/quota.h +++ b/sys/sys/quota.h @@ -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_ */ diff --git a/sys/ufs/files.ufs b/sys/ufs/files.ufs index a99a5aca9569..db186506eae8 100644 --- a/sys/ufs/files.ufs +++ b/sys/ufs/files.ufs @@ -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 diff --git a/sys/ufs/ufs/quota.h b/sys/ufs/ufs/quota.h index ec991e73bd72..5455169f371a 100644 --- a/sys/ufs/ufs/quota.h +++ b/sys/ufs/ufs/quota.h @@ -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 /* * 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 diff --git a/sys/ufs/ufs/quota1.h b/sys/ufs/ufs/quota1.h index 100f700d1f0c..6c522ba683c1 100644 --- a/sys/ufs/ufs/quota1.h +++ b/sys/ufs/ufs/quota1.h @@ -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_ */ diff --git a/sys/ufs/ufs/quota1_subr.c b/sys/ufs/ufs/quota1_subr.c index a06a7f268c58..c45e00f78414 100644 --- a/sys/ufs/ufs/quota1_subr.c +++ b/sys/ufs/ufs/quota1_subr.c @@ -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 -__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 #include -#include +#include #include 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; } + diff --git a/sys/ufs/ufs/quota2.h b/sys/ufs/ufs/quota2.h index 7e829471b424..65dde4e8eb9e 100644 --- a/sys/ufs/ufs/quota2.h +++ b/sys/ufs/ufs/quota2.h @@ -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 +#include /* 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_ */ diff --git a/sys/ufs/ufs/quota2_subr.c b/sys/ufs/ufs/quota2_subr.c index 7ed74e4700b0..9c2cfad65e54 100644 --- a/sys/ufs/ufs/quota2_subr.c +++ b/sys/ufs/ufs/quota2_subr.c @@ -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 -__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 #include @@ -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; -} diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 52c73492e110..78cef57e1607 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -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 -__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 #include #include -#include +#include 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; diff --git a/sys/ufs/ufs/ufs_quota1.c b/sys/ufs/ufs/ufs_quota1.c index f83af758f2b3..3303152df75d 100644 --- a/sys/ufs/ufs/ufs_quota1.c +++ b/sys/ufs/ufs/ufs_quota1.c @@ -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 -__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 #include @@ -47,7 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $" #include #include -#include +#include #include #include #include @@ -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_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 && diff --git a/sys/ufs/ufs/ufs_quota2.c b/sys/ufs/ufs/ufs_quota2.c index d8724427b533..b0bf589c1bba 100644 --- a/sys/ufs/ufs/ufs_quota2.c +++ b/sys/ufs/ufs/ufs_quota2.c @@ -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 -__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 #include @@ -51,7 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $" #include #include #include -#include +#include /* * 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; diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 134f5a9be70d..ac7230bcaaa2 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -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 -__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 #endif -#include +#include /* 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); diff --git a/usr.bin/quota/Makefile b/usr.bin/quota/Makefile index 0de21fe42895..0ef9a98b582e 100644 --- a/usr.bin/quota/Makefile +++ b/usr.bin/quota/Makefile @@ -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 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 diff --git a/usr.bin/quota/getvfsquota.c b/usr.bin/quota/getvfsquota.c index 2ca651554ae9..3ab43a6762a5 100644 --- a/usr.bin/quota/getvfsquota.c +++ b/usr.bin/quota/getvfsquota.c @@ -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 -__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 #include @@ -39,14 +39,14 @@ __RCSID("$NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $"); #include -#include +#include #include #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; } } diff --git a/usr.bin/quota/getvfsquota.h b/usr.bin/quota/getvfsquota.h index 93ccc6b85805..29960cfee3a0 100644 --- a/usr.bin/quota/getvfsquota.h +++ b/usr.bin/quota/getvfsquota.h @@ -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[]; diff --git a/usr.bin/quota/printquota.c b/usr.bin/quota/printquota.c index 660a6fcd8bd2..7b3c8eb985d5 100644 --- a/usr.bin/quota/printquota.c +++ b/usr.bin/quota/printquota.c @@ -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; +} diff --git a/usr.bin/quota/printquota.h b/usr.bin/quota/printquota.h index a1aaef9d6b49..364fa234433a 100644 --- a/usr.bin/quota/printquota.h +++ b/usr.bin/quota/printquota.h @@ -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 *); diff --git a/usr.bin/quota/quota.c b/usr.bin/quota/quota.c index 06f268aa19da..f2f2a5f7af26 100644 --- a/usr.bin/quota/quota.c +++ b/usr.bin/quota/quota.c @@ -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 #include -#include -#include - -#include -#include -#include +#include +#include #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; -} diff --git a/usr.bin/quota/quotautil.c b/usr.bin/quota/quotautil.c index 9e5d2edfce17..d2a6dcb67715 100644 --- a/usr.bin/quota/quotautil.c +++ b/usr.bin/quota/quotautil.c @@ -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 #include -#include +#include #include #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. */ diff --git a/usr.bin/quota/quotautil.h b/usr.bin/quota/quotautil.h index a5cd4a0f9bc5..6643ca6b3edf 100644 --- a/usr.bin/quota/quotautil.h +++ b/usr.bin/quota/quotautil.h @@ -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); diff --git a/usr.sbin/edquota/Makefile b/usr.sbin/edquota/Makefile index 719cce8ee5dd..3872de503b2c 100644 --- a/usr.sbin/edquota/Makefile +++ b/usr.sbin/edquota/Makefile @@ -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 @@ -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 diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index 28fe1aec0fba..db665036e117 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -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 #include -#include +#include +#include #include #include @@ -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); } diff --git a/usr.sbin/quotactl/quotactl.c b/usr.sbin/quotactl/quotactl.c index d24e45a52885..68fcb0e78641 100644 --- a/usr.sbin/quotactl/quotactl.c +++ b/usr.sbin/quotactl/quotactl.c @@ -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 #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 #include -#include +#include 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)); } diff --git a/usr.sbin/quotaon/Makefile b/usr.sbin/quotaon/Makefile index 4d863cb07955..afff59a4705e 100644 --- a/usr.sbin/quotaon/Makefile +++ b/usr.sbin/quotaon/Makefile @@ -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 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 diff --git a/usr.sbin/quotaon/quotaon.c b/usr.sbin/quotaon/quotaon.c index 0bcad1463f62..516fc7c0c4f6 100644 --- a/usr.sbin/quotaon/quotaon.c +++ b/usr.sbin/quotaon/quotaon.c @@ -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 #include -#include +#include #include #include @@ -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); diff --git a/usr.sbin/repquota/Makefile b/usr.sbin/repquota/Makefile index 58c0ab74d3c5..f1407b647a81 100644 --- a/usr.sbin/repquota/Makefile +++ b/usr.sbin/repquota/Makefile @@ -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 @@ -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 diff --git a/usr.sbin/repquota/repquota.c b/usr.sbin/repquota/repquota.c index e25f72075c83..adeac86aea7f 100644 --- a/usr.sbin/repquota/repquota.c +++ b/usr.sbin/repquota/repquota.c @@ -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 #include #include -#include -#include #include #include @@ -66,24 +64,26 @@ __RCSID("$NetBSD: repquota.c,v 1.29 2011/03/07 11:56:31 bouyer Exp $"); #include #include -#include +#include +#include #include +#include #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; }