Sun Jan 29 07:06:37 2012 UTC ()
Rearrange result processing for QUOTACTL_GETALL.


(dholland)
diff -r1.25 -r1.26 src/sys/kern/vfs_quotactl.c

cvs diff -r1.25 -r1.26 src/sys/kern/vfs_quotactl.c (expand / switch to unified diff)

--- src/sys/kern/vfs_quotactl.c 2012/01/29 07:06:01 1.25
+++ src/sys/kern/vfs_quotactl.c 2012/01/29 07:06:37 1.26
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_quotactl.c,v 1.25 2012/01/29 07:06:01 dholland Exp $ */ 1/* $NetBSD: vfs_quotactl.c,v 1.26 2012/01/29 07:06:37 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.25 2012/01/29 07:06:01 dholland Exp $"); 83__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.26 2012/01/29 07:06:37 dholland Exp $");
84 84
85#include <sys/malloc.h> /* XXX: temporary */ 85#include <sys/malloc.h> /* XXX: temporary */
86#include <sys/mount.h> 86#include <sys/mount.h>
87#include <sys/quota.h> 87#include <sys/quota.h>
88#include <sys/quotactl.h> 88#include <sys/quotactl.h>
89#include <quota/quotaprop.h> 89#include <quota/quotaprop.h>
90 90
91static int 91static int
92vfs_quotactl_getversion(struct mount *mp, 92vfs_quotactl_getversion(struct mount *mp,
93 prop_dictionary_t cmddict, int q2type, 93 prop_dictionary_t cmddict, int q2type,
94 prop_array_t datas) 94 prop_array_t datas)
95{ 95{
96 prop_array_t replies; 96 prop_array_t replies;
@@ -429,101 +429,120 @@ vfs_quotactl_put(struct mount *mp, @@ -429,101 +429,120 @@ vfs_quotactl_put(struct mount *mp,
429 if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) { 429 if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) {
430 error = ENOMEM; 430 error = ENOMEM;
431 } else { 431 } else {
432 error = 0; 432 error = 0;
433 } 433 }
434 return error; 434 return error;
435err: 435err:
436 prop_object_iterator_release(iter); 436 prop_object_iterator_release(iter);
437 prop_object_release(replies); 437 prop_object_release(replies);
438 return error; 438 return error;
439} 439}
440 440
441static prop_dictionary_t 441static prop_dictionary_t
442vfs_quotactl_getall_makereply(id_t id, int def, 442vfs_quotactl_getall_makereply(const struct quotakey *key)
443 const struct quotaval *blocks, 443{
444 const struct quotaval *files) 444 prop_dictionary_t dict;
 445 id_t id;
 446 int defaultq;
 447
 448 dict = prop_dictionary_create();
 449 if (dict == NULL)
 450 return NULL;
 451
 452 id = key->qk_id;
 453 if (id == QUOTA_DEFAULTID) {
 454 id = 0;
 455 defaultq = 1;
 456 } else {
 457 defaultq = 0;
 458 }
 459
 460 if (defaultq) {
 461 if (!prop_dictionary_set_cstring_nocopy(dict, "id",
 462 "default")) {
 463 goto err;
 464 }
 465 } else {
 466 if (!prop_dictionary_set_uint32(dict, "id", id)) {
 467 goto err;
 468 }
 469 }
 470
 471 return dict;
 472
 473err:
 474 prop_object_release(dict);
 475 return NULL;
 476}
 477
 478static int
 479vfs_quotactl_getall_addreply(prop_dictionary_t thisreply,
 480 const struct quotakey *key, const struct quotaval *val)
445{ 481{
446#define INITQVNAMES_ALL { \ 482#define INITQVNAMES_ALL { \
447 QUOTADICT_LIMIT_HARD, \ 483 QUOTADICT_LIMIT_HARD, \
448 QUOTADICT_LIMIT_SOFT, \ 484 QUOTADICT_LIMIT_SOFT, \
449 QUOTADICT_LIMIT_USAGE, \ 485 QUOTADICT_LIMIT_USAGE, \
450 QUOTADICT_LIMIT_ETIME, \ 486 QUOTADICT_LIMIT_ETIME, \
451 QUOTADICT_LIMIT_GTIME \ 487 QUOTADICT_LIMIT_GTIME \
452 } 488 }
453#define N_QV 5 489#define N_QV 5
454 490
455 const char *val_names[] = INITQVNAMES_ALL; 491 const char *val_names[] = INITQVNAMES_ALL;
456 uint64_t vals[N_QV]; 492 uint64_t vals[N_QV];
457 prop_dictionary_t dict1 = prop_dictionary_create(); 
458 prop_dictionary_t dict2; 493 prop_dictionary_t dict2;
 494 const char *objtypename;
