1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #define DEBUG_SUBSYSTEM S_LQUOTA
39 #include <linux/version.h>
40 #include <lprocfs_status.h>
42 #include <linux/seq_file.h>
43 #include <lustre_fsfilt.h>
45 #include "quota_internal.h"
47 #ifdef HAVE_QUOTA_SUPPORT
50 int lprocfs_quota_rd_bunit(char *page, char **start, off_t off, int count,
53 struct obd_device *obd = (struct obd_device *)data;
56 return snprintf(page, count, "%lu\n",
57 obd->u.obt.obt_qctxt.lqc_bunit_sz);
59 EXPORT_SYMBOL(lprocfs_quota_rd_bunit);
61 int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
62 unsigned long count, void *data)
64 struct obd_device *obd = (struct obd_device *)data;
68 rc = lprocfs_write_helper(buffer, count, &val);
72 if (val % QUOTABLOCK_SIZE ||
73 val <= obd->u.obt.obt_qctxt.lqc_btune_sz)
76 obd->u.obt.obt_qctxt.lqc_bunit_sz = val;
79 EXPORT_SYMBOL(lprocfs_quota_wr_bunit);
81 int lprocfs_quota_rd_btune(char *page, char **start, off_t off, int count,
84 struct obd_device *obd = (struct obd_device *)data;
87 return snprintf(page, count, "%lu\n",
88 obd->u.obt.obt_qctxt.lqc_btune_sz);
90 EXPORT_SYMBOL(lprocfs_quota_rd_btune);
92 int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
93 unsigned long count, void *data)
95 struct obd_device *obd = (struct obd_device *)data;
99 rc = lprocfs_write_helper(buffer, count, &val);
103 if (val <= QUOTABLOCK_SIZE * MIN_QLIMIT || val % QUOTABLOCK_SIZE ||
104 val >= obd->u.obt.obt_qctxt.lqc_bunit_sz)
107 obd->u.obt.obt_qctxt.lqc_btune_sz = val;
110 EXPORT_SYMBOL(lprocfs_quota_wr_btune);
112 int lprocfs_quota_rd_iunit(char *page, char **start, off_t off, int count,
113 int *eof, void *data)
115 struct obd_device *obd = (struct obd_device *)data;
116 LASSERT(obd != NULL);
118 return snprintf(page, count, "%lu\n",
119 obd->u.obt.obt_qctxt.lqc_iunit_sz);
121 EXPORT_SYMBOL(lprocfs_quota_rd_iunit);
123 int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
124 unsigned long count, void *data)
126 struct obd_device *obd = (struct obd_device *)data;
128 LASSERT(obd != NULL);
130 rc = lprocfs_write_helper(buffer, count, &val);
134 if (val <= obd->u.obt.obt_qctxt.lqc_itune_sz)
137 obd->u.obt.obt_qctxt.lqc_iunit_sz = val;
140 EXPORT_SYMBOL(lprocfs_quota_wr_iunit);
142 int lprocfs_quota_rd_itune(char *page, char **start, off_t off, int count,
143 int *eof, void *data)
145 struct obd_device *obd = (struct obd_device *)data;
146 LASSERT(obd != NULL);
148 return snprintf(page, count, "%lu\n",
149 obd->u.obt.obt_qctxt.lqc_itune_sz);
151 EXPORT_SYMBOL(lprocfs_quota_rd_itune);
153 int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
154 unsigned long count, void *data)
156 struct obd_device *obd = (struct obd_device *)data;
158 LASSERT(obd != NULL);
160 rc = lprocfs_write_helper(buffer, count, &val);
164 if (val <= MIN_QLIMIT ||
165 val >= obd->u.obt.obt_qctxt.lqc_iunit_sz)
168 obd->u.obt.obt_qctxt.lqc_itune_sz = val;
171 EXPORT_SYMBOL(lprocfs_quota_wr_itune);
174 #define GROUP_QUOTA 2
176 #define MAX_STYPE_SIZE 5
178 /* The following information about CURRENT quotas is expected on the output:
179 * MDS: u for user quotas (administrative+operational) turned on,
180 * g for group quotas (administrative+operational) turned on,
181 * 1 for 32-bit operational quotas and 32-bit administrative quotas,
182 * 2 for 32-bit operational quotas and 64-bit administrative quotas,
183 * 3 for 64-bit operational quotas and 64-bit administrative quotas
184 * OST: u for user quotas (operational) turned on,
185 * g for group quotas (operational) turned on,
186 * 1 for 32-bit local operational quotas,
187 * 3 for 64-bit local operational quotas,
188 * Permanent parameters can be read with lctl (?)
190 int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
191 int *eof, void *data)
193 struct obd_device *obd = (struct obd_device *)data;
194 char stype[MAX_STYPE_SIZE + 1] = "";
195 int oq_type, rc, is_mds;
196 lustre_quota_version_t aq_version, oq_version;
197 struct obd_device_target *obt;
199 LASSERT(obd != NULL);
202 is_mds = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME);
204 /* Collect the needed information */
205 oq_type = obd->u.obt.obt_qctxt.lqc_flags;
207 rc = mds_quota_get_version(obd, &aq_version, &oq_version);
211 oq_version = obt->obt_qfmt;
214 /* Transform the collected data into a user-readable string */
215 if (oq_type & LQC_USRQUOTA_FLAG)
217 if (oq_type & LQC_GRPQUOTA_FLAG)
220 if ((!is_mds || aq_version == LUSTRE_QUOTA_V1) &&
221 oq_version == LUSTRE_QUOTA_V1)
224 else if ((!is_mds || aq_version == LUSTRE_QUOTA_V2) &&
225 oq_version == LUSTRE_QUOTA_V2)
228 else if (is_mds && aq_version == LUSTRE_QUOTA_V2 &&
229 oq_version == LUSTRE_QUOTA_V1)
234 return snprintf(page, count, "%s\n", stype);
236 EXPORT_SYMBOL(lprocfs_quota_rd_type);
239 * generic_quota_on is very lazy and tolerant about current quota settings
240 * @global means to turn on quotas on each OST additionally to local quotas;
241 * should not be called from filter_quota_ctl on MDS nodes (as it starts
242 * admin quotas on MDS nodes).
244 int generic_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl, int global)
246 struct obd_device_target *obt = &obd->u.obt;
247 struct lvfs_run_ctxt saved;
248 int id, is_master, rc = 0, local; /* means we need a local quotaon */
250 if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
251 CDEBUG(D_INFO, "other people are doing quotacheck\n");
252 atomic_inc(&obt->obt_quotachecking);
256 id = UGQUOTA2LQC(oqctl->qc_type);
257 local = (obt->obt_qctxt.lqc_flags & id) != id;
259 oqctl->qc_cmd = Q_QUOTAON;
260 oqctl->qc_id = obt->obt_qfmt;
262 is_master= !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME);
263 if (is_master && local) {
264 down(&obd->u.mds.mds_qonoff_sem);
265 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
266 /* turn on cluster wide quota */
267 rc = mds_admin_quota_on(obd, oqctl);
268 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
269 if (rc && rc != -ENOENT)
270 CERROR("%s: %s admin quotaon failed. rc=%d\n",
271 obd->obd_name, global ? "global" : "local", rc);
276 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
277 /* turn on local quota */
278 rc = fsfilt_quotactl(obd, obt->obt_sb, oqctl);
279 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
282 CERROR("%s: %s quotaon failed with"
283 " rc=%d\n", obd->obd_name,
284 global ? "global" : "local", rc);
286 obt->obt_qctxt.lqc_flags |= UGQUOTA2LQC(oqctl->qc_type);
290 if (rc == 0 && global && is_master)
291 rc = obd_quotactl(obd->u.mds.mds_lov_exp, oqctl);
295 up(&obd->u.mds.mds_qonoff_sem);
297 atomic_inc(&obt->obt_quotachecking);
302 static int auto_quota_on(struct obd_device *obd, int type)
304 struct obd_quotactl *oqctl;
308 LASSERT(type == USRQUOTA || type == GRPQUOTA || type == UGQUOTA);
310 OBD_ALLOC_PTR(oqctl);
314 oqctl->qc_type = type;
316 rc = generic_quota_on(obd, oqctl, 0);
322 static int filter_quota_set_version(struct obd_device *obd,
323 lustre_quota_version_t version)
325 struct obd_device_target *obt = &obd->u.obt;
327 if (version != LUSTRE_QUOTA_V1) {
329 if (version != LUSTRE_QUOTA_V2)
334 if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
335 CDEBUG(D_INFO, "other people are doing quotacheck\n");
336 atomic_inc(&obt->obt_quotachecking);
340 /* do not complain of being busy if we actually have nothing to do */
341 if (obt->obt_qfmt != version) {
342 if (obt->obt_qctxt.lqc_flags&(LQC_USRQUOTA_FLAG|LQC_GRPQUOTA_FLAG)){
343 atomic_inc(&obt->obt_quotachecking);
346 obt->obt_qfmt = version;
349 atomic_inc(&obt->obt_quotachecking);
354 /* The following settings of CURRENT quotas is expected on the input:
355 * MDS: u for user quotas (administrative+operational) turned on,
356 * g for group quotas (administrative+operational) turned on,
357 * 1 for 32-bit operational quotas and 32-bit administrative quotas,
358 * 2 for 32-bit operational quotas and 64-bit administrative quotas,
359 * 3 for 64-bit operational quotas and 64-bit administrative quotas
360 * OST: u for user quotas (operational) turned on,
361 * g for group quotas (operational) turned on,
362 * 1 for 32-bit local operational quotas,
363 * 2 for 32-bit local operational quotas,
364 * 3 for 64-bit local operational quotas,
365 * Permanent parameters can be set with lctl/tunefs
367 int lprocfs_quota_wr_type(struct file *file, const char *buffer,
368 unsigned long count, void *data)
370 struct obd_device *obd = (struct obd_device *)data;
371 struct obd_device_target *obt;
372 int type = 0, is_mds, idx;
374 char stype[MAX_STYPE_SIZE + 1] = "";
375 static const lustre_quota_version_t s2av[3] = {LUSTRE_QUOTA_V1,
378 s2ov[3] = {LUSTRE_QUOTA_V1,
381 LASSERT(obd != NULL);
385 is_mds = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME);
387 if (count > MAX_STYPE_SIZE)
390 if (copy_from_user(stype, buffer, count))
393 for (i = 0 ; i < count ; i++) {
403 /* quota version specifiers */
407 idx = stype[i] - '1';
409 if (s2ov[idx] == LUSTRE_QUOTA_V2)
413 rc = mds_quota_set_version(obd, s2av[idx],
416 CDEBUG(D_QUOTA, "failed to set admin "
417 "quota to spec %c! %d\n",
422 rc = filter_quota_set_version(obd, s2ov[idx]);
424 CDEBUG(D_QUOTA, "failed to set op"
425 " quota to spec %c! %d\n",
431 default : /* just skip stray symbols like \n */
437 int rc = auto_quota_on(obd, type - 1);
441 else if (rc == -ENOENT)
442 CWARN("%s: quotaon failed because quota files don't "
443 "exist, please run quotacheck firstly\n",
445 else if (rc == -EALREADY)
446 CWARN("%s: quota is on already!\n", obd->obd_name);
453 EXPORT_SYMBOL(lprocfs_quota_wr_type);
455 int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off,
456 int count, int *eof, void *data)
458 struct obd_device *obd = (struct obd_device *)data;
459 LASSERT(obd != NULL);
461 return snprintf(page, count, "%d\n",
462 obd->u.obt.obt_qctxt.lqc_switch_seconds);
464 EXPORT_SYMBOL(lprocfs_quota_rd_switch_seconds);
466 int lprocfs_quota_wr_switch_seconds(struct file *file, const char *buffer,
467 unsigned long count, void *data)
469 struct obd_device *obd = (struct obd_device *)data;
471 LASSERT(obd != NULL);
473 rc = lprocfs_write_helper(buffer, count, &val);
480 obd->u.obt.obt_qctxt.lqc_switch_seconds = val;
483 EXPORT_SYMBOL(lprocfs_quota_wr_switch_seconds);
485 int lprocfs_quota_rd_sync_blk(char *page, char **start, off_t off,
486 int count, int *eof, void *data)
488 struct obd_device *obd = (struct obd_device *)data;
489 LASSERT(obd != NULL);
491 return snprintf(page, count, "%d\n",
492 obd->u.obt.obt_qctxt.lqc_sync_blk);
494 EXPORT_SYMBOL(lprocfs_quota_rd_sync_blk);
496 int lprocfs_quota_wr_sync_blk(struct file *file, const char *buffer,
497 unsigned long count, void *data)
499 struct obd_device *obd = (struct obd_device *)data;
501 LASSERT(obd != NULL);
503 rc = lprocfs_write_helper(buffer, count, &val);
510 obd->u.obt.obt_qctxt.lqc_sync_blk = val;
513 EXPORT_SYMBOL(lprocfs_quota_wr_sync_blk);
515 int lprocfs_quota_rd_switch_qs(char *page, char **start, off_t off,
516 int count, int *eof, void *data)
518 struct obd_device *obd = (struct obd_device *)data;
519 LASSERT(obd != NULL);
521 return snprintf(page, count, "changing qunit size is %s\n",
522 obd->u.obt.obt_qctxt.lqc_switch_qs ?
523 "enabled" : "disabled");
525 EXPORT_SYMBOL(lprocfs_quota_rd_switch_qs);
527 int lprocfs_quota_wr_switch_qs(struct file *file, const char *buffer,
528 unsigned long count, void *data)
530 struct obd_device *obd = (struct obd_device *)data;
532 LASSERT(obd != NULL);
534 rc = lprocfs_write_helper(buffer, count, &val);
539 obd->u.obt.obt_qctxt.lqc_switch_qs = 1;
541 obd->u.obt.obt_qctxt.lqc_switch_qs = 0;
545 EXPORT_SYMBOL(lprocfs_quota_wr_switch_qs);
547 int lprocfs_quota_rd_boundary_factor(char *page, char **start, off_t off,
548 int count, int *eof, void *data)
550 struct obd_device *obd = (struct obd_device *)data;
551 LASSERT(obd != NULL);
554 return snprintf(page, count, "%lu\n",
555 obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor);
557 EXPORT_SYMBOL(lprocfs_quota_rd_boundary_factor);
559 int lprocfs_quota_wr_boundary_factor(struct file *file, const char *buffer,
560 unsigned long count, void *data)
562 struct obd_device *obd = (struct obd_device *)data;
564 LASSERT(obd != NULL);
566 rc = lprocfs_write_helper(buffer, count, &val);
573 obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor = val;
576 EXPORT_SYMBOL(lprocfs_quota_wr_boundary_factor);
578 int lprocfs_quota_rd_least_bunit(char *page, char **start, off_t off,
579 int count, int *eof, void *data)
581 struct obd_device *obd = (struct obd_device *)data;
582 LASSERT(obd != NULL);
585 return snprintf(page, count, "%lu\n",
586 obd->u.obt.obt_qctxt.lqc_cqs_least_bunit);
588 EXPORT_SYMBOL(lprocfs_quota_rd_least_bunit);
590 int lprocfs_quota_wr_least_bunit(struct file *file, const char *buffer,
591 unsigned long count, void *data)
593 struct obd_device *obd = (struct obd_device *)data;
595 LASSERT(obd != NULL);
597 rc = lprocfs_write_helper(buffer, count, &val);
601 if (val < PTLRPC_MAX_BRW_SIZE ||
602 val >= obd->u.obt.obt_qctxt.lqc_bunit_sz)
605 obd->u.obt.obt_qctxt.lqc_cqs_least_bunit = val;
608 EXPORT_SYMBOL(lprocfs_quota_wr_least_bunit);
610 int lprocfs_quota_rd_least_iunit(char *page, char **start, off_t off,
611 int count, int *eof, void *data)
613 struct obd_device *obd = (struct obd_device *)data;
614 LASSERT(obd != NULL);
617 return snprintf(page, count, "%lu\n",
618 obd->u.obt.obt_qctxt.lqc_cqs_least_iunit);
620 EXPORT_SYMBOL(lprocfs_quota_rd_least_iunit);
622 int lprocfs_quota_wr_least_iunit(struct file *file, const char *buffer,
623 unsigned long count, void *data)
625 struct obd_device *obd = (struct obd_device *)data;
627 LASSERT(obd != NULL);
629 rc = lprocfs_write_helper(buffer, count, &val);
633 if (val < 1 || val >= obd->u.obt.obt_qctxt.lqc_iunit_sz)
636 obd->u.obt.obt_qctxt.lqc_cqs_least_iunit = val;
639 EXPORT_SYMBOL(lprocfs_quota_wr_least_iunit);
641 int lprocfs_quota_rd_qs_factor(char *page, char **start, off_t off,
642 int count, int *eof, void *data)
644 struct obd_device *obd = (struct obd_device *)data;
645 LASSERT(obd != NULL);
648 return snprintf(page, count, "%lu\n",
649 obd->u.obt.obt_qctxt.lqc_cqs_qs_factor);
651 EXPORT_SYMBOL(lprocfs_quota_rd_qs_factor);
653 int lprocfs_quota_wr_qs_factor(struct file *file, const char *buffer,
654 unsigned long count, void *data)
656 struct obd_device *obd = (struct obd_device *)data;
658 LASSERT(obd != NULL);
660 rc = lprocfs_write_helper(buffer, count, &val);
667 obd->u.obt.obt_qctxt.lqc_cqs_qs_factor = val;
670 EXPORT_SYMBOL(lprocfs_quota_wr_qs_factor);
672 struct lprocfs_vars lprocfs_quota_common_vars[] = {
673 { "quota_bunit_sz", lprocfs_quota_rd_bunit,
674 lprocfs_quota_wr_bunit, 0},
675 { "quota_btune_sz", lprocfs_quota_rd_btune,
676 lprocfs_quota_wr_btune, 0},
677 { "quota_iunit_sz", lprocfs_quota_rd_iunit,
678 lprocfs_quota_wr_iunit, 0},
679 { "quota_itune_sz", lprocfs_quota_rd_itune,
680 lprocfs_quota_wr_itune, 0},
681 { "quota_type", lprocfs_quota_rd_type,
682 lprocfs_quota_wr_type, 0},
683 { "quota_switch_seconds", lprocfs_quota_rd_switch_seconds,
684 lprocfs_quota_wr_switch_seconds, 0 },
685 { "quota_sync_blk", lprocfs_quota_rd_sync_blk,
686 lprocfs_quota_wr_sync_blk, 0},
690 struct lprocfs_vars lprocfs_quota_master_vars[] = {
691 { "quota_switch_qs", lprocfs_quota_rd_switch_qs,
692 lprocfs_quota_wr_switch_qs, 0 },
693 { "quota_boundary_factor", lprocfs_quota_rd_boundary_factor,
694 lprocfs_quota_wr_boundary_factor, 0 },
695 { "quota_least_bunit", lprocfs_quota_rd_least_bunit,
696 lprocfs_quota_wr_least_bunit, 0 },
697 { "quota_least_iunit", lprocfs_quota_rd_least_iunit,
698 lprocfs_quota_wr_least_iunit, 0 },
699 { "quota_qs_factor", lprocfs_quota_rd_qs_factor,
700 lprocfs_quota_wr_qs_factor, 0 },
704 int lquota_proc_setup(struct obd_device *obd, int is_master)
706 struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
710 LASSERT(lquota_type_proc_dir && obd);
711 qctxt->lqc_proc_dir = lprocfs_register(obd->obd_name,
712 lquota_type_proc_dir,
713 lprocfs_quota_common_vars, obd);
714 if (IS_ERR(qctxt->lqc_proc_dir)) {
715 rc = PTR_ERR(qctxt->lqc_proc_dir);
716 CERROR("%s: error %d setting up lprocfs\n",
718 qctxt->lqc_proc_dir = NULL;
723 rc = lprocfs_add_vars(qctxt->lqc_proc_dir,
724 lprocfs_quota_master_vars, obd);
726 CERROR("%s: error %d setting up lprocfs for "
727 "quota master\n", obd->obd_name, rc);
728 GOTO(out_free_proc, rc);
732 qctxt->lqc_stats = lprocfs_alloc_stats(LQUOTA_LAST_STAT -
733 LQUOTA_FIRST_STAT, 0);
734 if (!qctxt->lqc_stats)
735 GOTO(out_free_proc, rc = -ENOMEM);
737 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_SYNC_ACQ,
738 LPROCFS_CNTR_AVGMINMAX, "sync_acq_req", "us");
739 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_SYNC_REL,
740 LPROCFS_CNTR_AVGMINMAX, "sync_rel_req", "us");
741 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ASYNC_ACQ,
742 LPROCFS_CNTR_AVGMINMAX, "async_acq_req", "us");
743 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ASYNC_REL,
744 LPROCFS_CNTR_AVGMINMAX, "async_rel_req", "us");
746 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_CHK_BLK,
747 LPROCFS_CNTR_AVGMINMAX,
748 "wait_for_blk_quota(lquota_chkquota)", "us");
749 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_CHK_INO,
750 LPROCFS_CNTR_AVGMINMAX,
751 "wait_for_ino_quota(lquota_chkquota)", "us");
752 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_COMMIT_BLK,
753 LPROCFS_CNTR_AVGMINMAX,
754 "wait_for_blk_quota(lquota_pending_commit)",
756 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_COMMIT_INO,
757 LPROCFS_CNTR_AVGMINMAX,
758 "wait_for_ino_quota(lquota_pending_commit)",
761 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_PENDING_BLK_QUOTA,
762 LPROCFS_CNTR_AVGMINMAX,
763 "wait_for_pending_blk_quota_req"
764 "(qctxt_wait_pending_dqacq)", "us");
765 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_PENDING_INO_QUOTA,
766 LPROCFS_CNTR_AVGMINMAX,
767 "wait_for_pending_ino_quota_req"
768 "(qctxt_wait_pending_dqacq)", "us");
769 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_NOWAIT_PENDING_BLK_QUOTA,
770 LPROCFS_CNTR_AVGMINMAX,
771 "nowait_for_pending_blk_quota_req"
772 "(qctxt_wait_pending_dqacq)", "us");
773 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_NOWAIT_PENDING_INO_QUOTA,
774 LPROCFS_CNTR_AVGMINMAX,
775 "nowait_for_pending_ino_quota_req"
776 "(qctxt_wait_pending_dqacq)", "us");
778 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_QUOTA_CTL,
779 LPROCFS_CNTR_AVGMINMAX, "quota_ctl", "us");
780 lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ADJUST_QUNIT,
781 LPROCFS_CNTR_AVGMINMAX, "adjust_qunit", "us");
783 lprocfs_register_stats(qctxt->lqc_proc_dir, "stats", qctxt->lqc_stats);
788 lprocfs_remove(&qctxt->lqc_proc_dir);
793 int lquota_proc_cleanup(struct lustre_quota_ctxt *qctxt)
795 if (!qctxt || !qctxt->lqc_proc_dir)
798 if (qctxt->lqc_stats != NULL)
799 lprocfs_free_stats(&qctxt->lqc_stats);
801 lprocfs_remove(&qctxt->lqc_proc_dir);