Whamcloud - gitweb
cffb64629405be3d6c973361f28a4a7ae429cf5e
[fs/lustre-release.git] / lustre / quota / quotactl_test.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2005 Cluster File Systems, Inc.
5  *   Author: Lai Siyao <lsy@clusterfs.com>
6  *
7  *   This file is part of Lustre, http://www.lustre.org/
8  *
9  *   No redistribution or use is permitted outside of Cluster File Systems, Inc.
10  *
11  * A kernel module which tests the fsfilt quotactl API from the OBD setup function.
12  */
13
14 #ifndef EXPORT_SYMTAB
15 # define EXPORT_SYMTAB
16 #endif
17 #define DEBUG_SUBSYSTEM S_CLASS
18
19 #include <linux/module.h>
20 #include <linux/init.h>
21
22 #include <obd_class.h>
23 #include <lustre_fsfilt.h>
24 #include <lustre_mds.h>
25 #include <obd_ost.h>
26
27 static struct obd_quotactl oqctl;
28
29 /* Test quotaon */
30 static int quotactl_test_1(struct obd_device *obd, struct super_block *sb)
31 {
32         int rc;
33         ENTRY;
34
35         oqctl.qc_cmd = Q_QUOTAON;
36         oqctl.qc_id = QFMT_LDISKFS;
37         oqctl.qc_type = UGQUOTA;
38         rc = fsfilt_quotactl(obd, sb, &oqctl);
39         if (rc)
40                 CERROR("1a: quotactl Q_QUOTAON failed: %d\n", rc);
41         RETURN(rc);
42 }
43
44 #if 0 /* set/getinfo not supported, this is for cluster-wide quotas */
45 /* Test set/getinfo */
46 static int quotactl_test_2(struct obd_device *obd, struct super_block *sb)
47 {
48         struct obd_quotactl oqctl;
49         int rc;
50         ENTRY;
51
52         oqctl.qc_cmd = Q_SETINFO;
53         oqctl.qc_type = USRQUOTA;
54         oqctl.qc_dqinfo.dqi_bgrace = 1616;
55         oqctl.qc_dqinfo.dqi_igrace = 2828;
56         oqctl.qc_dqinfo.dqi_flags = 0;
57         rc = fsfilt_quotactl(obd, sb, &oqctl);
58         if (rc) {
59                 CERROR("2a: quotactl Q_SETINFO failed: %d\n", rc);
60                 RETURN(rc);
61         }
62
63         oqctl.qc_cmd = Q_GETINFO;
64         oqctl.qc_type = USRQUOTA;
65         rc = fsfilt_quotactl(obd, sb, &oqctl);
66         if (rc) {
67                 CERROR("2b: quotactl Q_GETINFO failed: %d\n", rc);
68                 RETURN(rc);
69         }
70         if (oqctl.qc_dqinfo.dqi_bgrace != 1616 ||
71             oqctl.qc_dqinfo.dqi_igrace != 2828 ||
72             oqctl.qc_dqinfo.dqi_flags != 0) {
73                 CERROR("2c: quotactl Q_GETINFO get wrong result: %d, %d, %d\n",
74                        oqctl.qc_dqinfo.dqi_bgrace,
75                        oqctl.qc_dqinfo.dqi_igrace,
76                        oqctl.qc_dqinfo.dqi_flags);
77                 RETURN(-EINVAL);
78         }
79
80         RETURN(0);
81 }
82 #endif
83
84 /* Test set/getquota */
85 static int quotactl_test_3(struct obd_device *obd, struct super_block *sb)
86 {
87         int rc;
88         ENTRY;
89
90         oqctl.qc_cmd = Q_SETQUOTA;
91         oqctl.qc_type = USRQUOTA;
92         oqctl.qc_id = 500;
93         oqctl.qc_dqblk.dqb_bhardlimit = 919;
94         oqctl.qc_dqblk.dqb_bsoftlimit = 818;
95         oqctl.qc_dqblk.dqb_ihardlimit = 616;
96         oqctl.qc_dqblk.dqb_isoftlimit = 515;
97         oqctl.qc_dqblk.dqb_valid = QIF_LIMITS;
98         rc = fsfilt_quotactl(obd, sb, &oqctl);
99         if (rc) {
100                 CERROR("3a: quotactl Q_SETQUOTA failed: %d\n", rc);
101                 RETURN(rc);
102         }
103
104         oqctl.qc_cmd = Q_GETQUOTA;
105         oqctl.qc_type = USRQUOTA;
106         oqctl.qc_id = 500;
107         rc = fsfilt_quotactl(obd, sb, &oqctl);
108         if (rc) {
109                 CERROR("3b: quotactl Q_SETQUOTA failed: %d\n", rc);
110                 RETURN(rc);
111         }
112         if (oqctl.qc_dqblk.dqb_bhardlimit != 919 ||
113             oqctl.qc_dqblk.dqb_bsoftlimit != 818 ||
114             oqctl.qc_dqblk.dqb_ihardlimit != 616 ||
115             oqctl.qc_dqblk.dqb_isoftlimit != 515) {
116                 CERROR("3c: quotactl Q_GETQUOTA get wrong result:"
117                        LPU64", "LPU64", "LPU64", "LPU64"\n",
118                        oqctl.qc_dqblk.dqb_bhardlimit,
119                        oqctl.qc_dqblk.dqb_bsoftlimit,
120                        oqctl.qc_dqblk.dqb_ihardlimit,
121                        oqctl.qc_dqblk.dqb_isoftlimit);
122                 RETURN(-EINVAL);
123         }
124
125         oqctl.qc_cmd = Q_SETQUOTA;
126         oqctl.qc_type = USRQUOTA;
127         oqctl.qc_id = 500;
128         oqctl.qc_dqblk.dqb_curspace = 717;
129         oqctl.qc_dqblk.dqb_curinodes = 414;
130         oqctl.qc_dqblk.dqb_valid = QIF_USAGE;
131         rc = fsfilt_quotactl(obd, sb, &oqctl);
132         if (rc) {
133                 CERROR("3d: quotactl Q_SETQUOTA failed: %d\n", rc);
134                 RETURN(rc);
135         }
136
137         oqctl.qc_cmd = Q_GETQUOTA;
138         oqctl.qc_type = USRQUOTA;
139         oqctl.qc_id = 500;
140         rc = fsfilt_quotactl(obd, sb, &oqctl);
141         if (rc) {
142                 CERROR("3e: quotactl Q_SETQUOTA failed: %d\n", rc);
143                 RETURN(rc);
144         }
145         if (oqctl.qc_dqblk.dqb_curspace != 717 ||
146             oqctl.qc_dqblk.dqb_curinodes != 414) {
147                 CERROR("3f: quotactl Q_GETQUOTA get wrong result: "
148                        LPU64", "LPU64"\n", oqctl.qc_dqblk.dqb_curspace,
149                        oqctl.qc_dqblk.dqb_curinodes);
150                 RETURN(-EINVAL);
151         }
152
153         oqctl.qc_cmd = Q_SETQUOTA;
154         oqctl.qc_type = USRQUOTA;
155         oqctl.qc_dqblk.dqb_btime = 313;
156         oqctl.qc_dqblk.dqb_itime = 212;
157         oqctl.qc_id = 500;
158         oqctl.qc_dqblk.dqb_valid = QIF_TIMES;
159         rc = fsfilt_quotactl(obd, sb, &oqctl);
160         if (rc) {
161                 CERROR("3g: quotactl Q_SETQUOTA failed: %d\n", rc);
162                 RETURN(rc);
163         }
164
165         oqctl.qc_cmd = Q_GETQUOTA;
166         oqctl.qc_type = USRQUOTA;
167         oqctl.qc_id = 500;
168         rc = fsfilt_quotactl(obd, sb, &oqctl);
169         if (rc) {
170                 CERROR("3h: quotactl Q_SETQUOTA failed: %d\n", rc);
171                 RETURN(rc);
172         }
173         if (oqctl.qc_dqblk.dqb_btime != 313 ||
174             oqctl.qc_dqblk.dqb_itime != 212) {
175                 CERROR("3i: quotactl Q_GETQUOTA get wrong result: "
176                        LPU64", "LPU64"\n", oqctl.qc_dqblk.dqb_btime,
177                        oqctl.qc_dqblk.dqb_itime);
178                 RETURN(-EINVAL);
179         }
180
181         oqctl.qc_cmd = Q_SETQUOTA;
182         oqctl.qc_type = USRQUOTA;
183         oqctl.qc_id = 500;
184         oqctl.qc_dqblk.dqb_bhardlimit = 919;
185         oqctl.qc_dqblk.dqb_bsoftlimit = 818;
186         oqctl.qc_dqblk.dqb_curspace = 717;
187         oqctl.qc_dqblk.dqb_ihardlimit = 616;
188         oqctl.qc_dqblk.dqb_isoftlimit = 515;
189         oqctl.qc_dqblk.dqb_curinodes = 414;
190         oqctl.qc_dqblk.dqb_btime = 313;
191         oqctl.qc_dqblk.dqb_itime = 212;
192         oqctl.qc_dqblk.dqb_valid = QIF_ALL;
193         rc = fsfilt_quotactl(obd, sb, &oqctl);
194         if (rc) {
195                 CERROR("3j: quotactl Q_SETQUOTA failed: %d\n", rc);
196                 RETURN(rc);
197         }
198
199         oqctl.qc_cmd = Q_GETQUOTA;
200         oqctl.qc_type = USRQUOTA;
201         oqctl.qc_id = 500;
202         rc = fsfilt_quotactl(obd, sb, &oqctl);
203         if (rc) {
204                 CERROR("3k: quotactl Q_SETQUOTA failed: %d\n", rc);
205                 RETURN(rc);
206         }
207         if (oqctl.qc_dqblk.dqb_bhardlimit != 919 ||
208             oqctl.qc_dqblk.dqb_bsoftlimit != 818 ||
209             oqctl.qc_dqblk.dqb_ihardlimit != 616 ||
210             oqctl.qc_dqblk.dqb_isoftlimit != 515 ||
211             oqctl.qc_dqblk.dqb_curspace != 717 ||
212             oqctl.qc_dqblk.dqb_curinodes != 414 ||
213             oqctl.qc_dqblk.dqb_btime != 0 ||
214             oqctl.qc_dqblk.dqb_itime != 0) {
215                 CERROR("3l: quotactl Q_GETQUOTA get wrong result:"
216                        LPU64", "LPU64", "LPU64", "LPU64", "LPU64", "LPU64", "
217                        LPU64", "LPU64"\n", oqctl.qc_dqblk.dqb_bhardlimit,
218                        oqctl.qc_dqblk.dqb_bsoftlimit,
219                        oqctl.qc_dqblk.dqb_ihardlimit,
220                        oqctl.qc_dqblk.dqb_isoftlimit,
221                        oqctl.qc_dqblk.dqb_curspace,
222                        oqctl.qc_dqblk.dqb_curinodes,
223                        oqctl.qc_dqblk.dqb_btime,
224                        oqctl.qc_dqblk.dqb_itime);
225                 RETURN(-EINVAL);
226         }
227
228         RETURN(0);
229 }
230
231 /* Test quotaoff */
232 static int quotactl_test_4(struct obd_device *obd, struct super_block *sb)
233 {
234         int rc;
235         ENTRY;
236
237         oqctl.qc_cmd = Q_QUOTAOFF;
238         oqctl.qc_id = 500;
239         oqctl.qc_type = UGQUOTA;
240         rc = fsfilt_quotactl(obd, sb, &oqctl);
241         if (rc) {
242                 CERROR("4a: quotactl Q_QUOTAOFF failed: %d\n", rc);
243                 RETURN(rc);
244         }
245
246         RETURN(0);
247 }
248
249 /* -------------------------------------------------------------------------
250  * Tests above, boring obd functions below
251  * ------------------------------------------------------------------------- */
252 static int quotactl_run_tests(struct obd_device *obd, struct obd_device *tgt)
253 {
254         struct super_block *sb;
255         struct lvfs_run_ctxt saved;
256         int rc;
257         ENTRY;
258
259         if (strcmp(tgt->obd_type->typ_name, LUSTRE_MDS_NAME) &&
260             !strcmp(tgt->obd_type->typ_name, "obdfilter")) {
261                 CERROR("TARGET OBD should be mds or ost\n");
262                 RETURN(-EINVAL);
263         }
264
265         sb = tgt->u.obt.obt_sb;
266
267         push_ctxt(&saved, &tgt->obd_lvfs_ctxt, NULL);
268
269         rc = quotactl_test_1(tgt, sb);
270         if (rc)
271                 GOTO(cleanup, rc);
272
273 #if 0
274         rc = quotactl_test_2(tgt, sb);
275         if (rc)
276                 GOTO(cleanup, rc);
277 #endif
278
279         rc = quotactl_test_3(tgt, sb);
280         if (rc)
281                 GOTO(cleanup, rc);
282
283  cleanup:
284         quotactl_test_4(tgt, sb);
285
286         pop_ctxt(&saved, &tgt->obd_lvfs_ctxt, NULL);
287
288         return rc;
289 }
290
291 static int quotactl_test_cleanup(struct obd_device *obd)
292 {
293         lprocfs_obd_cleanup(obd);
294         return 0;
295 }
296
297 static int quotactl_test_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
298 {
299         struct lprocfs_static_vars lvars;
300         struct obd_device *tgt;
301         int rc;
302         ENTRY;
303
304         if (lcfg->lcfg_bufcount < 1) {
305                 CERROR("requires a mds OBD name\n");
306                 RETURN(-EINVAL);
307         }
308
309         tgt = class_name2obd(lustre_cfg_string(lcfg, 1));
310         if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {
311                 CERROR("target device not attached or not set up (%s)\n",
312                        lustre_cfg_string(lcfg, 1));
313                 RETURN(-EINVAL);
314         }
315
316         lprocfs_init_vars(quotactl_test, &lvars);
317         lprocfs_obd_setup(obd, lvars.obd_vars);
318
319         rc = quotactl_run_tests(obd, tgt);
320
321         quotactl_test_cleanup(obd);
322
323         RETURN(rc);
324 }
325
326 static struct obd_ops quotactl_obd_ops = {
327         .o_owner       = THIS_MODULE,
328         .o_setup       = quotactl_test_setup,
329         .o_cleanup     = quotactl_test_cleanup,
330 };
331
332 #ifdef LPROCFS
333 static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
334 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
335 LPROCFS_INIT_VARS(quotactl_test, lprocfs_module_vars, lprocfs_obd_vars)
336 #endif
337
338 static int __init quotactl_test_init(void)
339 {
340         struct lprocfs_static_vars lvars;
341
342         lprocfs_init_vars(quotactl_test, &lvars);
343         return class_register_type(&quotactl_obd_ops, NULL, lvars.module_vars,
344                                    "quotactl_test", NULL);
345 }
346
347 static void __exit quotactl_test_exit(void)
348 {
349         class_unregister_type("quotactl_test");
350 }
351
352 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
353 MODULE_DESCRIPTION("quotactl test module");
354 MODULE_LICENSE("GPL");
355
356 module_init(quotactl_test_init);
357 module_exit(quotactl_test_exit);