1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2003 Cluster File Systems, Inc.
5 * Author: Lai Siyao <lsy@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org/
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * A kernel module which tests the fsfilt quotactl API from the OBD setup function.
26 # define EXPORT_SYMTAB
28 #define DEBUG_SUBSYSTEM S_CLASS
30 #include <linux/module.h>
31 #include <linux/init.h>
33 #include <linux/obd_class.h>
34 #include <linux/lustre_fsfilt.h>
35 #include <linux/lustre_mds.h>
36 #include <linux/obd_ost.h>
38 char *test_quotafile[] = {"aquotactl.user", "aquotactl.group"};
41 static int quotactl_test_1(struct obd_device *obd, struct super_block *sb)
43 struct obd_quotactl oqctl;
47 oqctl.qc_cmd = Q_QUOTAON;
48 oqctl.qc_id = QFMT_LDISKFS;
49 oqctl.qc_type = UGQUOTA;
50 rc = fsfilt_quotactl(obd, sb, &oqctl);
52 CERROR("1a: quotactl Q_QUOTAON failed: %d\n", rc);
59 #if 0 /* set/getinfo not supported, this is for cluster-wide quotas */
60 /* Test set/getinfo */
61 static int quotactl_test_2(struct obd_device *obd, struct super_block *sb)
63 struct obd_quotactl oqctl;
67 oqctl.qc_cmd = Q_SETINFO;
68 oqctl.qc_type = USRQUOTA;
69 oqctl.qc_dqinfo.dqi_bgrace = 1616;
70 oqctl.qc_dqinfo.dqi_igrace = 2828;
71 oqctl.qc_dqinfo.dqi_flags = 0;
72 rc = fsfilt_quotactl(obd, sb, &oqctl);
74 CERROR("2a: quotactl Q_SETINFO failed: %d\n", rc);
78 oqctl.qc_cmd = Q_GETINFO;
79 oqctl.qc_type = USRQUOTA;
80 rc = fsfilt_quotactl(obd, sb, &oqctl);
82 CERROR("2b: quotactl Q_GETINFO failed: %d\n", rc);
85 if (oqctl.qc_dqinfo.dqi_bgrace != 1616 ||
86 oqctl.qc_dqinfo.dqi_igrace != 2828 ||
87 oqctl.qc_dqinfo.dqi_flags != 0) {
88 CERROR("2c: quotactl Q_GETINFO get wrong result: %d, %d, %d\n",
89 oqctl.qc_dqinfo.dqi_bgrace,
90 oqctl.qc_dqinfo.dqi_igrace,
91 oqctl.qc_dqinfo.dqi_flags);
99 /* Test set/getquota */
100 static int quotactl_test_3(struct obd_device *obd, struct super_block *sb)
102 struct obd_quotactl oqctl;
106 oqctl.qc_cmd = Q_SETQUOTA;
107 oqctl.qc_type = USRQUOTA;
109 oqctl.qc_dqblk.dqb_bhardlimit = 919;
110 oqctl.qc_dqblk.dqb_bsoftlimit = 818;
111 oqctl.qc_dqblk.dqb_ihardlimit = 616;
112 oqctl.qc_dqblk.dqb_isoftlimit = 515;
113 oqctl.qc_dqblk.dqb_valid = QIF_LIMITS;
114 rc = fsfilt_quotactl(obd, sb, &oqctl);
116 CERROR("3a: quotactl Q_SETQUOTA failed: %d\n", rc);
120 oqctl.qc_cmd = Q_GETQUOTA;
121 oqctl.qc_type = USRQUOTA;
123 rc = fsfilt_quotactl(obd, sb, &oqctl);
125 CERROR("3b: quotactl Q_SETQUOTA failed: %d\n", rc);
128 if (oqctl.qc_dqblk.dqb_bhardlimit != 919 ||
129 oqctl.qc_dqblk.dqb_bsoftlimit != 818 ||
130 oqctl.qc_dqblk.dqb_ihardlimit != 616 ||
131 oqctl.qc_dqblk.dqb_isoftlimit != 515) {
132 CERROR("3c: quotactl Q_GETQUOTA get wrong result:"
133 "%llu, %llu, %llu, %llu\n",
134 oqctl.qc_dqblk.dqb_bhardlimit,
135 oqctl.qc_dqblk.dqb_bsoftlimit,
136 oqctl.qc_dqblk.dqb_ihardlimit,
137 oqctl.qc_dqblk.dqb_isoftlimit);
141 oqctl.qc_cmd = Q_SETQUOTA;
142 oqctl.qc_type = USRQUOTA;
144 oqctl.qc_dqblk.dqb_curspace = 717;
145 oqctl.qc_dqblk.dqb_curinodes = 414;
146 oqctl.qc_dqblk.dqb_valid = QIF_USAGE;
147 rc = fsfilt_quotactl(obd, sb, &oqctl);
149 CERROR("3d: quotactl Q_SETQUOTA failed: %d\n", rc);
153 oqctl.qc_cmd = Q_GETQUOTA;
154 oqctl.qc_type = USRQUOTA;
156 rc = fsfilt_quotactl(obd, sb, &oqctl);
158 CERROR("3e: quotactl Q_SETQUOTA failed: %d\n", rc);
161 if (oqctl.qc_dqblk.dqb_curspace != 717 ||
162 oqctl.qc_dqblk.dqb_curinodes != 414) {
163 CERROR("3f: quotactl Q_GETQUOTA get wrong result: %llu, %llu\n",
164 oqctl.qc_dqblk.dqb_curspace,
165 oqctl.qc_dqblk.dqb_curinodes);
169 oqctl.qc_cmd = Q_SETQUOTA;
170 oqctl.qc_type = USRQUOTA;
171 oqctl.qc_dqblk.dqb_btime = 313;
172 oqctl.qc_dqblk.dqb_itime = 212;
174 oqctl.qc_dqblk.dqb_valid = QIF_TIMES;
175 rc = fsfilt_quotactl(obd, sb, &oqctl);
177 CERROR("3g: quotactl Q_SETQUOTA failed: %d\n", rc);
181 oqctl.qc_cmd = Q_GETQUOTA;
182 oqctl.qc_type = USRQUOTA;
184 rc = fsfilt_quotactl(obd, sb, &oqctl);
186 CERROR("3h: quotactl Q_SETQUOTA failed: %d\n", rc);
189 if (oqctl.qc_dqblk.dqb_btime != 313 ||
190 oqctl.qc_dqblk.dqb_itime != 212) {
191 CERROR("3i: quotactl Q_GETQUOTA get wrong result: %llu, %llu\n",
192 oqctl.qc_dqblk.dqb_btime,
193 oqctl.qc_dqblk.dqb_itime);
197 oqctl.qc_cmd = Q_SETQUOTA;
198 oqctl.qc_type = USRQUOTA;
200 oqctl.qc_dqblk.dqb_bhardlimit = 919;
201 oqctl.qc_dqblk.dqb_bsoftlimit = 818;
202 oqctl.qc_dqblk.dqb_curspace = 717;
203 oqctl.qc_dqblk.dqb_ihardlimit = 616;
204 oqctl.qc_dqblk.dqb_isoftlimit = 515;
205 oqctl.qc_dqblk.dqb_curinodes = 414;
206 oqctl.qc_dqblk.dqb_btime = 313;
207 oqctl.qc_dqblk.dqb_itime = 212;
208 oqctl.qc_dqblk.dqb_valid = QIF_ALL;
209 rc = fsfilt_quotactl(obd, sb, &oqctl);
211 CERROR("3j: quotactl Q_SETQUOTA failed: %d\n", rc);
215 oqctl.qc_cmd = Q_GETQUOTA;
216 oqctl.qc_type = USRQUOTA;
218 rc = fsfilt_quotactl(obd, sb, &oqctl);
220 CERROR("3k: quotactl Q_SETQUOTA failed: %d\n", rc);
223 if (oqctl.qc_dqblk.dqb_bhardlimit != 919 ||
224 oqctl.qc_dqblk.dqb_bsoftlimit != 818 ||
225 oqctl.qc_dqblk.dqb_ihardlimit != 616 ||
226 oqctl.qc_dqblk.dqb_isoftlimit != 515 ||
227 oqctl.qc_dqblk.dqb_curspace != 717 ||
228 oqctl.qc_dqblk.dqb_curinodes != 414 ||
229 oqctl.qc_dqblk.dqb_btime != 0 ||
230 oqctl.qc_dqblk.dqb_itime != 0) {
231 CERROR("3l: quotactl Q_GETQUOTA get wrong result:"
232 "%llu, %llu, %llu, %llu, %llu, %llu, %llu, %llu\n",
233 oqctl.qc_dqblk.dqb_bhardlimit,
234 oqctl.qc_dqblk.dqb_bsoftlimit,
235 oqctl.qc_dqblk.dqb_ihardlimit,
236 oqctl.qc_dqblk.dqb_isoftlimit,
237 oqctl.qc_dqblk.dqb_curspace,
238 oqctl.qc_dqblk.dqb_curinodes,
239 oqctl.qc_dqblk.dqb_btime,
240 oqctl.qc_dqblk.dqb_itime);
248 static int quotactl_test_4(struct obd_device *obd, struct super_block *sb)
250 struct obd_quotactl oqctl;
254 oqctl.qc_cmd = Q_QUOTAOFF;
256 oqctl.qc_type = UGQUOTA;
257 rc = fsfilt_quotactl(obd, sb, &oqctl);
259 CERROR("4a: quotactl Q_QUOTAOFF failed: %d\n", rc);
266 /* -------------------------------------------------------------------------
267 * Tests above, boring obd functions below
268 * ------------------------------------------------------------------------- */
269 static int quotactl_run_tests(struct obd_device *obd, struct obd_device *tgt)
271 struct super_block *sb;
272 struct obd_run_ctxt saved;
276 if (!strcmp(tgt->obd_type->typ_name, LUSTRE_MDS_NAME))
277 sb = tgt->u.mds.mds_sb;
278 else if (!strcmp(tgt->obd_type->typ_name, "obdfilter"))
279 sb = tgt->u.filter.fo_sb;
281 CERROR("TARGET OBD should be mds or obdfilter\n");
285 push_ctxt(&saved, &tgt->obd_ctxt, NULL);
287 rc = quotactl_test_1(tgt, sb);
292 rc = quotactl_test_2(tgt, sb);
297 rc = quotactl_test_3(tgt, sb);
302 quotactl_test_4(tgt, sb);
304 pop_ctxt(&saved, &tgt->obd_ctxt, NULL);
309 static int quotactl_test_cleanup(struct obd_device *obd)
311 lprocfs_obd_cleanup(obd);
315 static int quotactl_test_setup(struct obd_device *obd, obd_count len, void *buf)
317 struct lprocfs_static_vars lvars;
318 struct lustre_cfg *lcfg = buf;
319 struct obd_device *tgt;
323 if (lcfg->lcfg_bufcount < 1) {
324 CERROR("requires a mds OBD name\n");
328 tgt = class_name2obd(lustre_cfg_string(lcfg, 1));
329 if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {
330 CERROR("target device not attached or not set up (%s)\n",
331 lustre_cfg_string(lcfg, 1));
335 lprocfs_init_vars(quotactl_test, &lvars);
336 lprocfs_obd_setup(obd, lvars.obd_vars);
338 rc = quotactl_run_tests(obd, tgt);
340 quotactl_test_cleanup(obd);
345 static struct obd_ops quotactl_obd_ops = {
346 .o_owner = THIS_MODULE,
347 .o_setup = quotactl_test_setup,
348 .o_cleanup = quotactl_test_cleanup,
351 static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
352 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
353 LPROCFS_INIT_VARS(quotactl_test, lprocfs_module_vars, lprocfs_obd_vars)
355 static int __init quotactl_test_init(void)
357 struct lprocfs_static_vars lvars;
359 lprocfs_init_vars(quotactl_test, &lvars);
360 return class_register_type("actl_obd_ops, lvars.module_vars,
364 static void __exit quotactl_test_exit(void)
366 class_unregister_type("quotactl_test");
369 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
370 MODULE_DESCRIPTION("quotactl test module");
371 MODULE_LICENSE("GPL");
373 module_init(quotactl_test_init);
374 module_exit(quotactl_test_exit);