459 495
460 if (dict1 == NULL) 496 switch (key->qk_objtype) {
461 return NULL; 497 case QUOTA_OBJTYPE_BLOCKS:
462 498 objtypename = QUOTADICT_LTYPE_BLOCK;
463 if (def) { 499 break;
464 if (!prop_dictionary_set_cstring_nocopy(dict1, "id", 500 case QUOTA_OBJTYPE_FILES:
465 "default")) { 501 objtypename = QUOTADICT_LTYPE_FILE;
466 goto err; 502 break;
467 } 503 default:
468 } else { 504 return EINVAL;
469 if (!prop_dictionary_set_uint32(dict1, "id", id)) { 
470 goto err; 
471 } 
472 } 505 }
473 506
474 vals[0] = blocks->qv_hardlimit; 507 vals[0] = val->qv_hardlimit;
475 vals[1] = blocks->qv_softlimit; 508 vals[1] = val->qv_softlimit;
476 vals[2] = blocks->qv_usage; 509 vals[2] = val->qv_usage;
477 vals[3] = blocks->qv_expiretime; 510 vals[3] = val->qv_expiretime;
478 vals[4] = blocks->qv_grace; 511 vals[4] = val->qv_grace;
479 dict2 = limits64toprop(vals, val_names, N_QV); 
480 if (dict2 == NULL) 
481 goto err; 
482 if (!prop_dictionary_set_and_rel(dict1, QUOTADICT_LTYPE_BLOCK, dict2)) 
483 goto err; 
484 
485 
486 vals[0] = files->qv_hardlimit; 
487 vals[1] = files->qv_softlimit; 
488 vals[2] = files->qv_usage; 
489 vals[3] = files->qv_expiretime; 
490 vals[4] = files->qv_grace; 
491 dict2 = limits64toprop(vals, val_names, N_QV); 512 dict2 = limits64toprop(vals, val_names, N_QV);
492 if (dict2 == NULL) 513 if (dict2 == NULL)
493 goto err; 514 return ENOMEM;
494 if (!prop_dictionary_set_and_rel(dict1, QUOTADICT_LTYPE_FILE, dict2)) 
495 goto err; 
496 515
497 return dict1; 516 if (!prop_dictionary_set_and_rel(thisreply, objtypename, dict2))
 517 return ENOMEM;
498 518
499err: 519 return 0;
500 prop_object_release(dict1); 
501 return NULL; 
502} 520}
503 521
504static int 522static int
505vfs_quotactl_getall(struct mount *mp, 523vfs_quotactl_getall(struct mount *mp,
506 prop_dictionary_t cmddict, int q2type, 524 prop_dictionary_t cmddict, int q2type,
507 prop_array_t datas) 525 prop_array_t datas)
508{ 526{
509 struct quotakcursor cursor; 527 struct quotakcursor cursor;
510 struct quota_getall_result result; 528 struct quota_getall_result result;
511 struct vfs_quotactl_args args; 529 struct vfs_quotactl_args args;
512 prop_array_t replies; 530 prop_array_t replies;
513 prop_dictionary_t dict; 531 prop_dictionary_t thisreply;
 532 struct quotakey *key;
 533 struct quotaval *val;
 534 id_t lastid;
514 unsigned i; 535 unsigned i;
515 id_t id; 
516 int defaultq; 
517 int error, error2; 536 int error, error2;
518 int skip = 0; 537 int skip = 0;
519 538
520 KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY); 539 KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
521 540
522 args.qc_type = QCT_CURSOROPEN; 541 args.qc_type = QCT_CURSOROPEN;
523 args.u.cursoropen.qc_cursor = &cursor; 542 args.u.cursoropen.qc_cursor = &cursor;
524 error = VFS_QUOTACTL(mp, QUOTACTL_CURSOROPEN, &args); 543 error = VFS_QUOTACTL(mp, QUOTACTL_CURSOROPEN, &args);
525 if (error) { 544 if (error) {
526 return error; 545 return error;
527 } 546 }
528 547
529 result.qr_keys = NULL; 548 result.qr_keys = NULL;
@@ -551,43 +570,54 @@ vfs_quotactl_getall(struct mount *mp, @@ -551,43 +570,54 @@ vfs_quotactl_getall(struct mount *mp,
551 goto err; 570 goto err;
552 } 571 }
553 572
554 replies = prop_array_create(); 573 replies = prop_array_create();
555 if (replies == NULL) { 574 if (replies == NULL) {
556 error = ENOMEM; 575 error = ENOMEM;
557 goto err; 576 goto err;
558 } 577 }
559 578
560 if (skip) { 579 if (skip) {
561 goto skip; 580 goto skip;
562 } 581 }
563 582
564 for (i = 0; i < result.qr_num; i += 2) { 583 thisreply = NULL;
565 id = result.qr_keys[i].qk_id; 584 lastid = 0; /* value not actually referenced */
566 if (id == QUOTA_DEFAULTID) { 585 for (i = 0; i < result.qr_num; i++) {
567 id = 0; 586 key = &result.qr_keys[i];
568 defaultq = 1; 587 val = &result.qr_vals[i];
569 } else { 588
570 defaultq = 0; 589 if (thisreply == NULL || key->qk_id != lastid) {
571 } 590 lastid = key->qk_id;
572 dict = vfs_quotactl_getall_makereply(id, defaultq, 591 thisreply = vfs_quotactl_getall_makereply(key);
573 &result.qr_vals[i], 592 if (thisreply == NULL) {
574 &result.qr_vals[i+1]); 593 error = ENOMEM;
575 if (dict == NULL) { 594 goto err;
576 error = ENOMEM; 595 }
577 goto err; 596 /*
 597 * Note: while we release our reference to
 598 * thisreply here, we can (and do) continue to
 599 * use the pointer in the loop because the
 600 * copy attached to the replies array is not
 601 * going away.
 602 */
 603 if (!prop_array_add_and_rel(replies, thisreply)) {
 604 error = ENOMEM;
 605 goto err;
 606 }
578 } 607 }
579 if (!prop_array_add_and_rel(replies, dict)) { 608
580 error = ENOMEM; 609 error = vfs_quotactl_getall_addreply(thisreply, key, val);
 610 if (error) {
581 goto err; 611 goto err;
582 } 612 }
583 } 613 }
584 614
585skip: 615skip:
586 616
587 if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) { 617 if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) {
588 error = ENOMEM; 618 error = ENOMEM;
589 goto err; 619 goto err;
590 } 620 }
591 621
592 error = 0; 622 error = 0;
593 err: 623 err: