Module Name: src Committed By: dholland Date: Mon Jan 30 16:45:13 UTC 2012
Modified Files: src/include: quota.h src/lib/libquota: quota_oldfiles.c quota_open.c quota_proplib.c quotapvt.h src/usr.sbin/quotaon: Makefile quotaon.c Log Message: Add quota_quotaon() and quota_quotaoff(). Use them in quotaon(8). To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/include/quota.h cvs rdiff -u -r1.4 -r1.5 src/lib/libquota/quota_oldfiles.c cvs rdiff -u -r1.5 -r1.6 src/lib/libquota/quota_open.c cvs rdiff -u -r1.9 -r1.10 src/lib/libquota/quota_proplib.c cvs rdiff -u -r1.11 -r1.12 src/lib/libquota/quotapvt.h cvs rdiff -u -r1.8 -r1.9 src/usr.sbin/quotaon/Makefile cvs rdiff -u -r1.28 -r1.29 src/usr.sbin/quotaon/quotaon.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/include/quota.h diff -u src/include/quota.h:1.4 src/include/quota.h:1.5 --- src/include/quota.h:1.4 Mon Jan 30 16:44:08 2012 +++ src/include/quota.h Mon Jan 30 16:45:13 2012 @@ -55,6 +55,9 @@ unsigned quota_getnumobjtypes(struct quo const char *quota_objtype_getname(struct quotahandle *, int /*objtype*/); int quota_objtype_isbytes(struct quotahandle *, int /*objtype*/); +int quota_quotaon(struct quotahandle *, int /*idtype*/); +int quota_quotaoff(struct quotahandle *, int /*idtype*/); + int quota_get(struct quotahandle *, const struct quotakey *, struct quotaval *); Index: src/lib/libquota/quota_oldfiles.c diff -u src/lib/libquota/quota_oldfiles.c:1.4 src/lib/libquota/quota_oldfiles.c:1.5 --- src/lib/libquota/quota_oldfiles.c:1.4 Mon Jan 30 06:15:22 2012 +++ src/lib/libquota/quota_oldfiles.c Mon Jan 30 16:45:13 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quota_oldfiles.c,v 1.4 2012/01/30 06:15:22 dholland Exp $ */ +/* $NetBSD: quota_oldfiles.c,v 1.5 2012/01/30 16:45:13 dholland Exp $ */ /* * Copyright (c) 1980, 1990, 1993 @@ -237,6 +237,57 @@ __quota_oldfiles_infstab(const char *mou return __quota_oldfiles_find_fstabentry(mountpoint) != NULL; } +static void +__quota_oldfiles_defquotafile(struct quotahandle *qh, int idtype, + char *buf, size_t maxlen) +{ + static const char *const names[] = INITQFNAMES; + + (void)snprintf(buf, maxlen, "%s/%s.%s", + qh->qh_mountpoint, + QUOTAFILENAME, names[USRQUOTA]); +} + +const char * +__quota_oldfiles_getquotafile(struct quotahandle *qh, int idtype, + char *buf, size_t maxlen) +{ + const struct oldfiles_fstabentry *ofe; + const char *file; + + ofe = __quota_oldfiles_find_fstabentry(qh->qh_mountpoint); + if (ofe == NULL) { + errno = ENXIO; + return NULL; + } + + switch (idtype) { + case USRQUOTA: + if (!ofe->ofe_hasuserquota) { + errno = ENXIO; + return NULL; + } + file = ofe->ofe_userquotafile; + break; + case GRPQUOTA: + if (!ofe->ofe_hasgroupquota) { + errno = ENXIO; + return NULL; + } + file = ofe->ofe_groupquotafile; + break; + default: + errno = EINVAL; + return NULL; + } + + if (file == NULL) { + __quota_oldfiles_defquotafile(qh, idtype, buf, maxlen); + file = buf; + } + return file; +} + static uint64_t dqblk_getlimit(uint32_t val) { @@ -316,8 +367,6 @@ __quota_oldfiles_open(struct quotahandle int __quota_oldfiles_initialize(struct quotahandle *qh) { - static const char *const names[] = INITQFNAMES; - const struct oldfiles_fstabentry *ofe; char path[PATH_MAX]; const char *userquotafile, *groupquotafile; @@ -345,9 +394,8 @@ __quota_oldfiles_initialize(struct quota if (ofe->ofe_hasuserquota) { userquotafile = ofe->ofe_userquotafile; if (userquotafile == NULL) { - (void)snprintf(path, sizeof(path), "%s/%s.%s", - qh->qh_mountpoint, - QUOTAFILENAME, names[USRQUOTA]); + __quota_oldfiles_defquotafile(qh, USRQUOTA, + path, sizeof(path)); userquotafile = path; } if (__quota_oldfiles_open(qh, userquotafile, @@ -358,9 +406,8 @@ __quota_oldfiles_initialize(struct quota if (ofe->ofe_hasgroupquota) { groupquotafile = ofe->ofe_groupquotafile; if (groupquotafile == NULL) { - (void)snprintf(path, sizeof(path), "%s/%s.%s", - qh->qh_mountpoint, - QUOTAFILENAME, names[GRPQUOTA]); + __quota_oldfiles_defquotafile(qh, GRPQUOTA, + path, sizeof(path)); groupquotafile = path; } if (__quota_oldfiles_open(qh, groupquotafile, @@ -380,6 +427,45 @@ __quota_oldfiles_getimplname(struct quot return "ufs/ffs quota v1 file access"; } +int +__quota_oldfiles_quotaon(struct quotahandle *qh, int idtype) +{ + int result; + + /* + * If we have the quota files open, close them. + */ + + if (qh->qh_oldfilesopen) { + if (qh->qh_userfile >= 0) { + close(qh->qh_userfile); + qh->qh_userfile = -1; + } + if (qh->qh_groupfile >= 0) { + close(qh->qh_groupfile); + qh->qh_groupfile = -1; + } + qh->qh_oldfilesopen = 0; + } + + /* + * Go over to the syscall interface. + */ + + result = __quota_proplib_quotaon(qh, idtype); + if (result < 0) { + return -1; + } + + /* + * We succeeded, so all further access should be via the + * kernel. + */ + + qh->qh_mode = QUOTA_MODE_PROPLIB; + return 0; +} + static int __quota_oldfiles_doget(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv, int *isallzero) Index: src/lib/libquota/quota_open.c diff -u src/lib/libquota/quota_open.c:1.5 src/lib/libquota/quota_open.c:1.6 --- src/lib/libquota/quota_open.c:1.5 Wed Jan 25 17:43:37 2012 +++ src/lib/libquota/quota_open.c Mon Jan 30 16:45:13 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quota_open.c,v 1.5 2012/01/25 17:43:37 dholland Exp $ */ +/* $NetBSD: quota_open.c,v 1.6 2012/01/30 16:45:13 dholland Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: quota_open.c,v 1.5 2012/01/25 17:43:37 dholland Exp $"); +__RCSID("$NetBSD: quota_open.c,v 1.6 2012/01/30 16:45:13 dholland Exp $"); #include <sys/types.h> #include <sys/statvfs.h> @@ -64,6 +64,15 @@ quota_open(const char *path) * 3. Check if the volume is listed in fstab as one of * the filesystem types supported by quota_oldfiles.c, * and with the proper mount options to enable quotas. + * + * Note that (as of this writing) the mount options for + * enabling quotas are accepted by mount for *all* filesystem + * types and then ignored -- the kernel mount flag (ST_QUOTA / + * MNT_QUOTA) gets set either by the filesystem based on its + * own criteria, or for old-style quotas, during quotaon. The + * quota filenames specified in fstab are not passed to or + * known by the kernel except via quota_oldfiles.c! This is + * generally gross but not easily fixed. */ if (statvfs(path, &stv) < 0) { @@ -144,3 +153,41 @@ quota_close(struct quotahandle *qh) free(qh->qh_mountpoint); free(qh); } + +int +quota_quotaon(struct quotahandle *qh, int idtype) +{ + switch (qh->qh_mode) { + case QUOTA_MODE_NFS: + errno = EOPNOTSUPP; + break; + case QUOTA_MODE_PROPLIB: + return __quota_proplib_quotaon(qh, idtype); + case QUOTA_MODE_OLDFILES: + return __quota_oldfiles_quotaon(qh, idtype); + default: + errno = EINVAL; + break; + } + return -1; +} + +int +quota_quotaoff(struct quotahandle *qh, int idtype) +{ + switch (qh->qh_mode) { + case QUOTA_MODE_NFS: + errno = EOPNOTSUPP; + break; + case QUOTA_MODE_PROPLIB: + return __quota_proplib_quotaoff(qh, idtype); + case QUOTA_MODE_OLDFILES: + /* can't quotaoff if we haven't quotaon'd */ + errno = ENOTCONN; + break; + default: + errno = EINVAL; + break; + } + return -1; +} Index: src/lib/libquota/quota_proplib.c diff -u src/lib/libquota/quota_proplib.c:1.9 src/lib/libquota/quota_proplib.c:1.10 --- src/lib/libquota/quota_proplib.c:1.9 Mon Jan 30 16:44:08 2012 +++ src/lib/libquota/quota_proplib.c Mon Jan 30 16:45:13 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quota_proplib.c,v 1.9 2012/01/30 16:44:08 dholland Exp $ */ +/* $NetBSD: quota_proplib.c,v 1.10 2012/01/30 16:45:13 dholland Exp $ */ /*- * Copyright (c) 2011 Manuel Bouyer * All rights reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: quota_proplib.c,v 1.9 2012/01/30 16:44:08 dholland Exp $"); +__RCSID("$NetBSD: quota_proplib.c,v 1.10 2012/01/30 16:45:13 dholland Exp $"); #include <stdlib.h> #include <string.h> @@ -35,6 +35,7 @@ __RCSID("$NetBSD: quota_proplib.c,v 1.9 #include <err.h> #include <quota.h> +#include <ufs/ufs/quota1.h> #include "quotapvt.h" #include <quota/quotaprop.h> @@ -55,6 +56,8 @@ struct proplib_quotacursor { unsigned didblocks; }; +static const char *const __quota1_qfnames[] = INITQFNAMES; + int __quota_proplib_getversion(struct quotahandle *qh, int8_t *version_ret) { @@ -240,6 +243,112 @@ __quota_proplib_objtype_isbytes(int objt } static int +__quota_proplib_quotaonoff(struct quotahandle *qh, int idtype, int offmode) +{ + prop_dictionary_t dict, data, cmd; + prop_array_t cmds, datas; + struct plistref pref; + int8_t error8; + const char *file; + char path[PATH_MAX]; + + /* + * Note that while it is an error to call quotaon on something + * that isn't a volume with old-style quotas that expects + * quotaon to be called, it's not our responsibility to check + * for that; the filesystem will. Also note that it is not an + * error to call quotaon repeatedly -- apparently this is to + * permit changing the quota file in use on the fly or + * something. So all we need to do here is ask the oldfiles + * code if the mount option was set in fstab and fetch back + * the filename. + */ + + if (offmode) { + file = NULL; + } else { + file = __quota_oldfiles_getquotafile(qh, idtype, + path, sizeof(path)); + if (file == NULL) { + /* + * This idtype (or maybe any idtype) was + * not enabled in fstab. + */ + errno = ENXIO; + return -1; + } + } + + 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 (offmode) { + if (!quota_prop_add_command(cmds, "quotaoff", + __quota1_qfnames[idtype], datas)) + err(1, "prop_add_command"); + } else { + data = prop_dictionary_create(); + if (data == NULL) + errx(1, "can't allocate proplist"); + if (!prop_dictionary_set_cstring(data, "quotafile", file)) + err(1, "prop_dictionary_set(quotafile)"); + if (!prop_array_add_and_rel(datas, data)) + err(1, "prop_array_add(data)"); + if (!quota_prop_add_command(cmds, "quotaon", + __quota1_qfnames[idtype], datas)) + err(1, "prop_add_command"); + } + if (!prop_dictionary_set(dict, "commands", cmds)) + err(1, "prop_dictionary_set(command)"); + + if (prop_dictionary_send_syscall(dict, &pref) != 0) + err(1, "prop_dictionary_send_syscall"); + prop_object_release(dict); + + if (quotactl(qh->qh_mountpoint, &pref) != 0) { + warn("quotactl(%s)", qh->qh_mountpoint); + return -1; + } + + if (prop_dictionary_recv_syscall(&pref, &dict) != 0) + err(1, "prop_dictionary_recv_syscall"); + + 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); + if (cmd == NULL) + err(1, "prop_array_get(cmd)"); + + if (!prop_dictionary_get_int8(cmd, "return", &error8)) + err(1, "prop_get(return)"); + + if (error8) { + errno = error8; + return -1; + } + + return 0; +} + +int +__quota_proplib_quotaon(struct quotahandle *qh, int idtype) +{ + return __quota_proplib_quotaonoff(qh, idtype, 0); +} + +int +__quota_proplib_quotaoff(struct quotahandle *qh, int idtype) +{ + return __quota_proplib_quotaonoff(qh, idtype, 1); +} + +static int __quota_proplib_extractval(int objtype, prop_dictionary_t data, struct quotaval *qv) { Index: src/lib/libquota/quotapvt.h diff -u src/lib/libquota/quotapvt.h:1.11 src/lib/libquota/quotapvt.h:1.12 --- src/lib/libquota/quotapvt.h:1.11 Mon Jan 30 16:44:09 2012 +++ src/lib/libquota/quotapvt.h Mon Jan 30 16:45:13 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quotapvt.h,v 1.11 2012/01/30 16:44:09 dholland Exp $ */ +/* $NetBSD: quotapvt.h,v 1.12 2012/01/30 16:45:13 dholland Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -64,6 +64,8 @@ const char *__quota_proplib_idtype_getna unsigned __quota_proplib_getnumobjtypes(void); const char *__quota_proplib_objtype_getname(int objtype); int __quota_proplib_objtype_isbytes(int objtype); +int __quota_proplib_quotaon(struct quotahandle *, int idtype); +int __quota_proplib_quotaoff(struct quotahandle *, int idtype); int __quota_proplib_get(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv); int __quota_proplib_put(struct quotahandle *qh, const struct quotakey *qk, @@ -95,6 +97,9 @@ void __quota_oldfiles_load_fstab(void); int __quota_oldfiles_infstab(const char *); int __quota_oldfiles_initialize(struct quotahandle *qh); const char *__quota_oldfiles_getimplname(struct quotahandle *); +const char *__quota_oldfiles_getquotafile(struct quotahandle *, int idtype, + char *buf, size_t maxlen); +int __quota_oldfiles_quotaon(struct quotahandle *, int idtype); int __quota_oldfiles_get(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv); int __quota_oldfiles_put(struct quotahandle *qh, const struct quotakey *qk, Index: src/usr.sbin/quotaon/Makefile diff -u src/usr.sbin/quotaon/Makefile:1.8 src/usr.sbin/quotaon/Makefile:1.9 --- src/usr.sbin/quotaon/Makefile:1.8 Thu Mar 24 17:05:47 2011 +++ src/usr.sbin/quotaon/Makefile Mon Jan 30 16:45:13 2012 @@ -1,5 +1,5 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $NetBSD: Makefile,v 1.8 2011/03/24 17:05:47 bouyer Exp $ +# $NetBSD: Makefile,v 1.9 2012/01/30 16:45:13 dholland Exp $ .include <bsd.own.mk> WARNS ?= 4 @@ -10,11 +10,6 @@ MAN= quotaon.8 MLINKS= quotaon.8 quotaoff.8 LINKS= ${BINDIR}/quotaon ${BINDIR}/quotaoff -.PATH: ${NETBSDSRCDIR}/usr.bin/quota -SRCS+= quotautil.c -CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/quota -CPPFLAGS+=-I${NETBSDSRCDIR}/sys - DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC} LDADD= -lquota -lprop -lrpcsvc Index: src/usr.sbin/quotaon/quotaon.c diff -u src/usr.sbin/quotaon/quotaon.c:1.28 src/usr.sbin/quotaon/quotaon.c:1.29 --- src/usr.sbin/quotaon/quotaon.c:1.28 Wed Jan 25 01:28:40 2012 +++ src/usr.sbin/quotaon/quotaon.c Mon Jan 30 16:45:13 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quotaon.c,v 1.28 2012/01/25 01:28:40 dholland Exp $ */ +/* $NetBSD: quotaon.c,v 1.29 2012/01/30 16:45:13 dholland Exp $ */ /* * Copyright (c) 1980, 1990, 1993 @@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: quotaon.c,v 1.28 2012/01/25 01:28:40 dholland Exp $"); +__RCSID("$NetBSD: quotaon.c,v 1.29 2012/01/30 16:45:13 dholland Exp $"); #endif #endif /* not lint */ @@ -53,10 +53,8 @@ __RCSID("$NetBSD: quotaon.c,v 1.28 2012/ #include <sys/file.h> #include <sys/mount.h> -#include <quota/quotaprop.h> +#include <quota.h> #include <ufs/ufs/quota1.h> -#include <sys/quota.h> - #include <err.h> #include <fstab.h> @@ -66,26 +64,29 @@ __RCSID("$NetBSD: quotaon.c,v 1.28 2012/ #include <string.h> #include <unistd.h> -#include "quotautil.h" -static int aflag; /* all file systems */ -static int gflag; /* operate on group quotas */ -static int uflag; /* operate on user quotas */ static int vflag; /* verbose */ static void usage(void) __dead; -static int quotaonoff(struct fstab *, int, int, const char *); +static int quotaonoff(struct fstab *, struct quotahandle *, int, int, int); static int readonly(struct fstab *); +static int oneof(const char *target, char *list[], int cnt); int main(int argc, char *argv[]) { struct fstab *fs; - char qfnp[MAXPATHLEN]; + struct quotahandle *qh; long argnum, done = 0; int i, offmode = 0, errs = 0; + unsigned restrictions; int ch; + int aflag = 0; /* all file systems */ + int gflag = 0; /* operate on group quotas */ + int uflag = 0; /* operate on user quotas */ + int noguflag = 0; /* operate on both (by default) */ + if (strcmp(getprogname(), "quotaoff") == 0) offmode++; else if (strcmp(getprogname(), "quotaon") != 0) @@ -117,30 +118,74 @@ main(int argc, char *argv[]) usage(); if (!gflag && !uflag) { - gflag++; - uflag++; + noguflag = 1; + } + + /* + * XXX at the moment quota_open also uses getfsent(), but it + * uses it only up front. To avoid conflicting with it, let it + * initialize first. + */ + qh = quota_open("/"); + if (qh != NULL) { + quota_close(qh); } + setfsent(); while ((fs = getfsent()) != NULL) { if ((strcmp(fs->fs_vfstype, "ffs") && strcmp(fs->fs_vfstype, "lfs")) || strcmp(fs->fs_type, FSTAB_RW)) continue; - if (aflag) { - if (gflag && hasquota(qfnp, sizeof(qfnp), fs, GRPQUOTA)) - errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); - if (uflag && hasquota(qfnp, sizeof(qfnp), fs, USRQUOTA)) - errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); + + if (!aflag) { + if ((argnum = oneof(fs->fs_file, argv, argc)) < 0 && + (argnum = oneof(fs->fs_spec, argv, argc)) < 0) { + continue; + } + done |= 1U << argnum; + } + + qh = quota_open(fs->fs_file); + if (qh == NULL) { + if (!aflag) { + warn("quota_open"); + errs++; + } + continue; + } + + restrictions = quota_getrestrictions(qh); + if ((restrictions & QUOTA_RESTRICT_NEEDSQUOTACHECK) == 0) { + /* Not a quota v1 volume, skip it */ + if (!aflag) { + errno = EBUSY; + warn("%s", fs->fs_file); + errs++; + } + quota_close(qh); continue; } - if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || - (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { - done |= 1U << argnum; - if (gflag && hasquota(qfnp, sizeof(qfnp), fs, GRPQUOTA)) - errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); - if (uflag && hasquota(qfnp, sizeof(qfnp), fs, USRQUOTA)) - errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); + + /* + * The idea here is to warn if someone explicitly + * tries to turn on group quotas and there are no + * group quotas, and likewise for user quotas, but not + * to warn if just doing the default thing and one of + * the quota types isn't configured. + */ + + if (noguflag) { + errs += quotaonoff(fs, qh, offmode, GRPQUOTA, 0); + errs += quotaonoff(fs, qh, offmode, USRQUOTA, 0); } + if (gflag) { + errs += quotaonoff(fs, qh, offmode, GRPQUOTA, 1); + } + if (uflag) { + errs += quotaonoff(fs, qh, offmode, USRQUOTA, 1); + } + quota_close(qh); } endfsent(); for (i = 0; i < argc; i++) @@ -159,76 +204,34 @@ usage(void) } static int -quotaonoff( struct fstab *fs, int offmode, int type, const char *qfpathname) +quotaonoff(struct fstab *fs, struct quotahandle *qh, int offmode, int idtype, + int warn_on_enxio) { const char *mode = (offmode == 1) ? "off" : "on"; - prop_dictionary_t dict, data, cmd; - prop_array_t cmds, datas; - struct plistref pref; - int8_t error8; - - dict = quota_prop_create(); - cmds = prop_array_create(); - datas = prop_array_create(); - if (strcmp(fs->fs_file, "/") && readonly(fs)) + if (strcmp(fs->fs_file, "/") && readonly(fs)) { return 1; - - if (dict == NULL || cmds == NULL || datas == NULL) - errx(1, "can't allocate proplist"); + } if (offmode) { - if (!quota_prop_add_command(cmds, "quotaoff", - qfextension[type], datas)) - err(1, "prop_add_command"); + if (quota_quotaoff(qh, idtype)) { + if (warn_on_enxio || errno != ENXIO) { + warn("quota%s for %s", mode, fs->fs_file); + } + return 1; + } } else { - data = prop_dictionary_create(); - if (data == NULL) - errx(1, "can't allocate proplist"); - if (!prop_dictionary_set_cstring(data, "quotafile", - qfpathname)) - err(1, "prop_dictionary_set(quotafile)"); - if (!prop_array_add_and_rel(datas, data)) - err(1, "prop_array_add(data)"); - if (!quota_prop_add_command(cmds, "quotaon", - qfextension[type], datas)) - err(1, "prop_add_command"); - } - if (!prop_dictionary_set(dict, "commands", cmds)) - err(1, "prop_dictionary_set(command)"); - - if (prop_dictionary_send_syscall(dict, &pref) != 0) - err(1, "prop_dictionary_send_syscall"); - prop_object_release(dict); - - if (quotactl(fs->fs_file, &pref) != 0) { - warn("quotactl(%s)", fs->fs_file); - return(1); - } - - if (prop_dictionary_recv_syscall(&pref, &dict) != 0) - err(1, "prop_dictionary_recv_syscall"); - - 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); - if (cmd == NULL) - err(1, "prop_array_get(cmd)"); - - if (!prop_dictionary_get_int8(cmd, "return", &error8)) - err(1, "prop_get(return)"); - - if (error8) { - errno = error8; - warn("quota%s for %s", mode, fs->fs_file); - return 1; + if (quota_quotaon(qh, idtype)) { + if (warn_on_enxio || errno != ENXIO) { + warn("quota%s for %s", mode, fs->fs_file); + } + return 1; + } } if (vflag) { printf("%s: %s quotas turned %s\n", - fs->fs_file, qfextension[type], mode); + fs->fs_file, quota_idtype_getname(qh, idtype), mode); } return 0; } @@ -253,3 +256,17 @@ readonly(struct fstab *fs) } return 0; } + +/* + * Check to see if target appears in list of size cnt. + */ +static int +oneof(const char *target, char *list[], int cnt) +{ + int i; + + for (i = 0; i < cnt; i++) + if (strcmp(target, list[i]) == 0) + return i; + return -1; +}