1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2005 Cluster File Systems, Inc.
5 * Author: Lai Siyao <lsy@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org/
9 * No redistribution or use is permitted outside of Cluster File Systems, Inc.
11 * A kernel module which tests the fsfilt quotacheck API from the OBD setup function.
15 # define EXPORT_SYMTAB
17 #define DEBUG_SUBSYSTEM S_CLASS
19 #include <linux/module.h>
20 #include <linux/init.h>
22 #include <linux/jbd.h>
23 #include <linux/slab.h>
24 #include <linux/pagemap.h>
25 #include <linux/quotaops.h>
26 #include <linux/ext3_fs.h>
27 #include <linux/ext3_jbd.h>
28 #include <linux/version.h>
29 #include <linux/bitops.h>
31 #include <obd_class.h>
32 #include <lustre_fsfilt.h>
33 #include <lustre_mds.h>
36 char *test_quotafile[] = {"aquotacheck.user", "aquotacheck.group"};
38 static inline struct ext3_group_desc *
39 get_group_desc(struct super_block *sb, int group)
41 unsigned long desc_block, desc;
42 struct ext3_group_desc *gdp;
44 desc_block = group / EXT3_DESC_PER_BLOCK(sb);
45 desc = group % EXT3_DESC_PER_BLOCK(sb);
46 gdp = (struct ext3_group_desc *)
47 EXT3_SB(sb)->s_group_desc[desc_block]->b_data;
52 static inline struct buffer_head *
53 read_inode_bitmap(struct super_block *sb, unsigned long group)
55 struct ext3_group_desc *desc;
56 struct buffer_head *bh;
58 desc = get_group_desc(sb, group);
59 bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));
64 static inline struct inode *ext3_iget_inuse(struct super_block *sb,
65 struct buffer_head *bitmap_bh,
66 int index, unsigned long ino)
68 struct inode *inode = NULL;
70 if (ext3_test_bit(index, bitmap_bh->b_data)) {
71 CERROR("i: %d, ino: %lu\n", index, ino);
73 inode = iget(sb, ino);
79 static void print_inode(struct inode *inode)
83 if (S_ISDIR(inode->i_mode) ||
84 S_ISREG(inode->i_mode) ||
85 S_ISLNK(inode->i_mode))
86 size = inode_get_bytes(inode);
88 CERROR("%lu: uid: %u, size: %llu, blocks: %lu, real size: %llu\n",
89 inode->i_ino, inode->i_uid, i_size_read(inode),
90 inode->i_blocks, size);
94 static int quotacheck_test_1(struct obd_device *obd, struct super_block *sb)
96 struct ext3_sb_info *sbi = EXT3_SB(sb);
97 struct buffer_head *bitmap_bh = NULL;
103 for (group = 0; group < sbi->s_groups_count; group++) {
104 ino = group * sbi->s_inodes_per_group + 1;
106 bitmap_bh = read_inode_bitmap(sb, group);
109 CERROR("groups_count: %lu, inodes_per_group: %lu, first_ino: %u, inodes_count: %u\n",
110 sbi->s_groups_count, sbi->s_inodes_per_group,
111 sbi->s_first_ino, le32_to_cpu(sbi->s_es->s_inodes_count));
113 for (i = 0; i < sbi->s_inodes_per_group; i++, ino++) {
114 if (ino < sbi->s_first_ino)
116 if (ino > le32_to_cpu(sbi->s_es->s_inodes_count)) {
117 CERROR("bad inode number: %lu > s_inodes_count\n", ino);
121 inode = ext3_iget_inuse(sb, bitmap_bh, i, ino);
132 /* -------------------------------------------------------------------------
133 * Tests above, boring obd functions below
134 * ------------------------------------------------------------------------- */
135 static int quotacheck_run_tests(struct obd_device *obd, struct obd_device *tgt)
140 if (strcmp(tgt->obd_type->typ_name, LUSTRE_MDS_NAME) &&
141 !strcmp(tgt->obd_type->typ_name, "obdfilter")) {
142 CERROR("TARGET OBD should be mds or ost\n");
146 rc = quotacheck_test_1(tgt, tgt->u.obt.obt_sb);
152 static struct lprocfs_vars lprocfs_quotacheck_test_obd_vars[] = { {0} };
153 static struct lprocfs_vars lprocfs_quotacheck_test_module_vars[] = { {0} };
155 void lprocfs_quotacheck_test_init_vars(struct lprocfs_static_vars *lvars)
157 lvars->module_vars = lprocfs_quotacheck_test_module_vars;
158 lvars->obd_vars = lprocfs_quotacheck_test_obd_vars;
162 static int quotacheck_test_cleanup(struct obd_device *obd)
164 lprocfs_obd_cleanup(obd);
168 static int quotacheck_test_setup(struct obd_device *obd, struct lustre_cfg* lcfg)
170 struct lprocfs_static_vars lvars = { 0 };
171 struct obd_device *tgt;
175 if (lcfg->lcfg_bufcount < 1) {
176 CERROR("requires a mds OBD name\n");
180 tgt = class_name2obd(lustre_cfg_string(lcfg, 1));
181 if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {
182 CERROR("target device not attached or not set up (%s)\n",
183 lustre_cfg_string(lcfg, 1));
187 rc = quotacheck_run_tests(obd, tgt);
189 quotacheck_test_cleanup(obd);
191 lprocfs_quotacheck_test_init_vars(&lvars);
192 lprocfs_obd_setup(obd, lvars.obd_vars);
197 static struct obd_ops quotacheck_obd_ops = {
198 .o_owner = THIS_MODULE,
199 .o_setup = quotacheck_test_setup,
200 .o_cleanup = quotacheck_test_cleanup,
203 static int __init quotacheck_test_init(void)
205 struct lprocfs_static_vars lvars = { 0 };
207 lprocfs_quotacheck_test_init_vars(&lvars);
208 return class_register_type("acheck_obd_ops, NULL, lvars.module_vars,
209 "quotacheck_test", NULL);
212 static void __exit quotacheck_test_exit(void)
214 class_unregister_type("quotacheck_test");
217 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
218 MODULE_DESCRIPTION("quotacheck test module");
219 MODULE_LICENSE("GPL");
221 module_init(quotacheck_test_init);
222 module_exit(quotacheck_test_exit);