Linux 2.2.0
[davej-history.git] / fs / umsdos / check.c
blob6516fb57dd403418475a94e313cb82475a027eb4
1 /*
2 * linux/fs/umsdos/check.c
4 * Sanity-checking code
5 */
7 #include <linux/signal.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/string.h>
12 #include <linux/types.h>
13 #include <linux/ptrace.h>
14 #include <linux/mman.h>
15 #include <linux/mm.h>
16 #include <linux/umsdos_fs.h>
18 #include <asm/system.h>
20 #ifdef CHECK_PAGE_TABLES
21 static int check_one_table (struct pde *page_dir)
23 if (pgd_none (*page_dir))
24 return 0;
25 if (pgd_bad (*page_dir))
26 return 1;
27 return 0;
31 * This function checks all page tables of "current"
33 void check_page_tables (void)
35 struct pgd *pg_dir;
36 static int err = 0;
38 int stack_level = (long) (&pg_dir) - current->kernel_stack_page;
40 if (stack_level < 1500)
41 printk ("** %d ** ", stack_level);
42 pg_dir = PAGE_DIR_OFFSET (current, 0);
43 if (err == 0) {
44 int i;
46 for (i = 0; i < PTRS_PER_PAGE; i++, page_dir++) {
47 int notok = check_one_table (page_dir);
49 if (notok) {
50 err++;
51 printk ("|%d:%08lx| ", i, page_dir->pgd);
54 if (err)
55 printk ("\nError MM %d\n", err);
58 #endif
61 #if UMS_DEBUG
63 * check a superblock
66 void check_sb (struct super_block *sb, const char c)
68 if (sb) {
69 printk (" (has %c_sb=%d, %d)",
70 c, MAJOR (sb->s_dev), MINOR (sb->s_dev));
71 } else {
72 printk (" (%c_sb is NULL)", c);
77 * check an inode
79 extern struct inode_operations umsdos_rdir_inode_operations;
81 void check_inode (struct inode *inode)
83 if (inode) {
84 printk (KERN_DEBUG "* inode is %lu (i_count=%d)",
85 inode->i_ino, inode->i_count);
86 check_sb (inode->i_sb, 'i');
88 if (inode->i_dentry.next) { /* FIXME: does this work ? */
89 printk (" (has i_dentry)");
90 } else {
91 printk (" (NO i_dentry)");
94 printk (" (i_patched=%d)", inode->u.umsdos_i.i_patched);
96 if (inode->i_op == NULL) {
97 printk (" (i_op is NULL)\n");
98 } else if (inode->i_op == &umsdos_dir_inode_operations) {
99 printk (" (i_op is umsdos_dir_inode_operations)\n");
100 } else if (inode->i_op == &umsdos_file_inode_operations) {
101 printk (" (i_op is umsdos_file_inode_operations)\n");
102 } else if (inode->i_op == &umsdos_file_inode_operations_no_bmap) {
103 printk (" (i_op is umsdos_file_inode_operations_no_bmap)\n");
104 } else if (inode->i_op == &umsdos_file_inode_operations_readpage) {
105 printk (" (i_op is umsdos_file_inode_operations_readpage)\n");
106 } else if (inode->i_op == &umsdos_rdir_inode_operations) {
107 printk (" (i_op is umsdos_rdir_inode_operations)\n");
108 } else if (inode->i_op == &umsdos_symlink_inode_operations) {
109 printk (" (i_op is umsdos_symlink_inode_operations)\n");
110 } else {
111 printk (" (i_op is UNKNOWN: %p)\n", inode->i_op);
113 } else {
114 printk (KERN_DEBUG "* inode is NULL\n");
119 * checks all inode->i_dentry
122 void checkd_inode (struct inode *inode)
124 struct dentry *ret;
125 struct list_head *cur;
126 int count = 0;
127 if (!inode) {
128 printk (KERN_ERR "checkd_inode: inode is NULL!\n");
129 return;
132 printk (KERN_DEBUG "checkd_inode: inode %lu\n", inode->i_ino);
133 cur = inode->i_dentry.next;
134 while (count++ < 10) {
135 PRINTK (("1..."));
136 if (!cur) {
137 printk (KERN_ERR "checkd_inode: *** NULL reached. exit.\n");
138 return;
140 PRINTK (("2..."));
141 ret = list_entry (cur, struct dentry, d_alias);
142 PRINTK (("3..."));
143 if (cur == cur->next) {
144 printk (KERN_DEBUG "checkd_inode: *** cur=cur->next: normal exit.\n");
145 return;
147 PRINTK (("4..."));
148 if (!ret) {
149 printk (KERN_ERR "checkd_inode: *** ret dentry is NULL. exit.\n");
150 return;
152 PRINTK (("5... (ret=%p)...", ret));
153 PRINTK (("5.1.. (ret->d_dname=%p)...", &(ret->d_name)));
154 PRINTK (("5.1.1. (ret->d_dname.len=%d)...", (int) ret->d_name.len));
155 PRINTK (("5.1.2. (ret->d_dname.name=%c)...", ret->d_name.name));
156 printk (KERN_DEBUG "checkd_inode: i_dentry is %.*s\n", (int) ret->d_name.len, ret->d_name.name);
157 PRINTK (("6..."));
158 cur = cur->next;
159 PRINTK (("7..."));
160 #if 1
161 printk (KERN_DEBUG "checkd_inode: *** finished after count 1 (operator forced)\n");
162 return;
163 #endif
165 printk (KERN_ERR "checkd_inode: *** OVER LIMIT (loop?) !\n");
166 return;
170 * internal part of check_dentry. does the real job.
174 void check_dent_int (struct dentry *dentry, int parent)
176 if (parent) {
177 printk (KERN_DEBUG "* parent(%d) dentry: %.*s\n",
178 parent, (int) dentry->d_name.len, dentry->d_name.name);
179 } else {
180 printk (KERN_DEBUG "* checking dentry: %.*s\n",
181 (int) dentry->d_name.len, dentry->d_name.name);
183 check_inode (dentry->d_inode);
184 printk (KERN_DEBUG "* d_count=%d", dentry->d_count);
185 check_sb (dentry->d_sb, 'd');
186 if (dentry->d_op == NULL) {
187 printk (" (d_op is NULL)\n");
188 } else {
189 printk (" (d_op is UNKNOWN: %p)\n", dentry->d_op);
194 * checks dentry with full traceback to root and prints info. Limited to 10 recursive depths to avoid infinite loops.
198 void check_dentry_path (struct dentry *dentry, const char *desc)
200 int count=0;
201 printk (KERN_DEBUG "*** check_dentry_path: %.60s\n", desc);
203 if (!dentry) {
204 printk (KERN_DEBUG "*** checking dentry... it is NULL !\n");
205 return;
207 if (IS_ERR(dentry)) {
208 printk (KERN_DEBUG "*** checking dentry... it is ERR(%ld) !\n",
209 PTR_ERR(dentry));
210 return;
213 while (dentry && count < 10) {
214 check_dent_int (dentry, count++);
215 if (dentry == dentry->d_parent) {
216 printk (KERN_DEBUG "*** end checking dentry (root reached ok)\n");
217 break;
219 dentry = dentry->d_parent;
222 if (count >= 10) { /* if infinite loop detected */
223 printk (KERN_ERR
224 "*** WARNING ! INFINITE LOOP ! check_dentry_path aborted !\n");
227 if (!dentry) {
228 printk (KERN_ERR
229 "*** WARNING ! NULL dentry ! check_dentry_path aborted !\n");
232 #else
233 void check_sb (struct super_block *sb, const char c) {};
234 void check_inode (struct inode *inode) {};
235 void checkd_inode (struct inode *inode) {};
236 void check_dentry_path (struct dentry *dentry, const char *desc) {};
237 #endif /* UMS_DEBUG */