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