Pass only one objtype and its quotaval to QUOTACTL_SET at one time. (The backend code to handle this is a lot tidier than I expected given that the proplib code doesn't allow setting blocks and files independently; I was afraid there would turn out to be a reason for that...) Note: this change requires a kernel version bump.diff -r1.12 -r1.13 src/sys/kern/vfs_quotactl.c
(dholland)
--- src/sys/kern/vfs_quotactl.c 2012/01/29 06:45:25 1.12
+++ src/sys/kern/vfs_quotactl.c 2012/01/29 06:47:38 1.13
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vfs_quotactl.c,v 1.12 2012/01/29 06:45:25 dholland Exp $ */ | 1 | /* $NetBSD: vfs_quotactl.c,v 1.13 2012/01/29 06:47:38 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.12 2012/01/29 06:45:25 dholland Exp $"); | 83 | __KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.13 2012/01/29 06:47:38 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; | |
@@ -369,50 +369,63 @@ vfs_quotactl_set(struct mount *mp, | @@ -369,50 +369,63 @@ vfs_quotactl_set(struct mount *mp, | |||
369 | KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY); | 369 | KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY); | |
370 | 370 | |||
371 | replies = prop_array_create(); | 371 | replies = prop_array_create(); | |
372 | if (replies == NULL) | 372 | if (replies == NULL) | |
373 | return ENOMEM; | 373 | return ENOMEM; | |
374 | 374 | |||
375 | iter = prop_array_iterator(datas); | 375 | iter = prop_array_iterator(datas); | |
376 | if (iter == NULL) { | 376 | if (iter == NULL) { | |
377 | prop_object_release(replies); | 377 | prop_object_release(replies); | |
378 | return ENOMEM; | 378 | return ENOMEM; | |
379 | } | 379 | } | |
380 | 380 | |||
381 | while ((data = prop_object_iterator_next(iter)) != NULL) { | 381 | while ((data = prop_object_iterator_next(iter)) != NULL) { | |
382 | ||||
383 | KASSERT(prop_object_type(data) == PROP_TYPE_DICTIONARY); | |||
384 | ||||
382 | if (!prop_dictionary_get_uint32(data, "id", &id)) { | 385 | if (!prop_dictionary_get_uint32(data, "id", &id)) { | |
383 | if (!prop_dictionary_get_cstring_nocopy(data, "id", | 386 | if (!prop_dictionary_get_cstring_nocopy(data, "id", | |
384 | &idstr)) | 387 | &idstr)) | |
385 | continue; | 388 | continue; | |
386 | if (strcmp(idstr, "default")) | 389 | if (strcmp(idstr, "default")) | |
387 | continue; | 390 | continue; | |
388 | id = 0; | 391 | id = 0; | |
389 | defaultq = 1; | 392 | defaultq = 1; | |
390 | } else { | 393 | } else { | |
391 | defaultq = 0; | 394 | defaultq = 0; | |
392 | } | 395 | } | |
393 | 396 | |||
394 | error = vfs_quotactl_set_extractinfo(data, &blocks, &files); | 397 | error = vfs_quotactl_set_extractinfo(data, &blocks, &files); | |
395 | if (error) { | 398 | if (error) { | |
396 | goto err; | 399 | goto err; | |
397 | } | 400 | } | |
398 | 401 | |||
399 | args.qc_type = QCT_SET; | 402 | args.qc_type = QCT_SET; | |
403 | args.u.set.qc_idtype = q2type; | |||
404 | args.u.set.qc_id = id; | |||
405 | args.u.set.qc_defaultq = defaultq; | |||
406 | args.u.set.qc_objtype = QUOTA_OBJTYPE_BLOCKS; | |||
407 | args.u.set.qc_val = &blocks; | |||
408 | error = VFS_QUOTACTL(mp, QUOTACTL_SET, &args); | |||
409 | if (error) { | |||
410 | goto err; | |||
411 | } | |||
412 | ||||
413 | args.qc_type = QCT_SET; | |||
414 | args.u.set.qc_idtype = q2type; | |||
400 | args.u.set.qc_id = id; | 415 | args.u.set.qc_id = id; | |
401 | args.u.set.qc_defaultq = defaultq; | 416 | args.u.set.qc_defaultq = defaultq; | |
402 | args.u.set.qc_q2type = q2type; | 417 | args.u.set.qc_objtype = QUOTA_OBJTYPE_FILES; | |
403 | args.u.set.qc_blocks = &blocks; | 418 | args.u.set.qc_val = &files; | |
404 | args.u.set.qc_files = &files; | |||
405 | args.u.set.qc_data = data; | |||
406 | error = VFS_QUOTACTL(mp, QUOTACTL_SET, &args); | 419 | error = VFS_QUOTACTL(mp, QUOTACTL_SET, &args); | |
407 | if (error) { | 420 | if (error) { | |
408 | goto err; | 421 | goto err; | |
409 | } | 422 | } | |
410 | } | 423 | } | |
411 | prop_object_iterator_release(iter); | 424 | prop_object_iterator_release(iter); | |
412 | if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) { | 425 | if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) { | |
413 | error = ENOMEM; | 426 | error = ENOMEM; | |
414 | } else { | 427 | } else { | |
415 | error = 0; | 428 | error = 0; | |
416 | } | 429 | } | |
417 | return error; | 430 | return error; | |
418 | err: | 431 | err: |
--- src/sys/sys/quotactl.h 2012/01/29 06:45:26 1.10
+++ src/sys/sys/quotactl.h 2012/01/29 06:47:38 1.11
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: quotactl.h,v 1.10 2012/01/29 06:45:26 dholland Exp $ */ | 1 | /* $NetBSD: quotactl.h,v 1.11 2012/01/29 06:47:38 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 | |
@@ -59,24 +59,23 @@ struct vfs_quotactl_args { | @@ -59,24 +59,23 @@ struct vfs_quotactl_args { | |||
59 | struct { | 59 | struct { | |
60 | prop_dictionary_t qc_cmddict; | 60 | prop_dictionary_t qc_cmddict; | |
61 | int qc_q2type; | 61 | int qc_q2type; | |
62 | prop_array_t qc_datas; | 62 | prop_array_t qc_datas; | |
63 | } proplib; | 63 | } proplib; | |
64 | struct { | 64 | struct { | |
65 | int *qc_version_ret; | 65 | int *qc_version_ret; | |
66 | } getversion; | 66 | } getversion; | |
67 | struct { | 67 | struct { | |
68 | const struct quotakey *qc_key; | 68 | const struct quotakey *qc_key; | |
69 | struct quotaval *qc_ret; | 69 | struct quotaval *qc_ret; | |
70 | } get; | 70 | } get; | |
71 | struct { | 71 | struct { | |
72 | int qc_idtype; | |||
72 | id_t qc_id; | 73 | id_t qc_id; | |
73 | int qc_defaultq; | 74 | int qc_defaultq; | |
74 | int qc_q2type; | 75 | int qc_objtype; | |
75 | const struct quotaval *qc_blocks; | 76 | const struct quotaval *qc_val; | |
76 | const struct quotaval *qc_files; | |||
77 | prop_dictionary_t qc_data; | |||
78 | } set; | 77 | } set; | |
79 | } u; | 78 | } u; | |
80 | }; | 79 | }; | |
81 | 80 | |||
82 | #endif /* _SYS_QUOTACTL_H_ */ | 81 | #endif /* _SYS_QUOTACTL_H_ */ |
--- src/sys/ufs/ufs/ufs_quota.c 2012/01/29 06:46:49 1.82
+++ src/sys/ufs/ufs/ufs_quota.c 2012/01/29 06:47:38 1.83
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota.c,v 1.82 2012/01/29 06:46:49 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota.c,v 1.83 2012/01/29 06:47:38 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.82 2012/01/29 06:46:49 dholland Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.83 2012/01/29 06:47:38 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> | |
@@ -258,63 +258,59 @@ quota_handle_cmd_get(struct mount *mp, s | @@ -258,63 +258,59 @@ quota_handle_cmd_get(struct mount *mp, s | |||
258 | panic("quota_handle_cmd_get: no support ?"); | 258 | panic("quota_handle_cmd_get: no support ?"); | |
259 | 259 | |||
260 | if (error != 0) | 260 | if (error != 0) | |
261 | return error; | 261 | return error; | |
262 | 262 | |||
263 | return error; | 263 | return error; | |
264 | } | 264 | } | |
265 | 265 | |||
266 | static int | 266 | static int | |
267 | quota_handle_cmd_set(struct mount *mp, struct lwp *l, | 267 | quota_handle_cmd_set(struct mount *mp, struct lwp *l, | |
268 | struct vfs_quotactl_args *args) | 268 | struct vfs_quotactl_args *args) | |
269 | { | 269 | { | |
270 | struct ufsmount *ump = VFSTOUFS(mp); | 270 | struct ufsmount *ump = VFSTOUFS(mp); | |
271 | int idtype; | |||
271 | id_t id; | 272 | id_t id; | |
272 | int defaultq; | 273 | int defaultq; | |
273 | int q2type; | 274 | int objtype; | |
274 | const struct quotaval *blocks; | 275 | const struct quotaval *qv; | |
275 | const struct quotaval *files; | |||
276 | prop_dictionary_t data; | |||
277 | int error; | 276 | int error; | |
278 | 277 | |||
279 | KASSERT(args->qc_type == QCT_SET); | 278 | KASSERT(args->qc_type == QCT_SET); | |
279 | idtype = args->u.set.qc_idtype; | |||
280 | id = args->u.set.qc_id; | 280 | id = args->u.set.qc_id; | |
281 | defaultq = args->u.set.qc_defaultq; | 281 | defaultq = args->u.set.qc_defaultq; | |
282 | q2type = args->u.set.qc_q2type; | 282 | objtype = args->u.set.qc_objtype; | |
283 | blocks = args->u.set.qc_blocks; | 283 | qv = args->u.set.qc_val; | |
284 | files = args->u.set.qc_files; | |||
285 | data = args->u.set.qc_data; | |||
286 | ||||
287 | KASSERT(prop_object_type(data) == PROP_TYPE_DICTIONARY); | |||
288 | 284 | |||
289 | if ((ump->um_flags & (UFS_QUOTA|UFS_QUOTA2)) == 0) | 285 | if ((ump->um_flags & (UFS_QUOTA|UFS_QUOTA2)) == 0) | |
290 | return EOPNOTSUPP; | 286 | return EOPNOTSUPP; | |
291 | 287 | |||
292 | /* avoid whitespace changes */ | 288 | /* avoid whitespace changes */ | |
293 | { | 289 | { | |
294 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | 290 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | |
295 | KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE, mp, KAUTH_ARG(id), NULL); | 291 | KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE, mp, KAUTH_ARG(id), NULL); | |
296 | if (error != 0) | 292 | if (error != 0) | |
297 | goto err; | 293 | goto err; | |
298 | #ifdef QUOTA | 294 | #ifdef QUOTA | |
299 | if (ump->um_flags & UFS_QUOTA) | 295 | if (ump->um_flags & UFS_QUOTA) | |
300 | error = quota1_handle_cmd_set(ump, q2type, id, defaultq, | 296 | error = quota1_handle_cmd_set(ump, idtype, id, defaultq, | |
301 | blocks, files); | 297 | objtype, qv); | |
302 | else | 298 | else | |
303 | #endif | 299 | #endif | |
304 | #ifdef QUOTA2 | 300 | #ifdef QUOTA2 | |
305 | if (ump->um_flags & UFS_QUOTA2) { | 301 | if (ump->um_flags & UFS_QUOTA2) { | |
306 | error = quota2_handle_cmd_set(ump, q2type, id, defaultq, | 302 | error = quota2_handle_cmd_set(ump, idtype, id, defaultq, | |
307 | blocks, files); | 303 | objtype, qv); | |
308 | } else | 304 | } else | |
309 | #endif | 305 | #endif | |
310 | panic("quota_handle_cmd_get: no support ?"); | 306 | panic("quota_handle_cmd_get: no support ?"); | |
311 | 307 | |||
312 | if (error && error != ENOENT) | 308 | if (error && error != ENOENT) | |
313 | goto err; | 309 | goto err; | |
314 | } | 310 | } | |
315 | 311 | |||
316 | return 0; | 312 | return 0; | |
317 | err: | 313 | err: | |
318 | return error; | 314 | return error; | |
319 | } | 315 | } | |
320 | 316 |
--- src/sys/ufs/ufs/ufs_quota.h 2012/01/29 06:46:50 1.7
+++ src/sys/ufs/ufs/ufs_quota.h 2012/01/29 06:47:38 1.8
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota.h,v 1.7 2012/01/29 06:46:50 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota.h,v 1.8 2012/01/29 06:47:38 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. | |
@@ -105,30 +105,30 @@ const char *quotatypes[MAXQUOTAS]; | @@ -105,30 +105,30 @@ const char *quotatypes[MAXQUOTAS]; | |||
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 *, const struct quotakey *, | 116 | int quota1_handle_cmd_get(struct ufsmount *, const struct quotakey *, | |
117 | struct quotaval *); | 117 | struct quotaval *); | |
118 | int quota1_handle_cmd_set(struct ufsmount *, int, int, int, | 118 | int quota1_handle_cmd_set(struct ufsmount *, int, int, int, int, | |
119 | const struct quotaval *, const struct quotaval *); | 119 | const struct quotaval *); | |
120 | int quota1_handle_cmd_quotaon(struct lwp *, struct ufsmount *, int, | 120 | int quota1_handle_cmd_quotaon(struct lwp *, struct ufsmount *, int, | |
121 | const char *); | 121 | const char *); | |
122 | int quota1_handle_cmd_quotaoff(struct lwp *, struct ufsmount *, int); | 122 | int quota1_handle_cmd_quotaoff(struct lwp *, struct ufsmount *, int); | |
123 | 123 | |||
124 | int chkdq2(struct inode *, int64_t, kauth_cred_t, int); | 124 | int chkdq2(struct inode *, int64_t, kauth_cred_t, int); | |
125 | int chkiq2(struct inode *, int32_t, kauth_cred_t, int); | 125 | int chkiq2(struct inode *, int32_t, kauth_cred_t, int); | |
126 | int quota2_handle_cmd_get(struct ufsmount *, const struct quotakey *, | 126 | int quota2_handle_cmd_get(struct ufsmount *, const struct quotakey *, | |
127 | struct quotaval *); | 127 | struct quotaval *); | |
128 | int quota2_handle_cmd_set(struct ufsmount *, int, int, int, | 128 | int quota2_handle_cmd_set(struct ufsmount *, int, int, int, int, | |
129 | const struct quotaval *, const struct quotaval *); | 129 | const struct quotaval *); | |
130 | int quota2_handle_cmd_clear(struct ufsmount *, int, int, int, prop_dictionary_t); | 130 | int quota2_handle_cmd_clear(struct ufsmount *, int, int, int, prop_dictionary_t); | |
131 | int quota2_handle_cmd_getall(struct ufsmount *, int, prop_array_t); | 131 | int quota2_handle_cmd_getall(struct ufsmount *, int, prop_array_t); | |
132 | int q2sync(struct mount *); | 132 | int q2sync(struct mount *); | |
133 | int dq2get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *); | 133 | int dq2get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *); | |
134 | int dq2sync(struct vnode *, struct dquot *); | 134 | int dq2sync(struct vnode *, struct dquot *); |
--- src/sys/ufs/ufs/ufs_quota1.c 2012/01/29 06:46:16 1.12
+++ src/sys/ufs/ufs/ufs_quota1.c 2012/01/29 06:47:38 1.13
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota1.c,v 1.12 2012/01/29 06:46:16 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota1.c,v 1.13 2012/01/29 06:47:38 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.12 2012/01/29 06:46:16 dholland Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.13 2012/01/29 06:47:38 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> | |
@@ -543,89 +543,106 @@ quota1_handle_cmd_get(struct ufsmount *u | @@ -543,89 +543,106 @@ quota1_handle_cmd_get(struct ufsmount *u | |||
543 | return 0; | 543 | return 0; | |
544 | } | 544 | } | |
545 | 545 | |||
546 | static uint32_t | 546 | static uint32_t | |
547 | quota1_encode_limit(uint64_t lim) | 547 | quota1_encode_limit(uint64_t lim) | |
548 | { | 548 | { | |
549 | if (lim == QUOTA_NOLIMIT || lim >= 0xffffffff) { | 549 | if (lim == QUOTA_NOLIMIT || lim >= 0xffffffff) { | |
550 | return 0; | 550 | return 0; | |
551 | } | 551 | } | |
552 | return lim; | 552 | return lim; | |
553 | } | 553 | } | |
554 | 554 | |||
555 | int | 555 | int | |
556 | quota1_handle_cmd_set(struct ufsmount *ump, int type, int id, | 556 | quota1_handle_cmd_set(struct ufsmount *ump, int idtype, int id, | |
557 | int defaultq, const struct quotaval *blocks, const struct quotaval *files) | 557 | int defaultq, int objtype, const struct quotaval *val) | |
558 | { | 558 | { | |
559 | struct dquot *dq; | 559 | struct dquot *dq; | |
560 | struct dqblk dqb; | 560 | struct dqblk dqb; | |
561 | int error; | 561 | int error; | |
562 | 562 | |||
563 | if (ump->um_quotas[type] == NULLVP) | 563 | switch (objtype) { | |
564 | case QUOTA_OBJTYPE_BLOCKS: | |||
565 | case QUOTA_OBJTYPE_FILES: | |||
566 | break; | |||
567 | default: | |||
568 | return EINVAL; | |||
569 | } | |||
570 | ||||
571 | if (ump->um_quotas[idtype] == NULLVP) | |||
564 | return ENODEV; | 572 | return ENODEV; | |
565 | 573 | |||
566 | if (defaultq) { | 574 | if (defaultq) { | |
567 | /* just update grace times */ | 575 | /* just update grace times */ | |
568 | KASSERT(id == 0); | 576 | KASSERT(id == 0); | |
569 | if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0) | 577 | if ((error = dqget(NULLVP, id, ump, idtype, &dq)) != 0) | |
570 | return error; | 578 | return error; | |
571 | mutex_enter(&dq->dq_interlock); | 579 | mutex_enter(&dq->dq_interlock); | |
572 | if (blocks->qv_grace > 0) | 580 | if (objtype == QUOTA_OBJTYPE_BLOCKS && val->qv_grace > 0) | |
573 | ump->umq1_btime[type] = dq->dq_btime = | 581 | ump->umq1_btime[idtype] = dq->dq_btime = | |
574 | blocks->qv_grace; | 582 | val->qv_grace; | |
575 | if (files->qv_grace > 0) | 583 | if (objtype == QUOTA_OBJTYPE_FILES && val->qv_grace > 0) | |
576 | ump->umq1_itime[type] = dq->dq_itime = | 584 | ump->umq1_itime[idtype] = dq->dq_itime = | |
577 | files->qv_grace; | 585 | val->qv_grace; | |
578 | mutex_exit(&dq->dq_interlock); | 586 | mutex_exit(&dq->dq_interlock); | |
579 | dq->dq_flags |= DQ_MOD; | 587 | dq->dq_flags |= DQ_MOD; | |
580 | dqrele(NULLVP, dq); | 588 | dqrele(NULLVP, dq); | |
581 | return 0; | 589 | return 0; | |
582 | } | 590 | } | |
583 | 591 | |||
584 | if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0) | 592 | if ((error = dqget(NULLVP, id, ump, idtype, &dq)) != 0) | |
585 | return (error); | 593 | return (error); | |
586 | mutex_enter(&dq->dq_interlock); | 594 | mutex_enter(&dq->dq_interlock); | |
587 | /* | 595 | /* | |
588 | * Copy all but the current values. | 596 | * Copy all but the current values. | |
589 | * Reset time limit if previously had no soft limit or were | 597 | * Reset time limit if previously had no soft limit or were | |
590 | * under it, but now have a soft limit and are over it. | 598 | * under it, but now have a soft limit and are over it. | |
591 | */ | 599 | */ | |
592 | dqb.dqb_curblocks = dq->dq_curblocks; | 600 | dqb.dqb_curblocks = dq->dq_curblocks; | |
593 | dqb.dqb_curinodes = dq->dq_curinodes; | 601 | dqb.dqb_curinodes = dq->dq_curinodes; | |
594 | dqb.dqb_btime = dq->dq_btime; | 602 | dqb.dqb_btime = dq->dq_btime; | |
595 | dqb.dqb_itime = dq->dq_itime; | 603 | dqb.dqb_itime = dq->dq_itime; | |
596 | dqb.dqb_bsoftlimit = quota1_encode_limit(blocks->qv_softlimit); | 604 | switch (objtype) { | |
597 | dqb.dqb_bhardlimit = quota1_encode_limit(blocks->qv_hardlimit); | 605 | case QUOTA_OBJTYPE_BLOCKS: | |
598 | dqb.dqb_isoftlimit = quota1_encode_limit(files->qv_softlimit); | 606 | dqb.dqb_bsoftlimit = quota1_encode_limit(val->qv_softlimit); | |
599 | dqb.dqb_ihardlimit = quota1_encode_limit(files->qv_hardlimit); | 607 | dqb.dqb_bhardlimit = quota1_encode_limit(val->qv_hardlimit); | |
600 | if (dq->dq_id == 0) { | 608 | dqb.dqb_isoftlimit = dq->dq_isoftlimit; | |
609 | dqb.dqb_ihardlimit = dq->dq_ihardlimit; | |||
610 | break; | |||
611 | case QUOTA_OBJTYPE_FILES: | |||
612 | dqb.dqb_bsoftlimit = dq->dq_bsoftlimit; | |||
613 | dqb.dqb_bhardlimit = dq->dq_bhardlimit; | |||
614 | dqb.dqb_isoftlimit = quota1_encode_limit(val->qv_softlimit); | |||
615 | dqb.dqb_ihardlimit = quota1_encode_limit(val->qv_hardlimit); | |||
616 | break; | |||
617 | } | |||
618 | if (dq->dq_id == 0 && val->qv_grace != QUOTA_NOTIME) { | |||
601 | /* also update grace time if available */ | 619 | /* also update grace time if available */ | |
602 | if (blocks->qv_grace != QUOTA_NOTIME) { | 620 | if (objtype == QUOTA_OBJTYPE_BLOCKS) { | |
603 | ump->umq1_btime[type] = dqb.dqb_btime = | 621 | ump->umq1_btime[idtype] = dqb.dqb_btime = val->qv_grace; | |
604 | blocks->qv_grace; | 622 | ||
605 | } | 623 | } | |
606 | if (files->qv_grace != QUOTA_NOTIME) { | 624 | if (objtype == QUOTA_OBJTYPE_FILES) { | |
607 | ump->umq1_itime[type] = dqb.dqb_itime = | 625 | ump->umq1_itime[idtype] = dqb.dqb_itime = val->qv_grace; | |
608 | files->qv_grace; | |||
609 | } | 626 | } | |
610 | } | 627 | } | |
611 | if (dqb.dqb_bsoftlimit && | 628 | if (dqb.dqb_bsoftlimit && | |
612 | dq->dq_curblocks >= dqb.dqb_bsoftlimit && | 629 | dq->dq_curblocks >= dqb.dqb_bsoftlimit && | |
613 | (dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit)) | 630 | (dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit)) | |
614 | dqb.dqb_btime = time_second + ump->umq1_btime[type]; | 631 | dqb.dqb_btime = time_second + ump->umq1_btime[idtype]; | |
615 | if (dqb.dqb_isoftlimit && | 632 | if (dqb.dqb_isoftlimit && | |
616 | dq->dq_curinodes >= dqb.dqb_isoftlimit && | 633 | dq->dq_curinodes >= dqb.dqb_isoftlimit && | |
617 | (dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit)) | 634 | (dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit)) | |
618 | dqb.dqb_itime = time_second + ump->umq1_itime[type]; | 635 | dqb.dqb_itime = time_second + ump->umq1_itime[idtype]; | |
619 | dq->dq_un.dq1_dqb = dqb; | 636 | dq->dq_un.dq1_dqb = dqb; | |
620 | if (dq->dq_curblocks < dq->dq_bsoftlimit) | 637 | if (dq->dq_curblocks < dq->dq_bsoftlimit) | |
621 | dq->dq_flags &= ~DQ_WARN(QL_BLOCK); | 638 | dq->dq_flags &= ~DQ_WARN(QL_BLOCK); | |
622 | if (dq->dq_curinodes < dq->dq_isoftlimit) | 639 | if (dq->dq_curinodes < dq->dq_isoftlimit) | |
623 | dq->dq_flags &= ~DQ_WARN(QL_FILE); | 640 | dq->dq_flags &= ~DQ_WARN(QL_FILE); | |
624 | if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 && | 641 | if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 && | |
625 | dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0) | 642 | dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0) | |
626 | dq->dq_flags |= DQ_FAKE; | 643 | dq->dq_flags |= DQ_FAKE; | |
627 | else | 644 | else | |
628 | dq->dq_flags &= ~DQ_FAKE; | 645 | dq->dq_flags &= ~DQ_FAKE; | |
629 | dq->dq_flags |= DQ_MOD; | 646 | dq->dq_flags |= DQ_MOD; | |
630 | mutex_exit(&dq->dq_interlock); | 647 | mutex_exit(&dq->dq_interlock); | |
631 | dqrele(NULLVP, dq); | 648 | dqrele(NULLVP, dq); |
--- src/sys/ufs/ufs/ufs_quota2.c 2012/01/29 06:46:50 1.8
+++ src/sys/ufs/ufs/ufs_quota2.c 2012/01/29 06:47:38 1.9
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota2.c,v 1.8 2012/01/29 06:46:50 dholland Exp $ */ | 1 | /* $NetBSD: ufs_quota2.c,v 1.9 2012/01/29 06:47:38 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.8 2012/01/29 06:46:50 dholland Exp $"); | 29 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.9 2012/01/29 06:47:38 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> | |
@@ -69,37 +69,36 @@ static int getq2h(struct ufsmount *, int | @@ -69,37 +69,36 @@ static int getq2h(struct ufsmount *, int | |||
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 prop_dictionary_t q2etoprop(struct quota2_entry *, int); | 77 | static prop_dictionary_t q2etoprop(struct quota2_entry *, int); | |
78 | 78 | |||
79 | static const char *limnames[] = INITQLNAMES; | 79 | static const char *limnames[] = INITQLNAMES; | |
80 | 80 | |||
81 | static void | 81 | static void | |
82 | quota2_dict_update_q2e_limits(const struct quotaval *blocks, | 82 | quota2_dict_update_q2e_limits(int objtype, const struct quotaval *val, | |
83 | const struct quotaval *files, | |||
84 | struct quota2_entry *q2e) | 83 | struct quota2_entry *q2e) | |
85 | { | 84 | { | |
86 | q2e->q2e_val[QL_BLOCK].q2v_hardlimit = blocks->qv_hardlimit; | 85 | /* make sure we can index q2e_val[] by the fs-independent objtype */ | |
87 | q2e->q2e_val[QL_BLOCK].q2v_softlimit = blocks->qv_softlimit; | 86 | CTASSERT(QUOTA_OBJTYPE_BLOCKS == QL_BLOCK); | |
88 | q2e->q2e_val[QL_BLOCK].q2v_grace = blocks->qv_grace; | 87 | CTASSERT(QUOTA_OBJTYPE_FILES == QL_FILE); | |
89 | 88 | |||
90 | q2e->q2e_val[QL_FILE].q2v_hardlimit = blocks->qv_hardlimit; | 89 | q2e->q2e_val[objtype].q2v_hardlimit = val->qv_hardlimit; | |
91 | q2e->q2e_val[QL_FILE].q2v_softlimit = blocks->qv_softlimit; | 90 | q2e->q2e_val[objtype].q2v_softlimit = val->qv_softlimit; | |
92 | q2e->q2e_val[QL_FILE].q2v_grace = blocks->qv_grace; | 91 | q2e->q2e_val[objtype].q2v_grace = val->qv_grace; | |
93 | } | 92 | } | |
94 | 93 | |||
95 | static prop_dictionary_t | 94 | static prop_dictionary_t | |
96 | q2etoprop(struct quota2_entry *q2e, int def) | 95 | q2etoprop(struct quota2_entry *q2e, int def) | |
97 | { | 96 | { | |
98 | const char *val_names[] = INITQVNAMES_ALL; | 97 | const char *val_names[] = INITQVNAMES_ALL; | |
99 | prop_dictionary_t dict1 = prop_dictionary_create(); | 98 | prop_dictionary_t dict1 = prop_dictionary_create(); | |
100 | prop_dictionary_t dict2; | 99 | prop_dictionary_t dict2; | |
101 | int i; | 100 | int i; | |
102 | 101 | |||
103 | if (dict1 == NULL) | 102 | if (dict1 == NULL) | |
104 | return NULL; | 103 | return NULL; | |
105 | 104 | |||
@@ -603,75 +602,75 @@ int | @@ -603,75 +602,75 @@ int | |||
603 | chkdq2(struct inode *ip, int64_t change, kauth_cred_t cred, int flags) | 602 | chkdq2(struct inode *ip, int64_t change, kauth_cred_t cred, int flags) | |
604 | { | 603 | { | |
605 | return quota2_check(ip, QL_BLOCK, change, cred, flags); | 604 | return quota2_check(ip, QL_BLOCK, change, cred, flags); | |
606 | } | 605 | } | |
607 | 606 | |||
608 | int | 607 | int | |
609 | chkiq2(struct inode *ip, int32_t change, kauth_cred_t cred, int flags) | 608 | chkiq2(struct inode *ip, int32_t change, kauth_cred_t cred, int flags) | |
610 | { | 609 | { | |
611 | return quota2_check(ip, QL_FILE, change, cred, flags); | 610 | return quota2_check(ip, QL_FILE, change, cred, flags); | |
612 | } | 611 | } | |
613 | 612 | |||
614 | int | 613 | int | |
615 | quota2_handle_cmd_set(struct ufsmount *ump, int type, int id, | 614 | quota2_handle_cmd_set(struct ufsmount *ump, int type, int id, | |
616 | int defaultq, const struct quotaval *blocks, const struct quotaval *files) | 615 | int defaultq, int objtype, const struct quotaval *val) | |
617 | { | 616 | { | |
618 | int error; | 617 | int error; | |
619 | struct dquot *dq; | 618 | struct dquot *dq; | |
620 | struct quota2_header *q2h; | 619 | struct quota2_header *q2h; | |
621 | struct quota2_entry q2e, *q2ep; | 620 | struct quota2_entry q2e, *q2ep; | |
622 | struct buf *bp; | 621 | struct buf *bp; | |
623 | const int needswap = UFS_MPNEEDSWAP(ump); | 622 | const int needswap = UFS_MPNEEDSWAP(ump); | |
624 | 623 | |||
625 | if (ump->um_quotas[type] == NULLVP) | 624 | if (ump->um_quotas[type] == NULLVP) | |
626 | return ENODEV; | 625 | return ENODEV; | |
627 | error = UFS_WAPBL_BEGIN(ump->um_mountp); | 626 | error = UFS_WAPBL_BEGIN(ump->um_mountp); | |
628 | if (error) | 627 | if (error) | |
629 | return error; | 628 | return error; | |
630 | 629 | |||
631 | if (defaultq) { | 630 | if (defaultq) { | |
632 | mutex_enter(&dqlock); | 631 | mutex_enter(&dqlock); | |
633 | error = getq2h(ump, type, &bp, &q2h, B_MODIFY); | 632 | error = getq2h(ump, type, &bp, &q2h, B_MODIFY); | |
634 | if (error) { | 633 | if (error) { | |
635 | mutex_exit(&dqlock); | 634 | mutex_exit(&dqlock); | |
636 | goto out_wapbl; | 635 | goto out_wapbl; | |
637 | } | 636 | } | |
638 | quota2_ufs_rwq2e(&q2h->q2h_defentry, &q2e, needswap); | 637 | quota2_ufs_rwq2e(&q2h->q2h_defentry, &q2e, needswap); | |
639 | quota2_dict_update_q2e_limits(blocks, files, &q2e); | 638 | quota2_dict_update_q2e_limits(objtype, val, &q2e); | |
640 | quota2_ufs_rwq2e(&q2e, &q2h->q2h_defentry, needswap); | 639 | quota2_ufs_rwq2e(&q2e, &q2h->q2h_defentry, needswap); | |
641 | mutex_exit(&dqlock); | 640 | mutex_exit(&dqlock); | |
642 | quota2_bwrite(ump->um_mountp, bp); | 641 | quota2_bwrite(ump->um_mountp, bp); | |
643 | goto out_wapbl; | 642 | goto out_wapbl; | |
644 | } | 643 | } | |
645 | 644 | |||
646 | error = dqget(NULLVP, id, ump, type, &dq); | 645 | error = dqget(NULLVP, id, ump, type, &dq); | |
647 | if (error) | 646 | if (error) | |
648 | goto out_wapbl; | 647 | goto out_wapbl; | |
649 | 648 | |||
650 | mutex_enter(&dq->dq_interlock); | 649 | mutex_enter(&dq->dq_interlock); | |
651 | if (dq->dq2_lblkno == 0 && dq->dq2_blkoff == 0) { | 650 | if (dq->dq2_lblkno == 0 && dq->dq2_blkoff == 0) { | |
652 | /* need to alloc a new on-disk quot */ | 651 | /* need to alloc a new on-disk quot */ | |
653 | mutex_enter(&dqlock); | 652 | mutex_enter(&dqlock); | |
654 | error = quota2_q2ealloc(ump, type, id, dq, &bp, &q2ep); | 653 | error = quota2_q2ealloc(ump, type, id, dq, &bp, &q2ep); | |
655 | mutex_exit(&dqlock); | 654 | mutex_exit(&dqlock); | |
656 | } else { | 655 | } else { | |
657 | error = getq2e(ump, type, dq->dq2_lblkno, dq->dq2_blkoff, | 656 | error = getq2e(ump, type, dq->dq2_lblkno, dq->dq2_blkoff, | |
658 | &bp, &q2ep, B_MODIFY); | 657 | &bp, &q2ep, B_MODIFY); | |
659 | } | 658 | } | |
660 | if (error) | 659 | if (error) | |
661 | goto out_il; | 660 | goto out_il; | |
662 | 661 | |||
663 | quota2_ufs_rwq2e(q2ep, &q2e, needswap); | 662 | quota2_ufs_rwq2e(q2ep, &q2e, needswap); | |
664 | quota2_dict_update_q2e_limits(blocks, files, &q2e); | 663 | quota2_dict_update_q2e_limits(objtype, val, &q2e); | |
665 | quota2_ufs_rwq2e(&q2e, q2ep, needswap); | 664 | quota2_ufs_rwq2e(&q2e, q2ep, needswap); | |
666 | quota2_bwrite(ump->um_mountp, bp); | 665 | quota2_bwrite(ump->um_mountp, bp); | |
667 | 666 | |||
668 | out_il: | 667 | out_il: | |
669 | mutex_exit(&dq->dq_interlock); | 668 | mutex_exit(&dq->dq_interlock); | |
670 | dqrele(NULLVP, dq); | 669 | dqrele(NULLVP, dq); | |
671 | out_wapbl: | 670 | out_wapbl: | |
672 | UFS_WAPBL_END(ump->um_mountp); | 671 | UFS_WAPBL_END(ump->um_mountp); | |
673 | return error; | 672 | return error; | |
674 | } | 673 | } | |
675 | 674 | |||
676 | struct dq2clear_callback { | 675 | struct dq2clear_callback { | |
677 | uid_t id; | 676 | uid_t id; |