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