Per the FS-independent schema, get one quotaval at a time from the filesystem, instead of blocks and files together. This results in fetching each FS-level quota entry twice and therefore doing slightly more work, but (1) quota access isn't a critical path and (2) after fetching the block values the file values will be hot in the cache, so it won't add much total time. Also move more of the FS-independent defintions from <quota.h> to <sys/quota.h> so we can use them internally. Step 4 of 5 for QUOTACTL_GET. Note: this change requires a kernel version bump.diff -r1.2 -r1.3 src/include/quota.h
(dholland)
--- src/include/quota.h 2012/01/29 06:38:23 1.2
+++ src/include/quota.h 2012/01/29 06:40:57 1.3
@@ -26,46 +26,26 @@ | @@ -26,46 +26,26 @@ | |||
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 | * POSSIBILITY OF SUCH DAMAGE. | 27 | * POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #ifndef _QUOTA_H_ | 30 | #ifndef _QUOTA_H_ | |
31 | #define _QUOTA_H_ | 31 | #define _QUOTA_H_ | |
32 | 32 | |||
33 | #include <sys/types.h> | 33 | #include <sys/types.h> | |
34 | #include <sys/quota.h> | 34 | #include <sys/quota.h> | |
35 | 35 | |||
36 | struct quotahandle; /* Opaque. */ | 36 | struct quotahandle; /* Opaque. */ | |
37 | struct quotacursor; /* Opaque. */ | 37 | struct quotacursor; /* Opaque. */ | |
38 | 38 | |||
39 | /* quota id types (entities being billed) */ | |||
40 | #define QUOTA_IDTYPE_USER 0 | |||
41 | #define QUOTA_IDTYPE_GROUP 1 | |||
42 | ||||
43 | /* quota object types (things being limited) */ | |||
44 | #define QUOTA_OBJTYPE_BLOCKS 0 | |||
45 | #define QUOTA_OBJTYPE_FILES 1 | |||
46 | ||||
47 | /* limit value for "no limit" */ | |||
48 | #define QUOTA_NOLIMIT ((uint64_t)0xffffffffffffffffULL) | |||
49 | ||||
50 | /* time value for "no time" */ | |||
51 | #define QUOTA_NOTIME ((time_t)-1) | |||
52 | ||||
53 | ||||
54 | struct quotakey { | |||
55 | int qk_idtype; | |||
56 | id_t qk_id; | |||
57 | int qk_objtype; | |||
58 | }; | |||
59 | 39 | |||
60 | void quotaval_clear(struct quotaval *); | 40 | void quotaval_clear(struct quotaval *); | |
61 | 41 | |||
62 | struct quotahandle *quota_open(const char *); | 42 | struct quotahandle *quota_open(const char *); | |
63 | void quota_close(struct quotahandle *); | 43 | void quota_close(struct quotahandle *); | |
64 | 44 | |||
65 | const char *quota_getmountpoint(struct quotahandle *); | 45 | const char *quota_getmountpoint(struct quotahandle *); | |
66 | const char *quota_getmountdevice(struct quotahandle *); | 46 | const char *quota_getmountdevice(struct quotahandle *); | |
67 | 47 | |||
68 | const char *quota_getimplname(struct quotahandle *); | 48 | const char *quota_getimplname(struct quotahandle *); | |
69 | 49 | |||
70 | unsigned quota_getnumidtypes(struct quotahandle *); | 50 | unsigned quota_getnumidtypes(struct quotahandle *); | |
71 | const char *quota_idtype_getname(struct quotahandle *, int /*idtype*/); | 51 | const char *quota_idtype_getname(struct quotahandle *, int /*idtype*/); |
--- src/sys/kern/vfs_quotactl.c 2012/01/29 06:39:36 1.8
+++ src/sys/kern/vfs_quotactl.c 2012/01/29 06:40:57 1.9
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vfs_quotactl.c,v 1.8 2012/01/29 06:39:36 dholland Exp $ */ | 1 | /* $NetBSD: vfs_quotactl.c,v 1.9 2012/01/29 06:40:57 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1991, 1993, 1994 | 4 | * Copyright (c) 1991, 1993, 1994 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * (c) UNIX System Laboratories, Inc. | 6 | * (c) UNIX System Laboratories, Inc. | |
7 | * All or some portions of this file are derived from material licensed | 7 | * All or some portions of this file are derived from material licensed | |
8 | * to the University of California by American Telephone and Telegraph | 8 | * to the University of California by American Telephone and Telegraph | |
9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | |
10 | * the permission of UNIX System Laboratories, Inc. | 10 | * the permission of UNIX System Laboratories, Inc. | |
11 | * | 11 | * | |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without | |
13 | * modification, are permitted provided that the following conditions | 13 | * modification, are permitted provided that the following conditions | |
14 | * are met: | 14 | * are met: | |
@@ -70,27 +70,27 @@ | @@ -70,27 +70,27 @@ | |||
70 | * | 70 | * | |
71 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | 71 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | |
72 | * From NetBSD: ufs_quota.c,v 1.70 2011/03/24 17:05:46 bouyer Exp | 72 | * From NetBSD: ufs_quota.c,v 1.70 2011/03/24 17:05:46 bouyer Exp | |
73 | */ | 73 | */ | |
74 | 74 | |||
75 | /* | 75 | /* | |
76 | * Note that both of the copyrights above are moderately spurious; | 76 | * Note that both of the copyrights above are moderately spurious; | |
77 | * this code should almost certainly have the Copyright 2010 Manuel | 77 | * this code should almost certainly have the Copyright 2010 Manuel | |
78 | * Bouyer notice and license found in e.g. sys/ufs/ufs/quota2_subr.c. | 78 | * Bouyer notice and license found in e.g. sys/ufs/ufs/quota2_subr.c. | |
79 | * However, they're what was on the files this code was sliced out of. | 79 | * However, they're what was on the files this code was sliced out of. | |
80 | */ | 80 | */ | |
81 | 81 | |||
82 | #include <sys/cdefs.h> | 82 | #include <sys/cdefs.h> | |
83 | __KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.8 2012/01/29 06:39:36 dholland Exp $"); | 83 | __KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.9 2012/01/29 06:40:57 dholland Exp $"); | |
84 | 84 | |||
85 | #include <sys/mount.h> | 85 | #include <sys/mount.h> | |
86 | #include <sys/quota.h> | 86 | #include <sys/quota.h> | |
87 | #include <sys/quotactl.h> | 87 | #include <sys/quotactl.h> | |
88 | #include <quota/quotaprop.h> | 88 | #include <quota/quotaprop.h> | |
89 | 89 | |||
90 | static int | 90 | static int | |
91 | vfs_quotactl_getversion(struct mount *mp, | 91 | vfs_quotactl_getversion(struct mount *mp, | |
92 | prop_dictionary_t cmddict, int q2type, | 92 | prop_dictionary_t cmddict, int q2type, | |
93 | prop_array_t datas) | 93 | prop_array_t datas) | |
94 | { | 94 | { | |
95 | prop_array_t replies; | 95 | prop_array_t replies; | |
96 | prop_dictionary_t data; | 96 | prop_dictionary_t data; | |
@@ -231,28 +231,45 @@ vfs_quotactl_get(struct mount *mp, | @@ -231,28 +231,45 @@ vfs_quotactl_get(struct mount *mp, | |||
231 | error = EINVAL; | 231 | error = EINVAL; | |
232 | goto fail; | 232 | goto fail; | |
233 | } | 233 | } | |
234 | id = 0; | 234 | id = 0; | |
235 | defaultq = 1; | 235 | defaultq = 1; | |
236 | } else { | 236 | } else { | |
237 | defaultq = 0; | 237 | defaultq = 0; | |
238 | } | 238 | } | |
239 | 239 | |||
240 | args.qc_type = QCT_GET; | 240 | args.qc_type = QCT_GET; | |
241 | args.u.get.qc_q2type = q2type; | 241 | args.u.get.qc_q2type = q2type; | |
242 | args.u.get.qc_id = id; | 242 | args.u.get.qc_id = id; | |
243 | args.u.get.qc_defaultq = defaultq; | 243 | args.u.get.qc_defaultq = defaultq; | |
244 | args.u.get.qc_blocks_ret = &blocks; | 244 | args.u.get.qc_objtype = QUOTA_OBJTYPE_BLOCKS; | |
245 | args.u.get.qc_files_ret = &files; | 245 | args.u.get.qc_ret = &blocks; | |
246 | error = VFS_QUOTACTL(mp, QUOTACTL_GET, &args); | |||
247 | if (error == EPERM) { | |||
248 | /* XXX does this make sense? */ | |||
249 | continue; | |||
250 | } else if (error == ENOENT) { | |||
251 | /* XXX does *this* make sense? */ | |||
252 | continue; | |||
253 | } else if (error) { | |||
254 | goto fail; | |||
255 | } | |||
256 | ||||
257 | args.qc_type = QCT_GET; | |||
258 | args.u.get.qc_q2type = q2type; | |||
259 | args.u.get.qc_id = id; | |||
260 | args.u.get.qc_defaultq = defaultq; | |||
261 | args.u.get.qc_objtype = QUOTA_OBJTYPE_FILES; | |||
262 | args.u.get.qc_ret = &files; | |||
246 | error = VFS_QUOTACTL(mp, QUOTACTL_GET, &args); | 263 | error = VFS_QUOTACTL(mp, QUOTACTL_GET, &args); | |
247 | if (error == EPERM) { | 264 | if (error == EPERM) { | |
248 | /* XXX does this make sense? */ | 265 | /* XXX does this make sense? */ | |
249 | continue; | 266 | continue; | |
250 | } else if (error == ENOENT) { | 267 | } else if (error == ENOENT) { | |
251 | /* XXX does *this* make sense? */ | 268 | /* XXX does *this* make sense? */ | |
252 | continue; | 269 | continue; | |
253 | } else if (error) { | 270 | } else if (error) { | |
254 | goto fail; | 271 | goto fail; | |
255 | } | 272 | } | |
256 | 273 | |||
257 | error = vfs_quotactl_get_addreply(id, defaultq, | 274 | error = vfs_quotactl_get_addreply(id, defaultq, | |
258 | &blocks, &files, | 275 | &blocks, &files, |
--- src/sys/sys/quota.h 2012/01/29 06:38:23 1.8
+++ src/sys/sys/quota.h 2012/01/29 06:40:57 1.9
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: quota.h,v 1.8 2012/01/29 06:38:23 dholland Exp $ */ | 1 | /* $NetBSD: quota.h,v 1.9 2012/01/29 06:40:57 dholland Exp $ */ | |
2 | /*- | 2 | /*- | |
3 | * Copyright (c) 2010 Manuel Bouyer | 3 | * Copyright (c) 2010 Manuel Bouyer | |
4 | * All rights reserved. | 4 | * All rights reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -20,28 +20,49 @@ | @@ -20,28 +20,49 @@ | |||
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
25 | * POSSIBILITY OF SUCH DAMAGE. | 25 | * POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #ifndef _SYS_QUOTA_H_ | 28 | #ifndef _SYS_QUOTA_H_ | |
29 | #define _SYS_QUOTA_H_ | 29 | #define _SYS_QUOTA_H_ | |
30 | 30 | |||
31 | #include <sys/types.h> | 31 | #include <sys/types.h> | |
32 | 32 | |||
33 | /* quota id types (entities being billed) */ | |||
34 | #define QUOTA_IDTYPE_USER 0 | |||
35 | #define QUOTA_IDTYPE_GROUP 1 | |||
36 | ||||
37 | /* quota object types (things being limited) */ | |||
38 | #define QUOTA_OBJTYPE_BLOCKS 0 | |||
39 | #define QUOTA_OBJTYPE_FILES 1 | |||
40 | ||||
33 | /* id value for "default" */ | 41 | /* id value for "default" */ | |
34 | #define QUOTA_DEFAULTID ((id_t)-1) | 42 | #define QUOTA_DEFAULTID ((id_t)-1) | |
35 | 43 | |||
44 | /* limit value for "no limit" */ | |||
45 | #define QUOTA_NOLIMIT ((uint64_t)0xffffffffffffffffULL) | |||
46 | ||||
47 | /* time value for "no time" */ | |||
48 | #define QUOTA_NOTIME ((time_t)-1) | |||
49 | ||||
50 | ||||
51 | struct quotakey { | |||
52 | int qk_idtype; | |||
53 | id_t qk_id; | |||
54 | int qk_objtype; | |||
55 | }; | |||
56 | ||||
36 | /* | 57 | /* | |
37 | * Structure used to describe the value part of a quota record. | 58 | * Structure used to describe the value part of a quota record. | |
38 | */ | 59 | */ | |
39 | struct quotaval { | 60 | struct quotaval { | |
40 | uint64_t qv_hardlimit; /* absolute limit */ | 61 | uint64_t qv_hardlimit; /* absolute limit */ | |
41 | uint64_t qv_softlimit; /* overflowable limit */ | 62 | uint64_t qv_softlimit; /* overflowable limit */ | |
42 | uint64_t qv_usage; /* current usage */ | 63 | uint64_t qv_usage; /* current usage */ | |
43 | time_t qv_expiretime; /* time when softlimit grace expires */ | 64 | time_t qv_expiretime; /* time when softlimit grace expires */ | |
44 | time_t qv_grace; /* allowed time for overflowing soft limit */ | 65 | time_t qv_grace; /* allowed time for overflowing soft limit */ | |
45 | }; | 66 | }; | |
46 | 67 | |||
47 | #endif /* _SYS_QUOTA_H_ */ | 68 | #endif /* _SYS_QUOTA_H_ */ |
--- src/sys/sys/quotactl.h 2012/01/29 06:39:36 1.6
+++ src/sys/sys/quotactl.h 2012/01/29 06:40:57 1.7
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: quotactl.h,v 1.6 2012/01/29 06:39:36 dholland Exp $ */ | 1 | /* $NetBSD: quotactl.h,v 1.7 2012/01/29 06:40:57 dholland Exp $ */ | |
2 | /*- | 2 | /*- | |
3 | * Copyright (c) 2011 The NetBSD Foundation, Inc. | 3 | * Copyright (c) 2011 The NetBSD Foundation, Inc. | |
4 | * All rights reserved. | 4 | * All rights reserved. | |
5 | * | 5 | * | |
6 | * This code is derived from software contributed to The NetBSD Foundation | 6 | * This code is derived from software contributed to The NetBSD Foundation | |
7 | * by David A. Holland. | 7 | * by David A. Holland. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -57,20 +57,20 @@ struct vfs_quotactl_args { | @@ -57,20 +57,20 @@ struct vfs_quotactl_args { | |||
57 | union { | 57 | union { | |
58 | struct { | 58 | struct { | |
59 | prop_dictionary_t qc_cmddict; | 59 | prop_dictionary_t qc_cmddict; | |
60 | int qc_q2type; | 60 | int qc_q2type; | |
61 | prop_array_t qc_datas; | 61 | prop_array_t qc_datas; | |
62 | } proplib; | 62 | } proplib; | |
63 | struct { | 63 | struct { | |
64 | int *qc_version_ret; | 64 | int *qc_version_ret; | |
65 | } getversion; | 65 | } getversion; | |
66 | struct { | 66 | struct { | |
67 | int qc_q2type; | 67 | int qc_q2type; | |
68 | id_t qc_id; | 68 | id_t qc_id; | |
69 | int qc_defaultq; | 69 | int qc_defaultq; | |
70 | struct quotaval *qc_blocks_ret; | 70 | int qc_objtype; | |
71 | struct quotaval *qc_files_ret; | 71 | struct quotaval *qc_ret; | |
72 | } get; | 72 | } get; | |
73 | } u; | 73 | } u; | |
74 | }; | 74 | }; | |
75 | 75 | |||
76 | #endif /* _SYS_QUOTACTL_H_ */ | 76 | #endif /* _SYS_QUOTACTL_H_ */ |
--- src/sys/ufs/ufs/ufs_quota.c 2012/01/29 06:39:37 1.76
+++ src/sys/ufs/ufs/ufs_quota.c 2012/01/29 06:40:57 1.77
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota.c,v 1.76 2012/01/29 06:39:37 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota.c,v 1.77 2012/01/29 06:40:57 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | 4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Robert Elz at The University of Melbourne. | 8 | * Robert Elz at The University of Melbourne. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -25,27 +25,27 @@ | @@ -25,27 +25,27 @@ | |||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | * | 33 | * | |
34 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | 34 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.76 2012/01/29 06:39:37 dholland Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.77 2012/01/29 06:40:57 dholland Exp $"); | |
39 | 39 | |||
40 | #if defined(_KERNEL_OPT) | 40 | #if defined(_KERNEL_OPT) | |
41 | #include "opt_quota.h" | 41 | #include "opt_quota.h" | |
42 | #endif | 42 | #endif | |
43 | #include <sys/param.h> | 43 | #include <sys/param.h> | |
44 | #include <sys/kernel.h> | 44 | #include <sys/kernel.h> | |
45 | #include <sys/systm.h> | 45 | #include <sys/systm.h> | |
46 | #include <sys/namei.h> | 46 | #include <sys/namei.h> | |
47 | #include <sys/file.h> | 47 | #include <sys/file.h> | |
48 | #include <sys/proc.h> | 48 | #include <sys/proc.h> | |
49 | #include <sys/vnode.h> | 49 | #include <sys/vnode.h> | |
50 | #include <sys/mount.h> | 50 | #include <sys/mount.h> | |
51 | #include <sys/kauth.h> | 51 | #include <sys/kauth.h> | |
@@ -225,52 +225,53 @@ quota_get_auth(struct mount *mp, struct | @@ -225,52 +225,53 @@ quota_get_auth(struct mount *mp, struct | |||
225 | return kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | 225 | return kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | |
226 | KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, KAUTH_ARG(id), NULL); | 226 | KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, KAUTH_ARG(id), NULL); | |
227 | } | 227 | } | |
228 | 228 | |||
229 | static int | 229 | static int | |
230 | quota_handle_cmd_get(struct mount *mp, struct lwp *l, | 230 | quota_handle_cmd_get(struct mount *mp, struct lwp *l, | |
231 | struct vfs_quotactl_args *args) | 231 | struct vfs_quotactl_args *args) | |
232 | { | 232 | { | |
233 | struct ufsmount *ump = VFSTOUFS(mp); | 233 | struct ufsmount *ump = VFSTOUFS(mp); | |
234 | int error; | 234 | int error; | |
235 | id_t id; | 235 | id_t id; | |
236 | int q2type; | 236 | int q2type; | |
237 | int defaultq; | 237 | int defaultq; | |
238 | struct quotaval *blocks, *files; | 238 | int objtype; | |
239 | struct quotaval *ret; | |||
239 | 240 | |||
240 | KASSERT(args->qc_type == QCT_GET); | 241 | KASSERT(args->qc_type == QCT_GET); | |
241 | id = args->u.get.qc_id; | 242 | id = args->u.get.qc_id; | |
242 | q2type = args->u.get.qc_q2type; | 243 | q2type = args->u.get.qc_q2type; | |
243 | defaultq = args->u.get.qc_defaultq; | 244 | defaultq = args->u.get.qc_defaultq; | |
244 | blocks = args->u.get.qc_blocks_ret; | 245 | objtype = args->u.get.qc_objtype; | |
245 | files = args->u.get.qc_files_ret; | 246 | ret = args->u.get.qc_ret; | |
246 | 247 | |||
247 | if ((ump->um_flags & (UFS_QUOTA|UFS_QUOTA2)) == 0) | 248 | if ((ump->um_flags & (UFS_QUOTA|UFS_QUOTA2)) == 0) | |
248 | return EOPNOTSUPP; | 249 | return EOPNOTSUPP; | |
249 | 250 | |||
250 | /* avoid whitespace diffs */ { | 251 | /* avoid whitespace diffs */ { | |
251 | error = quota_get_auth(mp, l, id); | 252 | error = quota_get_auth(mp, l, id); | |
252 | if (error != 0) | 253 | if (error != 0) | |
253 | return error; | 254 | return error; | |
254 | #ifdef QUOTA | 255 | #ifdef QUOTA | |
255 | if (ump->um_flags & UFS_QUOTA) { | 256 | if (ump->um_flags & UFS_QUOTA) { | |
256 | error = quota1_handle_cmd_get(ump, q2type, id, defaultq, | 257 | error = quota1_handle_cmd_get(ump, q2type, id, defaultq, | |
257 | blocks, files); | 258 | objtype, ret); | |
258 | } else | 259 | } else | |
259 | #endif | 260 | #endif | |
260 | #ifdef QUOTA2 | 261 | #ifdef QUOTA2 | |
261 | if (ump->um_flags & UFS_QUOTA2) { | 262 | if (ump->um_flags & UFS_QUOTA2) { | |
262 | error = quota2_handle_cmd_get(ump, q2type, id, defaultq, | 263 | error = quota2_handle_cmd_get(ump, q2type, id, defaultq, | |
263 | blocks, files); | 264 | objtype, ret); | |
264 | } else | 265 | } else | |
265 | #endif | 266 | #endif | |
266 | panic("quota_handle_cmd_get: no support ?"); | 267 | panic("quota_handle_cmd_get: no support ?"); | |
267 | 268 | |||
268 | if (error != 0) | 269 | if (error != 0) | |
269 | return error; | 270 | return error; | |
270 | } | 271 | } | |
271 | 272 | |||
272 | return error; | 273 | return error; | |
273 | } | 274 | } | |
274 | 275 | |||
275 | static int | 276 | static int | |
276 | quota_handle_cmd_set(struct mount *mp, struct lwp *l, | 277 | quota_handle_cmd_set(struct mount *mp, struct lwp *l, |
--- src/sys/ufs/ufs/ufs_quota.h 2012/01/29 06:38:24 1.3
+++ src/sys/ufs/ufs/ufs_quota.h 2012/01/29 06:40:57 1.4
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota.h,v 1.3 2012/01/29 06:38:24 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota.h,v 1.4 2012/01/29 06:40:57 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | 4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Robert Elz at The University of Melbourne. | 8 | * Robert Elz at The University of Melbourne. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -103,30 +103,30 @@ extern kcondvar_t dqcv; | @@ -103,30 +103,30 @@ extern kcondvar_t dqcv; | |||
103 | const char *quotatypes[MAXQUOTAS]; | 103 | const char *quotatypes[MAXQUOTAS]; | |
104 | 104 | |||
105 | int getinoquota(struct inode *); | 105 | int getinoquota(struct inode *); | |
106 | int dqget(struct vnode *, u_long, struct ufsmount *, int, struct dquot **); | 106 | int dqget(struct vnode *, u_long, struct ufsmount *, int, struct dquot **); | |
107 | void dqref(struct dquot *); | 107 | void dqref(struct dquot *); | |
108 | void dqrele(struct vnode *, struct dquot *); | 108 | void dqrele(struct vnode *, struct dquot *); | |
109 | void dqflush(struct vnode *); | 109 | void dqflush(struct vnode *); | |
110 | 110 | |||
111 | int chkdq1(struct inode *, int64_t, kauth_cred_t, int); | 111 | int chkdq1(struct inode *, int64_t, kauth_cred_t, int); | |
112 | int chkiq1(struct inode *, int32_t, kauth_cred_t, int); | 112 | int chkiq1(struct inode *, int32_t, kauth_cred_t, int); | |
113 | int q1sync(struct mount *); | 113 | int q1sync(struct mount *); | |
114 | int dq1get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *); | 114 | int dq1get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *); | |
115 | int dq1sync(struct vnode *, struct dquot *); | 115 | int dq1sync(struct vnode *, struct dquot *); | |
116 | int quota1_handle_cmd_get(struct ufsmount *, int, int, int, | 116 | int quota1_handle_cmd_get(struct ufsmount *, int, int, int, int, | |
117 | struct quotaval *, struct quotaval *); | 117 | struct quotaval *); | |
118 | int quota1_handle_cmd_set(struct ufsmount *, int, int, int, prop_dictionary_t); | 118 | int quota1_handle_cmd_set(struct ufsmount *, int, int, int, prop_dictionary_t); | |
119 | int quota1_handle_cmd_quotaon(struct lwp *, struct ufsmount *, int, | 119 | int quota1_handle_cmd_quotaon(struct lwp *, struct ufsmount *, int, | |
120 | const char *); | 120 | const char *); | |
121 | int quota1_handle_cmd_quotaoff(struct lwp *, struct ufsmount *, int); | 121 | int quota1_handle_cmd_quotaoff(struct lwp *, struct ufsmount *, int); | |
122 | 122 | |||
123 | int chkdq2(struct inode *, int64_t, kauth_cred_t, int); | 123 | int chkdq2(struct inode *, int64_t, kauth_cred_t, int); | |
124 | int chkiq2(struct inode *, int32_t, kauth_cred_t, int); | 124 | int chkiq2(struct inode *, int32_t, kauth_cred_t, int); | |
125 | int quota2_handle_cmd_get(struct ufsmount *, int, int, int, | 125 | int quota2_handle_cmd_get(struct ufsmount *, int, int, int, int, | |
126 | struct quotaval *, struct quotaval *); | 126 | struct quotaval *); | |
127 | int quota2_handle_cmd_set(struct ufsmount *, int, int, int, prop_dictionary_t); | 127 | int quota2_handle_cmd_set(struct ufsmount *, int, int, int, prop_dictionary_t); | |
128 | int quota2_handle_cmd_clear(struct ufsmount *, int, int, int, prop_dictionary_t); | 128 | int quota2_handle_cmd_clear(struct ufsmount *, int, int, int, prop_dictionary_t); | |
129 | int quota2_handle_cmd_getall(struct ufsmount *, int, prop_array_t); | 129 | int quota2_handle_cmd_getall(struct ufsmount *, int, prop_array_t); | |
130 | int q2sync(struct mount *); | 130 | int q2sync(struct mount *); | |
131 | int dq2get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *); | 131 | int dq2get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *); | |
132 | int dq2sync(struct vnode *, struct dquot *); | 132 | int dq2sync(struct vnode *, struct dquot *); |
--- src/sys/ufs/ufs/ufs_quota1.c 2012/01/29 06:38:24 1.8
+++ src/sys/ufs/ufs/ufs_quota1.c 2012/01/29 06:40:57 1.9
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota1.c,v 1.8 2012/01/29 06:38:24 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota1.c,v 1.9 2012/01/29 06:40:57 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | 4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Robert Elz at The University of Melbourne. | 8 | * Robert Elz at The University of Melbourne. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -25,27 +25,27 @@ | @@ -25,27 +25,27 @@ | |||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | * | 33 | * | |
34 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | 34 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.8 2012/01/29 06:38:24 dholland Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.9 2012/01/29 06:40:57 dholland Exp $"); | |
39 | 39 | |||
40 | #include <sys/param.h> | 40 | #include <sys/param.h> | |
41 | #include <sys/kernel.h> | 41 | #include <sys/kernel.h> | |
42 | #include <sys/systm.h> | 42 | #include <sys/systm.h> | |
43 | #include <sys/namei.h> | 43 | #include <sys/namei.h> | |
44 | #include <sys/file.h> | 44 | #include <sys/file.h> | |
45 | #include <sys/proc.h> | 45 | #include <sys/proc.h> | |
46 | #include <sys/vnode.h> | 46 | #include <sys/vnode.h> | |
47 | #include <sys/mount.h> | 47 | #include <sys/mount.h> | |
48 | #include <sys/kauth.h> | 48 | #include <sys/kauth.h> | |
49 | 49 | |||
50 | #include <quota/quotaprop.h> | 50 | #include <quota/quotaprop.h> | |
51 | #include <ufs/ufs/quota1.h> | 51 | #include <ufs/ufs/quota1.h> | |
@@ -484,58 +484,67 @@ again: | @@ -484,58 +484,67 @@ again: | |||
484 | if (ump->um_quotas[i] != NULLVP) | 484 | if (ump->um_quotas[i] != NULLVP) | |
485 | break; | 485 | break; | |
486 | ump->umq1_qflags[type] &= ~QTF_CLOSING; | 486 | ump->umq1_qflags[type] &= ~QTF_CLOSING; | |
487 | cv_broadcast(&dqcv); | 487 | cv_broadcast(&dqcv); | |
488 | mutex_exit(&dqlock); | 488 | mutex_exit(&dqlock); | |
489 | kauth_cred_free(cred); | 489 | kauth_cred_free(cred); | |
490 | if (i == MAXQUOTAS) | 490 | if (i == MAXQUOTAS) | |
491 | mp->mnt_flag &= ~MNT_QUOTA; | 491 | mp->mnt_flag &= ~MNT_QUOTA; | |
492 | return (error); | 492 | return (error); | |
493 | } | 493 | } | |
494 | 494 | |||
495 | int | 495 | int | |
496 | quota1_handle_cmd_get(struct ufsmount *ump, int idtype, int id, | 496 | quota1_handle_cmd_get(struct ufsmount *ump, int idtype, int id, | |
497 | int defaultq, struct quotaval *blocks, struct quotaval *files) | 497 | int defaultq, int objtype, struct quotaval *ret) | |
498 | { | 498 | { | |
499 | struct dquot *dq; | 499 | struct dquot *dq; | |
500 | int error; | 500 | int error; | |
501 | uint64_t *valuesp[QUOTA_NLIMITS]; | 501 | struct quotaval blocks, files; | |
502 | ||||
503 | valuesp[QUOTA_LIMIT_BLOCK] = &blocks->qv_hardlimit; | |||
504 | valuesp[QUOTA_LIMIT_FILE] = &files->qv_hardlimit; | |||
505 | 502 | |||
506 | if (ump->um_quotas[idtype] == NULLVP) | 503 | if (ump->um_quotas[idtype] == NULLVP) | |
507 | return ENODEV; | 504 | return ENODEV; | |
508 | 505 | |||
509 | if (defaultq) { /* we want the grace period of id 0 */ | 506 | if (defaultq) { /* we want the grace period of id 0 */ | |
510 | if ((error = dqget(NULLVP, 0, ump, idtype, &dq)) != 0) | 507 | if ((error = dqget(NULLVP, 0, ump, idtype, &dq)) != 0) | |
511 | return error; | 508 | return error; | |
512 | 509 | |||
513 | } else { | 510 | } else { | |
514 | if ((error = dqget(NULLVP, id, ump, idtype, &dq)) != 0) | 511 | if ((error = dqget(NULLVP, id, ump, idtype, &dq)) != 0) | |
515 | return error; | 512 | return error; | |
516 | } | 513 | } | |
517 | dqblk_to_quotavals(&dq->dq_un.dq1_dqb, blocks, files); | 514 | dqblk_to_quotavals(&dq->dq_un.dq1_dqb, &blocks, &files); | |
518 | dqrele(NULLVP, dq); | 515 | dqrele(NULLVP, dq); | |
519 | if (defaultq) { | 516 | if (defaultq) { | |
520 | if (blocks->qv_expiretime > 0) | 517 | if (blocks.qv_expiretime > 0) | |
521 | blocks->qv_grace = blocks->qv_expiretime; | 518 | blocks.qv_grace = blocks.qv_expiretime; | |
522 | else | 519 | else | |
523 | blocks->qv_grace = MAX_DQ_TIME; | 520 | blocks.qv_grace = MAX_DQ_TIME; | |
524 | if (files->qv_expiretime > 0) | 521 | if (files.qv_expiretime > 0) | |
525 | files->qv_grace = files->qv_expiretime; | 522 | files.qv_grace = files.qv_expiretime; | |
526 | else | 523 | else | |
527 | files->qv_grace = MAX_DQ_TIME; | 524 | files.qv_grace = MAX_DQ_TIME; | |
528 | } | 525 | } | |
526 | ||||
527 | switch (objtype) { | |||
528 | case QUOTA_OBJTYPE_BLOCKS: | |||
529 | *ret = blocks; | |||
530 | break; | |||
531 | case QUOTA_OBJTYPE_FILES: | |||
532 | *ret = files; | |||
533 | break; | |||
534 | default: | |||
535 | return EINVAL; | |||
536 | } | |||
537 | ||||
529 | return 0; | 538 | return 0; | |
530 | } | 539 | } | |
531 | 540 | |||
532 | int | 541 | int | |
533 | quota1_handle_cmd_set(struct ufsmount *ump, int type, int id, | 542 | quota1_handle_cmd_set(struct ufsmount *ump, int type, int id, | |
534 | int defaultq, prop_dictionary_t data) | 543 | int defaultq, prop_dictionary_t data) | |
535 | { | 544 | { | |
536 | struct dquot *dq; | 545 | struct dquot *dq; | |
537 | struct dqblk dqb; | 546 | struct dqblk dqb; | |
538 | int error; | 547 | int error; | |
539 | uint64_t bval[2]; | 548 | uint64_t bval[2]; | |
540 | uint64_t ival[2]; | 549 | uint64_t ival[2]; | |
541 | const char *val_limitsonly_grace[] = {QUOTADICT_LIMIT_GTIME}; | 550 | const char *val_limitsonly_grace[] = {QUOTADICT_LIMIT_GTIME}; |
--- src/sys/ufs/ufs/ufs_quota2.c 2012/01/29 06:38:24 1.5
+++ src/sys/ufs/ufs/ufs_quota2.c 2012/01/29 06:40:58 1.6
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota2.c,v 1.5 2012/01/29 06:38:24 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota2.c,v 1.6 2012/01/29 06:40:58 dholland Exp $ */ | |
2 | /*- | 2 | /*- | |
3 | * Copyright (c) 2010 Manuel Bouyer | 3 | * Copyright (c) 2010 Manuel Bouyer | |
4 | * All rights reserved. | 4 | * All rights reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -16,27 +16,27 @@ | @@ -16,27 +16,27 @@ | |||
16 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 16 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
17 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 17 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
25 | * POSSIBILITY OF SUCH DAMAGE. | 25 | * POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.5 2012/01/29 06:38:24 dholland Exp $"); | 29 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.6 2012/01/29 06:40:58 dholland Exp $"); | |
30 | 30 | |||
31 | #include <sys/buf.h> | 31 | #include <sys/buf.h> | |
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/kernel.h> | 33 | #include <sys/kernel.h> | |
34 | #include <sys/systm.h> | 34 | #include <sys/systm.h> | |
35 | #include <sys/malloc.h> | 35 | #include <sys/malloc.h> | |
36 | #include <sys/namei.h> | 36 | #include <sys/namei.h> | |
37 | #include <sys/file.h> | 37 | #include <sys/file.h> | |
38 | #include <sys/proc.h> | 38 | #include <sys/proc.h> | |
39 | #include <sys/vnode.h> | 39 | #include <sys/vnode.h> | |
40 | #include <sys/mount.h> | 40 | #include <sys/mount.h> | |
41 | #include <sys/fstrans.h> | 41 | #include <sys/fstrans.h> | |
42 | #include <sys/kauth.h> | 42 | #include <sys/kauth.h> | |
@@ -67,28 +67,26 @@ static int getinoquota2(struct inode *, | @@ -67,28 +67,26 @@ static int getinoquota2(struct inode *, | |||
67 | struct quota2_entry **); | 67 | struct quota2_entry **); | |
68 | static int getq2h(struct ufsmount *, int, struct buf **, | 68 | static int getq2h(struct ufsmount *, int, struct buf **, | |
69 | struct quota2_header **, int); | 69 | struct quota2_header **, int); | |
70 | static int getq2e(struct ufsmount *, int, daddr_t, int, struct buf **, | 70 | static int getq2e(struct ufsmount *, int, daddr_t, int, struct buf **, | |
71 | struct quota2_entry **, int); | 71 | struct quota2_entry **, int); | |
72 | static int quota2_walk_list(struct ufsmount *, struct buf *, int, | 72 | static int quota2_walk_list(struct ufsmount *, struct buf *, int, | |
73 | uint64_t *, int, void *, | 73 | uint64_t *, int, void *, | |
74 | int (*func)(struct ufsmount *, uint64_t *, struct quota2_entry *, | 74 | int (*func)(struct ufsmount *, uint64_t *, struct quota2_entry *, | |
75 | uint64_t, void *)); | 75 | uint64_t, void *)); | |
76 | 76 | |||
77 | static int quota2_dict_update_q2e_limits(prop_dictionary_t, | 77 | static int quota2_dict_update_q2e_limits(prop_dictionary_t, | |
78 | struct quota2_entry *); | 78 | struct quota2_entry *); | |
79 | static prop_dictionary_t q2etoprop(struct quota2_entry *, int); | 79 | static prop_dictionary_t q2etoprop(struct quota2_entry *, int); | |
80 | static void q2e_to_quotavals(struct quota2_entry *, int, id_t *, | |||
81 | struct quotaval *, struct quotaval *); | |||
82 | 80 | |||
83 | static const char *limnames[] = INITQLNAMES; | 81 | static const char *limnames[] = INITQLNAMES; | |
84 | 82 | |||
85 | static int | 83 | static int | |
86 | quota2_dict_update_q2e_limits(prop_dictionary_t data, | 84 | quota2_dict_update_q2e_limits(prop_dictionary_t data, | |
87 | struct quota2_entry *q2e) | 85 | struct quota2_entry *q2e) | |
88 | { | 86 | { | |
89 | const char *val_limitsonly_names[] = INITQVNAMES_LIMITSONLY; | 87 | const char *val_limitsonly_names[] = INITQVNAMES_LIMITSONLY; | |
90 | 88 | |||
91 | int i, error; | 89 | int i, error; | |
92 | prop_dictionary_t val; | 90 | prop_dictionary_t val; | |
93 | 91 | |||
94 | for (i = 0; i < N_QL; i++) { | 92 | for (i = 0; i < N_QL; i++) { | |
@@ -149,38 +147,37 @@ q2val_to_quotaval(struct quota2_val *q2v | @@ -149,38 +147,37 @@ q2val_to_quotaval(struct quota2_val *q2v | |||
149 | { | 147 | { | |
150 | qv->qv_softlimit = q2v->q2v_softlimit; | 148 | qv->qv_softlimit = q2v->q2v_softlimit; | |
151 | qv->qv_hardlimit = q2v->q2v_hardlimit; | 149 | qv->qv_hardlimit = q2v->q2v_hardlimit; | |
152 | qv->qv_usage = q2v->q2v_cur; | 150 | qv->qv_usage = q2v->q2v_cur; | |
153 | qv->qv_expiretime = q2v->q2v_time; | 151 | qv->qv_expiretime = q2v->q2v_time; | |
154 | qv->qv_grace = q2v->q2v_grace; | 152 | qv->qv_grace = q2v->q2v_grace; | |
155 | } | 153 | } | |
156 | 154 | |||
157 | /* | 155 | /* | |
158 | * Convert a quota2entry and default-flag to the FS-independent | 156 | * Convert a quota2entry and default-flag to the FS-independent | |
159 | * representation. | 157 | * representation. | |
160 | */ | 158 | */ | |
161 | static void | 159 | static void | |
162 | q2e_to_quotavals(struct quota2_entry *q2e, int def, | 160 | q2e_to_quotaval(struct quota2_entry *q2e, int def, | |
163 | id_t *id, struct quotaval *blocks, struct quotaval *files) | 161 | id_t *id, int objtype, struct quotaval *ret) | |
164 | { | 162 | { | |
165 | if (def) { | 163 | if (def) { | |
166 | *id = QUOTA_DEFAULTID; | 164 | *id = QUOTA_DEFAULTID; | |
167 | } else { | 165 | } else { | |
168 | *id = q2e->q2e_uid; | 166 | *id = q2e->q2e_uid; | |
169 | } | 167 | } | |
170 | 168 | |||
171 | CTASSERT(N_QL == 2); | 169 | KASSERT(objtype >= 0 && objtype < N_QL); | |
172 | q2val_to_quotaval(&q2e->q2e_val[QL_BLOCK], blocks); | 170 | q2val_to_quotaval(&q2e->q2e_val[objtype], ret); | |
173 | q2val_to_quotaval(&q2e->q2e_val[QL_FILE], files); | |||
174 | } | 171 | } | |
175 | 172 | |||
176 | 173 | |||
177 | static int | 174 | static int | |
178 | quota2_bwrite(struct mount *mp, struct buf *bp) | 175 | quota2_bwrite(struct mount *mp, struct buf *bp) | |
179 | { | 176 | { | |
180 | if (mp->mnt_flag & MNT_SYNCHRONOUS) | 177 | if (mp->mnt_flag & MNT_SYNCHRONOUS) | |
181 | return bwrite(bp); | 178 | return bwrite(bp); | |
182 | else { | 179 | else { | |
183 | bdwrite(bp); | 180 | bdwrite(bp); | |
184 | return 0; | 181 | return 0; | |
185 | } | 182 | } | |
186 | } | 183 | } | |
@@ -847,27 +844,27 @@ quota2_array_add_q2e(struct ufsmount *um | @@ -847,27 +844,27 @@ quota2_array_add_q2e(struct ufsmount *um | |||
847 | mutex_exit(&dq->dq_interlock); | 844 | mutex_exit(&dq->dq_interlock); | |
848 | dqrele(NULLVP, dq); | 845 | dqrele(NULLVP, dq); | |
849 | 846 | |||
850 | dict = q2etoprop(&q2e, 0); | 847 | dict = q2etoprop(&q2e, 0); | |
851 | if (dict == NULL) | 848 | if (dict == NULL) | |
852 | return ENOMEM; | 849 | return ENOMEM; | |
853 | if (!prop_array_add_and_rel(replies, dict)) | 850 | if (!prop_array_add_and_rel(replies, dict)) | |
854 | return ENOMEM; | 851 | return ENOMEM; | |
855 | return 0; | 852 | return 0; | |
856 | } | 853 | } | |
857 | 854 | |||
858 | static int | 855 | static int | |
859 | quota2_fetch_q2e(struct ufsmount *ump, int type, | 856 | quota2_fetch_q2e(struct ufsmount *ump, int type, | |
860 | int id, struct quotaval *blocks, struct quotaval *files) | 857 | int id, int objtype, struct quotaval *ret) | |
861 | { | 858 | { | |
862 | struct dquot *dq; | 859 | struct dquot *dq; | |
863 | int error; | 860 | int error; | |
864 | struct quota2_entry *q2ep, q2e; | 861 | struct quota2_entry *q2ep, q2e; | |
865 | struct buf *bp; | 862 | struct buf *bp; | |
866 | const int needswap = UFS_MPNEEDSWAP(ump); | 863 | const int needswap = UFS_MPNEEDSWAP(ump); | |
867 | id_t id2; | 864 | id_t id2; | |
868 | 865 | |||
869 | error = dqget(NULLVP, id, ump, type, &dq); | 866 | error = dqget(NULLVP, id, ump, type, &dq); | |
870 | if (error) | 867 | if (error) | |
871 | return error; | 868 | return error; | |
872 | 869 | |||
873 | mutex_enter(&dq->dq_interlock); | 870 | mutex_enter(&dq->dq_interlock); | |
@@ -878,58 +875,71 @@ quota2_fetch_q2e(struct ufsmount *ump, i | @@ -878,58 +875,71 @@ quota2_fetch_q2e(struct ufsmount *ump, i | |||
878 | } | 875 | } | |
879 | error = getq2e(ump, type, dq->dq2_lblkno, dq->dq2_blkoff, | 876 | error = getq2e(ump, type, dq->dq2_lblkno, dq->dq2_blkoff, | |
880 | &bp, &q2ep, 0); | 877 | &bp, &q2ep, 0); | |
881 | if (error) { | 878 | if (error) { | |
882 | mutex_exit(&dq->dq_interlock); | 879 | mutex_exit(&dq->dq_interlock); | |
883 | dqrele(NULLVP, dq); | 880 | dqrele(NULLVP, dq); | |
884 | return error; | 881 | return error; | |
885 | } | 882 | } | |
886 | quota2_ufs_rwq2e(q2ep, &q2e, needswap); | 883 | quota2_ufs_rwq2e(q2ep, &q2e, needswap); | |
887 | brelse(bp, 0); | 884 | brelse(bp, 0); | |
888 | mutex_exit(&dq->dq_interlock); | 885 | mutex_exit(&dq->dq_interlock); | |
889 | dqrele(NULLVP, dq); | 886 | dqrele(NULLVP, dq); | |
890 | 887 | |||
891 | q2e_to_quotavals(&q2e, 0, &id2, blocks, files); | 888 | q2e_to_quotaval(&q2e, 0, &id2, objtype, ret); | |
892 | KASSERT(id2 == id); | 889 | KASSERT(id2 == id); | |
893 | return 0; | 890 | return 0; | |
894 | } | 891 | } | |
895 | 892 | |||
896 | int | 893 | int | |
897 | quota2_handle_cmd_get(struct ufsmount *ump, int type, int id, | 894 | quota2_handle_cmd_get(struct ufsmount *ump, int type, int id, | |
898 | int defaultq, struct quotaval *blocks, struct quotaval *files) | 895 | int defaultq, int objtype, struct quotaval *ret) | |
899 | { | 896 | { | |
900 | int error; | 897 | int error; | |
901 | struct quota2_header *q2h; | 898 | struct quota2_header *q2h; | |
902 | struct quota2_entry q2e; | 899 | struct quota2_entry q2e; | |
903 | struct buf *bp; | 900 | struct buf *bp; | |
904 | const int needswap = UFS_MPNEEDSWAP(ump); | 901 | const int needswap = UFS_MPNEEDSWAP(ump); | |
905 | id_t id2; | 902 | id_t id2; | |
906 | 903 | |||
904 | /* | |||
905 | * Make sure the FS-independent codes match the internal ones, | |||
906 | * so we can use the passed-in objtype without having to | |||
907 | * convert it explicitly to QL_BLOCK/QL_FILE. | |||
908 | */ | |||
909 | CTASSERT(QL_BLOCK == QUOTA_OBJTYPE_BLOCKS); | |||
910 | CTASSERT(QL_FILE == QUOTA_OBJTYPE_FILES); | |||
911 | CTASSERT(N_QL == 2); | |||
912 | ||||
913 | if (objtype < 0 || objtype >= N_QL) { | |||
914 | return EINVAL; | |||
915 | } | |||
916 | ||||
907 | if (ump->um_quotas[type] == NULLVP) | 917 | if (ump->um_quotas[type] == NULLVP) | |
908 | return ENODEV; | 918 | return ENODEV; | |
909 | if (defaultq) { | 919 | if (defaultq) { | |
910 | mutex_enter(&dqlock); | 920 | mutex_enter(&dqlock); | |
911 | error = getq2h(ump, type, &bp, &q2h, 0); | 921 | error = getq2h(ump, type, &bp, &q2h, 0); | |
912 | if (error) { | 922 | if (error) { | |
913 | mutex_exit(&dqlock); | 923 | mutex_exit(&dqlock); | |
914 | return error; | 924 | return error; | |
915 | } | 925 | } | |
916 | quota2_ufs_rwq2e(&q2h->q2h_defentry, &q2e, needswap); | 926 | quota2_ufs_rwq2e(&q2h->q2h_defentry, &q2e, needswap); | |
917 | mutex_exit(&dqlock); | 927 | mutex_exit(&dqlock); | |
918 | brelse(bp, 0); | 928 | brelse(bp, 0); | |
919 | q2e_to_quotavals(&q2e, defaultq, &id2, blocks, files); | 929 | q2e_to_quotaval(&q2e, defaultq, &id2, objtype, ret); | |
920 | (void)id2; | 930 | (void)id2; | |
921 | } else | 931 | } else | |
922 | error = quota2_fetch_q2e(ump, type, id, blocks, files); | 932 | error = quota2_fetch_q2e(ump, type, id, objtype, ret); | |
923 | 933 | |||
924 | return error; | 934 | return error; | |
925 | } | 935 | } | |
926 | 936 | |||
927 | struct getuids { | 937 | struct getuids { | |
928 | long nuids; /* number of uids in array */ | 938 | long nuids; /* number of uids in array */ | |
929 | long size; /* size of array */ | 939 | long size; /* size of array */ | |
930 | uid_t *uids; /* array of uids, dynamically allocated */ | 940 | uid_t *uids; /* array of uids, dynamically allocated */ | |
931 | }; | 941 | }; | |
932 | 942 | |||
933 | static int | 943 | static int | |
934 | quota2_getuids_callback(struct ufsmount *ump, uint64_t *offp, | 944 | quota2_getuids_callback(struct ufsmount *ump, uint64_t *offp, | |
935 | struct quota2_entry *q2ep, uint64_t off, void *v) | 945 | struct quota2_entry *q2ep, uint64_t off, void *v) |