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 #ifdef MODULE
17 #include <linux/module.h>
18 #include <linux/version.h>
19 #else
20 #define MOD_INC_USE_COUNT
21 #define MOD_DEC_USE_COUNT
22 #endif
23
24 #include <stdarg.h>
25
26 #include <asm/bitops.h>
27 #include <asm/segment.h>
28 #include <asm/system.h>
29
30 #include <linux/errno.h>
31 #include <linux/fs.h>
32 #include <linux/ext2_fs.h>
33 #include <linux/malloc.h>
34 #include <linux/sched.h>
35 #include <linux/stat.h>
36 #include <linux/string.h>
37 #include <linux/locks.h>
38
39 static char error_buf[1024];
40
41 void ext2_error (struct super_block * sb, const char * function,
42 const char * fmt, ...)
43 {
44 va_list args;
45
46 if (!(sb->s_flags & MS_RDONLY)) {
47 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
48 sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
49 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
50 sb->s_dirt = 1;
51 }
52 va_start (args, fmt);
53 vsprintf (error_buf, fmt, args);
54 va_end (args);
55 if (test_opt (sb, ERRORS_PANIC) ||
56 (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_PANIC &&
57 !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_RO)))
58 panic ("EXT2-fs panic (device %d/%d): %s: %s\n",
59 MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
60 printk (KERN_CRIT "EXT2-fs error (device %d/%d): %s: %s\n",
61 MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
62 if (test_opt (sb, ERRORS_RO) ||
63 (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_RO &&
64 !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_PANIC))) {
65 printk ("Remounting filesystem read-only\n");
66 sb->s_flags |= MS_RDONLY;
67 }
68 }
69
70 NORET_TYPE void ext2_panic (struct super_block * sb, const char * function,
71 const char * fmt, ...)
72 {
73 va_list args;
74
75 if (!(sb->s_flags & MS_RDONLY)) {
76 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
77 sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
78 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
79 sb->s_dirt = 1;
80 }
81 va_start (args, fmt);
82 vsprintf (error_buf, fmt, args);
83 va_end (args);
84 panic ("EXT2-fs panic (device %d/%d): %s: %s\n",
85 MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
86 }
87
88 void ext2_warning (struct super_block * sb, const char * function,
89 const char * fmt, ...)
90 {
91 va_list args;
92
93 va_start (args, fmt);
94 vsprintf (error_buf, fmt, args);
95 va_end (args);
96 printk (KERN_WARNING "EXT2-fs warning (device %d/%d): %s: %s\n",
97 MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
98 }
99
100 void ext2_put_super (struct super_block * sb)
101 {
102 int db_count;
103 int i;
104
105 lock_super (sb);
106 if (!(sb->s_flags & MS_RDONLY)) {
107 sb->u.ext2_sb.s_es->s_state = sb->u.ext2_sb.s_mount_state;
108 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
109 }
110 sb->s_dev = 0;
111 db_count = sb->u.ext2_sb.s_db_per_group;
112 for (i = 0; i < db_count; i++)
113 if (sb->u.ext2_sb.s_group_desc[i])
114 brelse (sb->u.ext2_sb.s_group_desc[i]);
115 kfree_s (sb->u.ext2_sb.s_group_desc,
116 db_count * sizeof (struct buffer_head *));
117 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
118 if (sb->u.ext2_sb.s_inode_bitmap[i])
119 brelse (sb->u.ext2_sb.s_inode_bitmap[i]);
120 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
121 if (sb->u.ext2_sb.s_block_bitmap[i])
122 brelse (sb->u.ext2_sb.s_block_bitmap[i]);
123 brelse (sb->u.ext2_sb.s_sbh);
124 unlock_super (sb);
125 MOD_DEC_USE_COUNT;
126 return;
127 }
128
129 static struct super_operations ext2_sops = {
130 ext2_read_inode,
131 NULL,
132 ext2_write_inode,
133 ext2_put_inode,
134 ext2_put_super,
135 ext2_write_super,
136 ext2_statfs,
137 ext2_remount
138 };
139
140
141
142
143 static int parse_options (char * options, unsigned long * sb_block,
144 unsigned short *resuid, unsigned short * resgid,
145 unsigned long * mount_options)
146 {
147 char * this_char;
148 char * value;
149
150 if (!options)
151 return 1;
152 for (this_char = strtok (options, ",");
153 this_char != NULL;
154 this_char = strtok (NULL, ",")) {
155 if ((value = strchr (this_char, '=')) != NULL)
156 *value++ = 0;
157 if (!strcmp (this_char, "bsddf"))
158 clear_opt (*mount_options, MINIX_DF);
159 else if (!strcmp (this_char, "check")) {
160 if (!value || !*value)
161 set_opt (*mount_options, CHECK_NORMAL);
162 else if (!strcmp (value, "none")) {
163 clear_opt (*mount_options, CHECK_NORMAL);
164 clear_opt (*mount_options, CHECK_STRICT);
165 }
166 else if (strcmp (value, "normal"))
167 set_opt (*mount_options, CHECK_NORMAL);
168 else if (strcmp (value, "strict")) {
169 set_opt (*mount_options, CHECK_NORMAL);
170 set_opt (*mount_options, CHECK_STRICT);
171 }
172 else {
173 printk ("EXT2-fs: Invalid check option: %s\n",
174 value);
175 return 0;
176 }
177 }
178 else if (!strcmp (this_char, "debug"))
179 set_opt (*mount_options, DEBUG);
180 else if (!strcmp (this_char, "errors")) {
181 if (!value || !*value) {
182 printk ("EXT2-fs: the errors option requires "
183 "an argument");
184 return 0;
185 }
186 if (!strcmp (value, "continue")) {
187 clear_opt (*mount_options, ERRORS_RO);
188 clear_opt (*mount_options, ERRORS_PANIC);
189 set_opt (*mount_options, ERRORS_CONT);
190 }
191 else if (!strcmp (value, "remount-ro")) {
192 clear_opt (*mount_options, ERRORS_CONT);
193 clear_opt (*mount_options, ERRORS_PANIC);
194 set_opt (*mount_options, ERRORS_RO);
195 }
196 else if (!strcmp (value, "panic")) {
197 clear_opt (*mount_options, ERRORS_CONT);
198 clear_opt (*mount_options, ERRORS_RO);
199 set_opt (*mount_options, ERRORS_PANIC);
200 }
201 else {
202 printk ("EXT2-fs: Invalid errors option: %s\n",
203 value);
204 return 0;
205 }
206 }
207 else if (!strcmp (this_char, "grpid") ||
208 !strcmp (this_char, "bsdgroups"))
209 set_opt (*mount_options, GRPID);
210 else if (!strcmp (this_char, "minixdf"))
211 set_opt (*mount_options, MINIX_DF);
212 else if (!strcmp (this_char, "nocheck")) {
213 clear_opt (*mount_options, CHECK_NORMAL);
214 clear_opt (*mount_options, CHECK_STRICT);
215 }
216 else if (!strcmp (this_char, "nogrpid") ||
217 !strcmp (this_char, "sysvgroups"))
218 clear_opt (*mount_options, GRPID);
219 else if (!strcmp (this_char, "resgid")) {
220 if (!value || !*value) {
221 printk ("EXT2-fs: the resgid option requires "
222 "an argument");
223 return 0;
224 }
225 *resgid = simple_strtoul (value, &value, 0);
226 if (*value) {
227 printk ("EXT2-fs: Invalid resgid option: %s\n",
228 value);
229 return 0;
230 }
231 }
232 else if (!strcmp (this_char, "resuid")) {
233 if (!value || !*value) {
234 printk ("EXT2-fs: the resuid option requires "
235 "an argument");
236 return 0;
237 }
238 *resuid = simple_strtoul (value, &value, 0);
239 if (*value) {
240 printk ("EXT2-fs: Invalid resuid option: %s\n",
241 value);
242 return 0;
243 }
244 }
245 else if (!strcmp (this_char, "sb")) {
246 if (!value || !*value) {
247 printk ("EXT2-fs: the sb option requires "
248 "an argument");
249 return 0;
250 }
251 *sb_block = simple_strtoul (value, &value, 0);
252 if (*value) {
253 printk ("EXT2-fs: Invalid sb option: %s\n",
254 value);
255 return 0;
256 }
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 int 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 %d/%d.\n",
404 MAJOR(dev), MINOR(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 %d/%d.\n",
474 MAJOR(dev), MINOR(dev));
475
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 0x%04x.\n",
485 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 (sb->u.ext2_sb.s_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 char kernel_version[] = UTS_RELEASE;
691
692 static struct file_system_type ext2_fs_type = {
693 ext2_read_super, "ext2", 1, NULL
694 };
695
696 int init_module(void)
697 {
698 register_filesystem(&ext2_fs_type);
699 return 0;
700 }
701
702 void cleanup_module(void)
703 {
704 unregister_filesystem(&ext2_fs_type);
705 }
706
707 #endif
708
709 void ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
710 {
711 unsigned long overhead;
712 unsigned long overhead_per_group;
713 struct statfs tmp;
714
715 if (test_opt (sb, MINIX_DF))
716 overhead = 0;
717 else {
718
719
720
721 overhead_per_group = 1 +
722 sb->u.ext2_sb.s_db_per_group +
723 1 +
724 1 +
725 sb->u.ext2_sb.s_itb_per_group ;
726 overhead = sb->u.ext2_sb.s_es->s_first_data_block +
727 sb->u.ext2_sb.s_groups_count * overhead_per_group;
728 }
729
730 tmp.f_type = EXT2_SUPER_MAGIC;
731 tmp.f_bsize = sb->s_blocksize;
732 tmp.f_blocks = sb->u.ext2_sb.s_es->s_blocks_count - overhead;
733 tmp.f_bfree = ext2_count_free_blocks (sb);
734 tmp.f_bavail = tmp.f_bfree - sb->u.ext2_sb.s_es->s_r_blocks_count;
735 if (tmp.f_bfree < sb->u.ext2_sb.s_es->s_r_blocks_count)
736 tmp.f_bavail = 0;
737 tmp.f_files = sb->u.ext2_sb.s_es->s_inodes_count;
738 tmp.f_ffree = ext2_count_free_inodes (sb);
739 tmp.f_namelen = EXT2_NAME_LEN;
740 memcpy_tofs(buf, &tmp, bufsiz);
741 }