This source file includes following definitions.
- ext2_error
- ext2_panic
- ext2_warning
- ext2_put_super
- parse_options
- ext2_setup_super
- ext2_check_descriptors
- ext2_read_super
- ext2_commit_super
- ext2_write_super
- ext2_remount
- init_module
- cleanup_module
- ext2_statfs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <linux/module.h>
17
18 #include <stdarg.h>
19
20 #include <asm/bitops.h>
21 #include <asm/segment.h>
22 #include <asm/system.h>
23
24 #include <linux/errno.h>
25 #include <linux/fs.h>
26 #include <linux/ext2_fs.h>
27 #include <linux/malloc.h>
28 #include <linux/sched.h>
29 #include <linux/stat.h>
30 #include <linux/string.h>
31 #include <linux/locks.h>
32
33 static char error_buf[1024];
34
35 void ext2_error (struct super_block * sb, const char * function,
36 const char * fmt, ...)
37 {
38 va_list args;
39
40 if (!(sb->s_flags & MS_RDONLY)) {
41 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
42 sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
43 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
44 sb->s_dirt = 1;
45 }
46 va_start (args, fmt);
47 vsprintf (error_buf, fmt, args);
48 va_end (args);
49 if (test_opt (sb, ERRORS_PANIC) ||
50 (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_PANIC &&
51 !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_RO)))
52 panic ("EXT2-fs panic (device %s): %s: %s\n",
53 kdevname(sb->s_dev), function, error_buf);
54 printk (KERN_CRIT "EXT2-fs error (device %s): %s: %s\n",
55 kdevname(sb->s_dev), function, error_buf);
56 if (test_opt (sb, ERRORS_RO) ||
57 (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_RO &&
58 !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_PANIC))) {
59 printk ("Remounting filesystem read-only\n");
60 sb->s_flags |= MS_RDONLY;
61 }
62 }
63
64 NORET_TYPE void ext2_panic (struct super_block * sb, const char * function,
65 const char * fmt, ...)
66 {
67 va_list args;
68
69 if (!(sb->s_flags & MS_RDONLY)) {
70 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
71 sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
72 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
73 sb->s_dirt = 1;
74 }
75 va_start (args, fmt);
76 vsprintf (error_buf, fmt, args);
77 va_end (args);
78 panic ("EXT2-fs panic (device %s): %s: %s\n",
79 kdevname(sb->s_dev), function, error_buf);
80 }
81
82 void ext2_warning (struct super_block * sb, const char * function,
83 const char * fmt, ...)
84 {
85 va_list args;
86
87 va_start (args, fmt);
88 vsprintf (error_buf, fmt, args);
89 va_end (args);
90 printk (KERN_WARNING "EXT2-fs warning (device %s): %s: %s\n",
91 kdevname(sb->s_dev), function, error_buf);
92 }
93
94 void ext2_put_super (struct super_block * sb)
95 {
96 int db_count;
97 int i;
98
99 lock_super (sb);
100 if (!(sb->s_flags & MS_RDONLY)) {
101 sb->u.ext2_sb.s_es->s_state = sb->u.ext2_sb.s_mount_state;
102 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
103 }
104 sb->s_dev = 0;
105 db_count = sb->u.ext2_sb.s_db_per_group;
106 for (i = 0; i < db_count; i++)
107 if (sb->u.ext2_sb.s_group_desc[i])
108 brelse (sb->u.ext2_sb.s_group_desc[i]);
109 kfree_s (sb->u.ext2_sb.s_group_desc,
110 db_count * sizeof (struct buffer_head *));
111 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
112 if (sb->u.ext2_sb.s_inode_bitmap[i])
113 brelse (sb->u.ext2_sb.s_inode_bitmap[i]);
114 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
115 if (sb->u.ext2_sb.s_block_bitmap[i])
116 brelse (sb->u.ext2_sb.s_block_bitmap[i]);
117 brelse (sb->u.ext2_sb.s_sbh);
118 unlock_super (sb);
119 MOD_DEC_USE_COUNT;
120 return;
121 }
122
123 static struct super_operations ext2_sops = {
124 ext2_read_inode,
125 NULL,
126 ext2_write_inode,
127 ext2_put_inode,
128 ext2_put_super,
129 ext2_write_super,
130 ext2_statfs,
131 ext2_remount
132 };
133
134
135
136
137 static int parse_options (char * options, unsigned long * sb_block,
138 unsigned short *resuid, unsigned short * resgid,
139 unsigned long * mount_options)
140 {
141 char * this_char;
142 char * value;
143
144 if (!options)
145 return 1;
146 for (this_char = strtok (options, ",");
147 this_char != NULL;
148 this_char = strtok (NULL, ",")) {
149 if ((value = strchr (this_char, '=')) != NULL)
150 *value++ = 0;
151 if (!strcmp (this_char, "bsddf"))
152 clear_opt (*mount_options, MINIX_DF);
153 else if (!strcmp (this_char, "check")) {
154 if (!value || !*value)
155 set_opt (*mount_options, CHECK_NORMAL);
156 else if (!strcmp (value, "none")) {
157 clear_opt (*mount_options, CHECK_NORMAL);
158 clear_opt (*mount_options, CHECK_STRICT);
159 }
160 else if (!strcmp (value, "normal"))
161 set_opt (*mount_options, CHECK_NORMAL);
162 else if (!strcmp (value, "strict")) {
163 set_opt (*mount_options, CHECK_NORMAL);
164 set_opt (*mount_options, CHECK_STRICT);
165 }
166 else {
167 printk ("EXT2-fs: Invalid check option: %s\n",
168 value);
169 return 0;
170 }
171 }
172 else if (!strcmp (this_char, "debug"))
173 set_opt (*mount_options, DEBUG);
174 else if (!strcmp (this_char, "errors")) {
175 if (!value || !*value) {
176 printk ("EXT2-fs: the errors option requires "
177 "an argument");
178 return 0;
179 }
180 if (!strcmp (value, "continue")) {
181 clear_opt (*mount_options, ERRORS_RO);
182 clear_opt (*mount_options, ERRORS_PANIC);
183 set_opt (*mount_options, ERRORS_CONT);
184 }
185 else if (!strcmp (value, "remount-ro")) {
186 clear_opt (*mount_options, ERRORS_CONT);
187 clear_opt (*mount_options, ERRORS_PANIC);
188 set_opt (*mount_options, ERRORS_RO);
189 }
190 else if (!strcmp (value, "panic")) {
191 clear_opt (*mount_options, ERRORS_CONT);
192 clear_opt (*mount_options, ERRORS_RO);
193 set_opt (*mount_options, ERRORS_PANIC);
194 }
195 else {
196 printk ("EXT2-fs: Invalid errors option: %s\n",
197 value);
198 return 0;
199 }
200 }
201 else if (!strcmp (this_char, "grpid") ||
202 !strcmp (this_char, "bsdgroups"))
203 set_opt (*mount_options, GRPID);
204 else if (!strcmp (this_char, "minixdf"))
205 set_opt (*mount_options, MINIX_DF);
206 else if (!strcmp (this_char, "nocheck")) {
207 clear_opt (*mount_options, CHECK_NORMAL);
208 clear_opt (*mount_options, CHECK_STRICT);
209 }
210 else if (!strcmp (this_char, "nogrpid") ||
211 !strcmp (this_char, "sysvgroups"))
212 clear_opt (*mount_options, GRPID);
213 else if (!strcmp (this_char, "resgid")) {
214 if (!value || !*value) {
215 printk ("EXT2-fs: the resgid option requires "
216 "an argument");
217 return 0;
218 }
219 *resgid = simple_strtoul (value, &value, 0);
220 if (*value) {
221 printk ("EXT2-fs: Invalid resgid option: %s\n",
222 value);
223 return 0;
224 }
225 }
226 else if (!strcmp (this_char, "resuid")) {
227 if (!value || !*value) {
228 printk ("EXT2-fs: the resuid option requires "
229 "an argument");
230 return 0;
231 }
232 *resuid = simple_strtoul (value, &value, 0);
233 if (*value) {
234 printk ("EXT2-fs: Invalid resuid option: %s\n",
235 value);
236 return 0;
237 }
238 }
239 else if (!strcmp (this_char, "sb")) {
240 if (!value || !*value) {
241 printk ("EXT2-fs: the sb option requires "
242 "an argument");
243 return 0;
244 }
245 *sb_block = simple_strtoul (value, &value, 0);
246 if (*value) {
247 printk ("EXT2-fs: Invalid sb option: %s\n",
248 value);
249 return 0;
250 }
251 }
252
253 else if (!strcmp (this_char, "grpquota")
254 || !strcmp (this_char, "noquota")
255 || !strcmp (this_char, "quota")
256 || !strcmp (this_char, "usrquota"))
257 ;
258 else {
259 printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
260 return 0;
261 }
262 }
263 return 1;
264 }
265
266 static void ext2_setup_super (struct super_block * sb,
267 struct ext2_super_block * es)
268 {
269 if (es->s_rev_level > EXT2_CURRENT_REV) {
270 printk ("EXT2-fs warning: revision level too high, "
271 "forcing read/only mode\n");
272 sb->s_flags |= MS_RDONLY;
273 }
274 if (!(sb->s_flags & MS_RDONLY)) {
275 if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
276 printk ("EXT2-fs warning: mounting unchecked fs, "
277 "running e2fsck is recommended\n");
278 else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS))
279 printk ("EXT2-fs warning: mounting fs with errors, "
280 "running e2fsck is recommended\n");
281 else if (es->s_max_mnt_count >= 0 &&
282 es->s_mnt_count >= (unsigned short) es->s_max_mnt_count)
283 printk ("EXT2-fs warning: maximal mount count reached, "
284 "running e2fsck is recommended\n");
285 else if (es->s_checkinterval &&
286 (es->s_lastcheck + es->s_checkinterval <= CURRENT_TIME))
287 printk ("EXT2-fs warning: checktime reached, "
288 "running e2fsck is recommended\n");
289 es->s_state &= ~EXT2_VALID_FS;
290 if (!es->s_max_mnt_count)
291 es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
292 es->s_mnt_count++;
293 es->s_mtime = CURRENT_TIME;
294 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
295 sb->s_dirt = 1;
296 if (test_opt (sb, DEBUG))
297 printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
298 "bpg=%lu, ipg=%lu, mo=%04lx]\n",
299 EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
300 sb->u.ext2_sb.s_frag_size,
301 sb->u.ext2_sb.s_groups_count,
302 EXT2_BLOCKS_PER_GROUP(sb),
303 EXT2_INODES_PER_GROUP(sb),
304 sb->u.ext2_sb.s_mount_opt);
305 if (test_opt (sb, CHECK)) {
306 ext2_check_blocks_bitmap (sb);
307 ext2_check_inodes_bitmap (sb);
308 }
309 }
310 }
311
312 static int ext2_check_descriptors (struct super_block * sb)
313 {
314 int i;
315 int desc_block = 0;
316 unsigned long block = sb->u.ext2_sb.s_es->s_first_data_block;
317 struct ext2_group_desc * gdp = NULL;
318
319 ext2_debug ("Checking group descriptors");
320
321 for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++)
322 {
323 if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
324 gdp = (struct ext2_group_desc *) sb->u.ext2_sb.s_group_desc[desc_block++]->b_data;
325 if (gdp->bg_block_bitmap < block ||
326 gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
327 {
328 ext2_error (sb, "ext2_check_descriptors",
329 "Block bitmap for group %d"
330 " not in group (block %lu)!",
331 i, (unsigned long) gdp->bg_block_bitmap);
332 return 0;
333 }
334 if (gdp->bg_inode_bitmap < block ||
335 gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
336 {
337 ext2_error (sb, "ext2_check_descriptors",
338 "Inode bitmap for group %d"
339 " not in group (block %lu)!",
340 i, (unsigned long) gdp->bg_inode_bitmap);
341 return 0;
342 }
343 if (gdp->bg_inode_table < block ||
344 gdp->bg_inode_table + sb->u.ext2_sb.s_itb_per_group >=
345 block + EXT2_BLOCKS_PER_GROUP(sb))
346 {
347 ext2_error (sb, "ext2_check_descriptors",
348 "Inode table for group %d"
349 " not in group (block %lu)!",
350 i, (unsigned long) gdp->bg_inode_table);
351 return 0;
352 }
353 block += EXT2_BLOCKS_PER_GROUP(sb);
354 gdp++;
355 }
356 return 1;
357 }
358
359 #define log2(n) ffz(~(n))
360
361 struct super_block * ext2_read_super (struct super_block * sb, void * data,
362 int silent)
363 {
364 struct buffer_head * bh;
365 struct ext2_super_block * es;
366 unsigned long sb_block = 1;
367 unsigned short resuid = EXT2_DEF_RESUID;
368 unsigned short resgid = EXT2_DEF_RESGID;
369 unsigned long logic_sb_block = 1;
370 kdev_t dev = sb->s_dev;
371 int db_count;
372 int i, j;
373
374 set_opt (sb->u.ext2_sb.s_mount_opt, CHECK_NORMAL);
375 if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
376 &sb->u.ext2_sb.s_mount_opt)) {
377 sb->s_dev = 0;
378 return NULL;
379 }
380
381 MOD_INC_USE_COUNT;
382 lock_super (sb);
383 set_blocksize (dev, BLOCK_SIZE);
384 if (!(bh = bread (dev, sb_block, BLOCK_SIZE))) {
385 sb->s_dev = 0;
386 unlock_super (sb);
387 printk ("EXT2-fs: unable to read superblock\n");
388 MOD_DEC_USE_COUNT;
389 return NULL;
390 }
391
392
393
394
395 es = (struct ext2_super_block *) bh->b_data;
396 sb->u.ext2_sb.s_es = es;
397 sb->s_magic = es->s_magic;
398 if (sb->s_magic != EXT2_SUPER_MAGIC) {
399 sb->s_dev = 0;
400 unlock_super (sb);
401 brelse (bh);
402 if (!silent)
403 printk ("VFS: Can't find an ext2 filesystem on dev "
404 "%s.\n", kdevname(dev));
405 return NULL;
406 }
407 sb->s_blocksize_bits = sb->u.ext2_sb.s_es->s_log_block_size + 10;
408 sb->s_blocksize = 1 << sb->s_blocksize_bits;
409 if (sb->s_blocksize != BLOCK_SIZE &&
410 (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||
411 sb->s_blocksize == 4096)) {
412 unsigned long offset;
413
414 brelse (bh);
415 set_blocksize (dev, sb->s_blocksize);
416 logic_sb_block = (sb_block*BLOCK_SIZE) / sb->s_blocksize;
417 offset = (sb_block*BLOCK_SIZE) % sb->s_blocksize;
418 bh = bread (dev, logic_sb_block, sb->s_blocksize);
419 if(!bh) {
420 MOD_DEC_USE_COUNT;
421 return NULL;
422 }
423 es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
424 sb->u.ext2_sb.s_es = es;
425 if (es->s_magic != EXT2_SUPER_MAGIC) {
426 sb->s_dev = 0;
427 unlock_super (sb);
428 brelse (bh);
429 printk ("EXT2-fs: Magic mismatch, very weird !\n");
430 MOD_DEC_USE_COUNT;
431 return NULL;
432 }
433 }
434 sb->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
435 es->s_log_frag_size;
436 if (sb->u.ext2_sb.s_frag_size)
437 sb->u.ext2_sb.s_frags_per_block = sb->s_blocksize /
438 sb->u.ext2_sb.s_frag_size;
439 else
440 sb->s_magic = 0;
441 sb->u.ext2_sb.s_blocks_per_group = es->s_blocks_per_group;
442 sb->u.ext2_sb.s_frags_per_group = es->s_frags_per_group;
443 sb->u.ext2_sb.s_inodes_per_group = es->s_inodes_per_group;
444 sb->u.ext2_sb.s_inodes_per_block = sb->s_blocksize /
445 sizeof (struct ext2_inode);
446 sb->u.ext2_sb.s_itb_per_group = sb->u.ext2_sb.s_inodes_per_group /
447 sb->u.ext2_sb.s_inodes_per_block;
448 sb->u.ext2_sb.s_desc_per_block = sb->s_blocksize /
449 sizeof (struct ext2_group_desc);
450 sb->u.ext2_sb.s_sbh = bh;
451 if (resuid != EXT2_DEF_RESUID)
452 sb->u.ext2_sb.s_resuid = resuid;
453 else
454 sb->u.ext2_sb.s_resuid = es->s_def_resuid;
455 if (resgid != EXT2_DEF_RESGID)
456 sb->u.ext2_sb.s_resgid = resgid;
457 else
458 sb->u.ext2_sb.s_resgid = es->s_def_resgid;
459 sb->u.ext2_sb.s_mount_state = es->s_state;
460 sb->u.ext2_sb.s_rename_lock = 0;
461 sb->u.ext2_sb.s_rename_wait = NULL;
462 sb->u.ext2_sb.s_addr_per_block_bits =
463 log2 (EXT2_ADDR_PER_BLOCK(sb));
464 sb->u.ext2_sb.s_inodes_per_block_bits =
465 log2 (EXT2_INODES_PER_BLOCK(sb));
466 sb->u.ext2_sb.s_desc_per_block_bits =
467 log2 (EXT2_DESC_PER_BLOCK(sb));
468 if (sb->s_magic != EXT2_SUPER_MAGIC) {
469 sb->s_dev = 0;
470 unlock_super (sb);
471 brelse (bh);
472 if (!silent)
473 printk ("VFS: Can't find an ext2 filesystem on dev "
474 "%s.\n",
475 kdevname(dev));
476 MOD_DEC_USE_COUNT;
477 return NULL;
478 }
479 if (sb->s_blocksize != bh->b_size) {
480 sb->s_dev = 0;
481 unlock_super (sb);
482 brelse (bh);
483 if (!silent)
484 printk ("VFS: Unsupported blocksize on dev "
485 "%s.\n", kdevname(dev));
486 MOD_DEC_USE_COUNT;
487 return NULL;
488 }
489
490 if (sb->s_blocksize != sb->u.ext2_sb.s_frag_size) {
491 sb->s_dev = 0;
492 unlock_super (sb);
493 brelse (bh);
494 printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",
495 sb->u.ext2_sb.s_frag_size, sb->s_blocksize);
496 MOD_DEC_USE_COUNT;
497 return NULL;
498 }
499
500 if (sb->u.ext2_sb.s_blocks_per_group > sb->s_blocksize * 8) {
501 sb->s_dev = 0;
502 unlock_super (sb);
503 brelse (bh);
504 printk ("EXT2-fs: #blocks per group too big: %lu\n",
505 sb->u.ext2_sb.s_blocks_per_group);
506 MOD_DEC_USE_COUNT;
507 return NULL;
508 }
509 if (sb->u.ext2_sb.s_frags_per_group > sb->s_blocksize * 8) {
510 sb->s_dev = 0;
511 unlock_super (sb);
512 brelse (bh);
513 printk ("EXT2-fs: #fragments per group too big: %lu\n",
514 sb->u.ext2_sb.s_frags_per_group);
515 MOD_DEC_USE_COUNT;
516 return NULL;
517 }
518 if (sb->u.ext2_sb.s_inodes_per_group > sb->s_blocksize * 8) {
519 sb->s_dev = 0;
520 unlock_super (sb);
521 brelse (bh);
522 printk ("EXT2-fs: #inodes per group too big: %lu\n",
523 sb->u.ext2_sb.s_inodes_per_group);
524 MOD_DEC_USE_COUNT;
525 return NULL;
526 }
527
528 sb->u.ext2_sb.s_groups_count = (es->s_blocks_count -
529 es->s_first_data_block +
530 EXT2_BLOCKS_PER_GROUP(sb) - 1) /
531 EXT2_BLOCKS_PER_GROUP(sb);
532 db_count = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
533 EXT2_DESC_PER_BLOCK(sb);
534 sb->u.ext2_sb.s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL);
535 if (sb->u.ext2_sb.s_group_desc == NULL) {
536 sb->s_dev = 0;
537 unlock_super (sb);
538 brelse (bh);
539 printk ("EXT2-fs: not enough memory\n");
540 MOD_DEC_USE_COUNT;
541 return NULL;
542 }
543 for (i = 0; i < db_count; i++) {
544 sb->u.ext2_sb.s_group_desc[i] = bread (dev, logic_sb_block + i + 1,
545 sb->s_blocksize);
546 if (!sb->u.ext2_sb.s_group_desc[i]) {
547 sb->s_dev = 0;
548 unlock_super (sb);
549 for (j = 0; j < i; j++)
550 brelse (sb->u.ext2_sb.s_group_desc[j]);
551 kfree_s (sb->u.ext2_sb.s_group_desc,
552 db_count * sizeof (struct buffer_head *));
553 brelse (bh);
554 printk ("EXT2-fs: unable to read group descriptors\n");
555 MOD_DEC_USE_COUNT;
556 return NULL;
557 }
558 }
559 if (!ext2_check_descriptors (sb)) {
560 sb->s_dev = 0;
561 unlock_super (sb);
562 for (j = 0; j < db_count; j++)
563 brelse (sb->u.ext2_sb.s_group_desc[j]);
564 kfree_s (sb->u.ext2_sb.s_group_desc,
565 db_count * sizeof (struct buffer_head *));
566 brelse (bh);
567 printk ("EXT2-fs: group descriptors corrupted !\n");
568 MOD_DEC_USE_COUNT;
569 return NULL;
570 }
571 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
572 sb->u.ext2_sb.s_inode_bitmap_number[i] = 0;
573 sb->u.ext2_sb.s_inode_bitmap[i] = NULL;
574 sb->u.ext2_sb.s_block_bitmap_number[i] = 0;
575 sb->u.ext2_sb.s_block_bitmap[i] = NULL;
576 }
577 sb->u.ext2_sb.s_loaded_inode_bitmaps = 0;
578 sb->u.ext2_sb.s_loaded_block_bitmaps = 0;
579 sb->u.ext2_sb.s_db_per_group = db_count;
580 unlock_super (sb);
581
582
583
584 sb->s_dev = dev;
585 sb->s_op = &ext2_sops;
586 if (!(sb->s_mounted = iget (sb, EXT2_ROOT_INO))) {
587 sb->s_dev = 0;
588 for (i = 0; i < db_count; i++)
589 if (sb->u.ext2_sb.s_group_desc[i])
590 brelse (sb->u.ext2_sb.s_group_desc[i]);
591 kfree_s (sb->u.ext2_sb.s_group_desc,
592 db_count * sizeof (struct buffer_head *));
593 brelse (bh);
594 printk ("EXT2-fs: get root inode failed\n");
595 MOD_DEC_USE_COUNT;
596 return NULL;
597 }
598 ext2_setup_super (sb, es);
599 return sb;
600 }
601
602 static void ext2_commit_super (struct super_block * sb,
603 struct ext2_super_block * es)
604 {
605 es->s_wtime = CURRENT_TIME;
606 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
607 sb->s_dirt = 0;
608 }
609
610
611
612
613
614
615
616
617
618
619
620
621 void ext2_write_super (struct super_block * sb)
622 {
623 struct ext2_super_block * es;
624
625 if (!(sb->s_flags & MS_RDONLY)) {
626 es = sb->u.ext2_sb.s_es;
627
628 ext2_debug ("setting valid to 0\n");
629
630 if (es->s_state & EXT2_VALID_FS) {
631 es->s_state &= ~EXT2_VALID_FS;
632 es->s_mtime = CURRENT_TIME;
633 }
634 ext2_commit_super (sb, es);
635 }
636 sb->s_dirt = 0;
637 }
638
639 int ext2_remount (struct super_block * sb, int * flags, char * data)
640 {
641 struct ext2_super_block * es;
642 unsigned short resuid = sb->u.ext2_sb.s_resuid;
643 unsigned short resgid = sb->u.ext2_sb.s_resgid;
644 unsigned long new_mount_opt;
645 unsigned long tmp;
646
647
648
649
650 set_opt (new_mount_opt, CHECK_NORMAL);
651 if (!parse_options (data, &tmp, &resuid, &resgid,
652 &new_mount_opt))
653 return -EINVAL;
654
655 sb->u.ext2_sb.s_mount_opt = new_mount_opt;
656 sb->u.ext2_sb.s_resuid = resuid;
657 sb->u.ext2_sb.s_resgid = resgid;
658 es = sb->u.ext2_sb.s_es;
659 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
660 return 0;
661 if (*flags & MS_RDONLY) {
662 if (es->s_state & EXT2_VALID_FS ||
663 !(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
664 return 0;
665
666
667
668
669 es->s_state = sb->u.ext2_sb.s_mount_state;
670 es->s_mtime = CURRENT_TIME;
671 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
672 sb->s_dirt = 1;
673 ext2_commit_super (sb, es);
674 }
675 else {
676
677
678
679
680
681 sb->u.ext2_sb.s_mount_state = es->s_state;
682 sb->s_flags &= ~MS_RDONLY;
683 ext2_setup_super (sb, es);
684 }
685 return 0;
686 }
687
688 #ifdef MODULE
689
690 static struct file_system_type ext2_fs_type = {
691 ext2_read_super, "ext2", 1, NULL
692 };
693
694 int init_module(void)
695 {
696 return register_filesystem(&ext2_fs_type);
697 }
698
699 void cleanup_module(void)
700 {
701 unregister_filesystem(&ext2_fs_type);
702 }
703
704 #endif
705
706 void ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
707 {
708 unsigned long overhead;
709 unsigned long overhead_per_group;
710 struct statfs tmp;
711
712 if (test_opt (sb, MINIX_DF))
713 overhead = 0;
714 else {
715
716
717
718 overhead_per_group = 1 +
719 sb->u.ext2_sb.s_db_per_group +
720 1 +
721 1 +
722 sb->u.ext2_sb.s_itb_per_group ;
723 overhead = sb->u.ext2_sb.s_es->s_first_data_block +
724 sb->u.ext2_sb.s_groups_count * overhead_per_group;
725 }
726
727 tmp.f_type = EXT2_SUPER_MAGIC;
728 tmp.f_bsize = sb->s_blocksize;
729 tmp.f_blocks = sb->u.ext2_sb.s_es->s_blocks_count - overhead;
730 tmp.f_bfree = ext2_count_free_blocks (sb);
731 tmp.f_bavail = tmp.f_bfree - sb->u.ext2_sb.s_es->s_r_blocks_count;
732 if (tmp.f_bfree < sb->u.ext2_sb.s_es->s_r_blocks_count)
733 tmp.f_bavail = 0;
734 tmp.f_files = sb->u.ext2_sb.s_es->s_inodes_count;
735 tmp.f_ffree = ext2_count_free_inodes (sb);
736 tmp.f_namelen = EXT2_NAME_LEN;
737 memcpy_tofs(buf, &tmp, bufsiz);
738 }