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 else {
253 printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
254 return 0;
255 }
256 }
257 return 1;
258 }
259
260 static void ext2_setup_super (struct super_block * sb,
261 struct ext2_super_block * es)
262 {
263 if (es->s_rev_level > EXT2_CURRENT_REV) {
264 printk ("EXT2-fs warning: revision level too high, "
265 "forcing read/only mode\n");
266 sb->s_flags |= MS_RDONLY;
267 }
268 if (!(sb->s_flags & MS_RDONLY)) {
269 if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
270 printk ("EXT2-fs warning: mounting unchecked fs, "
271 "running e2fsck is recommended\n");
272 else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS))
273 printk ("EXT2-fs warning: mounting fs with errors, "
274 "running e2fsck is recommended\n");
275 else if (es->s_max_mnt_count >= 0 &&
276 es->s_mnt_count >= (unsigned short) es->s_max_mnt_count)
277 printk ("EXT2-fs warning: maximal mount count reached, "
278 "running e2fsck is recommended\n");
279 else if (es->s_checkinterval &&
280 (es->s_lastcheck + es->s_checkinterval <= CURRENT_TIME))
281 printk ("EXT2-fs warning: checktime reached, "
282 "running e2fsck is recommended\n");
283 es->s_state &= ~EXT2_VALID_FS;
284 if (!es->s_max_mnt_count)
285 es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
286 es->s_mnt_count++;
287 es->s_mtime = CURRENT_TIME;
288 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
289 sb->s_dirt = 1;
290 if (test_opt (sb, DEBUG))
291 printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
292 "bpg=%lu, ipg=%lu, mo=%04lx]\n",
293 EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
294 sb->u.ext2_sb.s_frag_size,
295 sb->u.ext2_sb.s_groups_count,
296 EXT2_BLOCKS_PER_GROUP(sb),
297 EXT2_INODES_PER_GROUP(sb),
298 sb->u.ext2_sb.s_mount_opt);
299 if (test_opt (sb, CHECK)) {
300 ext2_check_blocks_bitmap (sb);
301 ext2_check_inodes_bitmap (sb);
302 }
303 }
304 }
305
306 static int ext2_check_descriptors (struct super_block * sb)
307 {
308 int i;
309 int desc_block = 0;
310 unsigned long block = sb->u.ext2_sb.s_es->s_first_data_block;
311 struct ext2_group_desc * gdp = NULL;
312
313 ext2_debug ("Checking group descriptors");
314
315 for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++)
316 {
317 if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
318 gdp = (struct ext2_group_desc *) sb->u.ext2_sb.s_group_desc[desc_block++]->b_data;
319 if (gdp->bg_block_bitmap < block ||
320 gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
321 {
322 ext2_error (sb, "ext2_check_descriptors",
323 "Block bitmap for group %d"
324 " not in group (block %lu)!",
325 i, (unsigned long) gdp->bg_block_bitmap);
326 return 0;
327 }
328 if (gdp->bg_inode_bitmap < block ||
329 gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
330 {
331 ext2_error (sb, "ext2_check_descriptors",
332 "Inode bitmap for group %d"
333 " not in group (block %lu)!",
334 i, (unsigned long) gdp->bg_inode_bitmap);
335 return 0;
336 }
337 if (gdp->bg_inode_table < block ||
338 gdp->bg_inode_table + sb->u.ext2_sb.s_itb_per_group >=
339 block + EXT2_BLOCKS_PER_GROUP(sb))
340 {
341 ext2_error (sb, "ext2_check_descriptors",
342 "Inode table for group %d"
343 " not in group (block %lu)!",
344 i, (unsigned long) gdp->bg_inode_table);
345 return 0;
346 }
347 block += EXT2_BLOCKS_PER_GROUP(sb);
348 gdp++;
349 }
350 return 1;
351 }
352
353 #define log2(n) ffz(~(n))
354
355 struct super_block * ext2_read_super (struct super_block * sb, void * data,
356 int silent)
357 {
358 struct buffer_head * bh;
359 struct ext2_super_block * es;
360 unsigned long sb_block = 1;
361 unsigned short resuid = EXT2_DEF_RESUID;
362 unsigned short resgid = EXT2_DEF_RESGID;
363 unsigned long logic_sb_block = 1;
364 kdev_t dev = sb->s_dev;
365 int db_count;
366 int i, j;
367
368 set_opt (sb->u.ext2_sb.s_mount_opt, CHECK_NORMAL);
369 if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
370 &sb->u.ext2_sb.s_mount_opt)) {
371 sb->s_dev = 0;
372 return NULL;
373 }
374
375 MOD_INC_USE_COUNT;
376 lock_super (sb);
377 set_blocksize (dev, BLOCK_SIZE);
378 if (!(bh = bread (dev, sb_block, BLOCK_SIZE))) {
379 sb->s_dev = 0;
380 unlock_super (sb);
381 printk ("EXT2-fs: unable to read superblock\n");
382 MOD_DEC_USE_COUNT;
383 return NULL;
384 }
385
386
387
388
389 es = (struct ext2_super_block *) bh->b_data;
390 sb->u.ext2_sb.s_es = es;
391 sb->s_magic = es->s_magic;
392 if (sb->s_magic != EXT2_SUPER_MAGIC) {
393 sb->s_dev = 0;
394 unlock_super (sb);
395 brelse (bh);
396 if (!silent)
397 printk ("VFS: Can't find an ext2 filesystem on dev "
398 "%s.\n", kdevname(dev));
399 return NULL;
400 }
401 sb->s_blocksize_bits = sb->u.ext2_sb.s_es->s_log_block_size + 10;
402 sb->s_blocksize = 1 << sb->s_blocksize_bits;
403 if (sb->s_blocksize != BLOCK_SIZE &&
404 (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||
405 sb->s_blocksize == 4096)) {
406 unsigned long offset;
407
408 brelse (bh);
409 set_blocksize (dev, sb->s_blocksize);
410 logic_sb_block = (sb_block*BLOCK_SIZE) / sb->s_blocksize;
411 offset = (sb_block*BLOCK_SIZE) % sb->s_blocksize;
412 bh = bread (dev, logic_sb_block, sb->s_blocksize);
413 if(!bh) {
414 MOD_DEC_USE_COUNT;
415 return NULL;
416 }
417 es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
418 sb->u.ext2_sb.s_es = es;
419 if (es->s_magic != EXT2_SUPER_MAGIC) {
420 sb->s_dev = 0;
421 unlock_super (sb);
422 brelse (bh);
423 printk ("EXT2-fs: Magic mismatch, very weird !\n");
424 MOD_DEC_USE_COUNT;
425 return NULL;
426 }
427 }
428 sb->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
429 es->s_log_frag_size;
430 if (sb->u.ext2_sb.s_frag_size)
431 sb->u.ext2_sb.s_frags_per_block = sb->s_blocksize /
432 sb->u.ext2_sb.s_frag_size;
433 else
434 sb->s_magic = 0;
435 sb->u.ext2_sb.s_blocks_per_group = es->s_blocks_per_group;
436 sb->u.ext2_sb.s_frags_per_group = es->s_frags_per_group;
437 sb->u.ext2_sb.s_inodes_per_group = es->s_inodes_per_group;
438 sb->u.ext2_sb.s_inodes_per_block = sb->s_blocksize /
439 sizeof (struct ext2_inode);
440 sb->u.ext2_sb.s_itb_per_group = sb->u.ext2_sb.s_inodes_per_group /
441 sb->u.ext2_sb.s_inodes_per_block;
442 sb->u.ext2_sb.s_desc_per_block = sb->s_blocksize /
443 sizeof (struct ext2_group_desc);
444 sb->u.ext2_sb.s_sbh = bh;
445 if (resuid != EXT2_DEF_RESUID)
446 sb->u.ext2_sb.s_resuid = resuid;
447 else
448 sb->u.ext2_sb.s_resuid = es->s_def_resuid;
449 if (resgid != EXT2_DEF_RESGID)
450 sb->u.ext2_sb.s_resgid = resgid;
451 else
452 sb->u.ext2_sb.s_resgid = es->s_def_resgid;
453 sb->u.ext2_sb.s_mount_state = es->s_state;
454 sb->u.ext2_sb.s_rename_lock = 0;
455 sb->u.ext2_sb.s_rename_wait = NULL;
456 sb->u.ext2_sb.s_addr_per_block_bits =
457 log2 (EXT2_ADDR_PER_BLOCK(sb));
458 sb->u.ext2_sb.s_inodes_per_block_bits =
459 log2 (EXT2_INODES_PER_BLOCK(sb));
460 sb->u.ext2_sb.s_desc_per_block_bits =
461 log2 (EXT2_DESC_PER_BLOCK(sb));
462 if (sb->s_magic != EXT2_SUPER_MAGIC) {
463 sb->s_dev = 0;
464 unlock_super (sb);
465 brelse (bh);
466 if (!silent)
467 printk ("VFS: Can't find an ext2 filesystem on dev "
468 "%s.\n",
469 kdevname(dev));
470 MOD_DEC_USE_COUNT;
471 return NULL;
472 }
473 if (sb->s_blocksize != bh->b_size) {
474 sb->s_dev = 0;
475 unlock_super (sb);
476 brelse (bh);
477 if (!silent)
478 printk ("VFS: Unsupported blocksize on dev "
479 "%s.\n", kdevname(dev));
480 MOD_DEC_USE_COUNT;
481 return NULL;
482 }
483
484 if (sb->s_blocksize != sb->u.ext2_sb.s_frag_size) {
485 sb->s_dev = 0;
486 unlock_super (sb);
487 brelse (bh);
488 printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",
489 sb->u.ext2_sb.s_frag_size, sb->s_blocksize);
490 MOD_DEC_USE_COUNT;
491 return NULL;
492 }
493
494 if (sb->u.ext2_sb.s_blocks_per_group > sb->s_blocksize * 8) {
495 sb->s_dev = 0;
496 unlock_super (sb);
497 brelse (bh);
498 printk ("EXT2-fs: #blocks per group too big: %lu\n",
499 sb->u.ext2_sb.s_blocks_per_group);
500 MOD_DEC_USE_COUNT;
501 return NULL;
502 }
503 if (sb->u.ext2_sb.s_frags_per_group > sb->s_blocksize * 8) {
504 sb->s_dev = 0;
505 unlock_super (sb);
506 brelse (bh);
507 printk ("EXT2-fs: #fragments per group too big: %lu\n",
508 sb->u.ext2_sb.s_frags_per_group);
509 MOD_DEC_USE_COUNT;
510 return NULL;
511 }
512 if (sb->u.ext2_sb.s_inodes_per_group > sb->s_blocksize * 8) {
513 sb->s_dev = 0;
514 unlock_super (sb);
515 brelse (bh);
516 printk ("EXT2-fs: #inodes per group too big: %lu\n",
517 sb->u.ext2_sb.s_inodes_per_group);
518 MOD_DEC_USE_COUNT;
519 return NULL;
520 }
521
522 sb->u.ext2_sb.s_groups_count = (es->s_blocks_count -
523 es->s_first_data_block +
524 EXT2_BLOCKS_PER_GROUP(sb) - 1) /
525 EXT2_BLOCKS_PER_GROUP(sb);
526 db_count = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
527 EXT2_DESC_PER_BLOCK(sb);
528 sb->u.ext2_sb.s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL);
529 if (sb->u.ext2_sb.s_group_desc == NULL) {
530 sb->s_dev = 0;
531 unlock_super (sb);
532 brelse (bh);
533 printk ("EXT2-fs: not enough memory\n");
534 MOD_DEC_USE_COUNT;
535 return NULL;
536 }
537 for (i = 0; i < db_count; i++) {
538 sb->u.ext2_sb.s_group_desc[i] = bread (dev, logic_sb_block + i + 1,
539 sb->s_blocksize);
540 if (!sb->u.ext2_sb.s_group_desc[i]) {
541 sb->s_dev = 0;
542 unlock_super (sb);
543 for (j = 0; j < i; j++)
544 brelse (sb->u.ext2_sb.s_group_desc[j]);
545 kfree_s (sb->u.ext2_sb.s_group_desc,
546 db_count * sizeof (struct buffer_head *));
547 brelse (bh);
548 printk ("EXT2-fs: unable to read group descriptors\n");
549 MOD_DEC_USE_COUNT;
550 return NULL;
551 }
552 }
553 if (!ext2_check_descriptors (sb)) {
554 sb->s_dev = 0;
555 unlock_super (sb);
556 for (j = 0; j < db_count; j++)
557 brelse (sb->u.ext2_sb.s_group_desc[j]);
558 kfree_s (sb->u.ext2_sb.s_group_desc,
559 db_count * sizeof (struct buffer_head *));
560 brelse (bh);
561 printk ("EXT2-fs: group descriptors corrupted !\n");
562 MOD_DEC_USE_COUNT;
563 return NULL;
564 }
565 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
566 sb->u.ext2_sb.s_inode_bitmap_number[i] = 0;
567 sb->u.ext2_sb.s_inode_bitmap[i] = NULL;
568 sb->u.ext2_sb.s_block_bitmap_number[i] = 0;
569 sb->u.ext2_sb.s_block_bitmap[i] = NULL;
570 }
571 sb->u.ext2_sb.s_loaded_inode_bitmaps = 0;
572 sb->u.ext2_sb.s_loaded_block_bitmaps = 0;
573 sb->u.ext2_sb.s_db_per_group = db_count;
574 unlock_super (sb);
575
576
577
578 sb->s_dev = dev;
579 sb->s_op = &ext2_sops;
580 if (!(sb->s_mounted = iget (sb, EXT2_ROOT_INO))) {
581 sb->s_dev = 0;
582 for (i = 0; i < db_count; i++)
583 if (sb->u.ext2_sb.s_group_desc[i])
584 brelse (sb->u.ext2_sb.s_group_desc[i]);
585 kfree_s (sb->u.ext2_sb.s_group_desc,
586 db_count * sizeof (struct buffer_head *));
587 brelse (bh);
588 printk ("EXT2-fs: get root inode failed\n");
589 MOD_DEC_USE_COUNT;
590 return NULL;
591 }
592 ext2_setup_super (sb, es);
593 return sb;
594 }
595
596 static void ext2_commit_super (struct super_block * sb,
597 struct ext2_super_block * es)
598 {
599 es->s_wtime = CURRENT_TIME;
600 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
601 sb->s_dirt = 0;
602 }
603
604
605
606
607
608
609
610
611
612
613
614
615 void ext2_write_super (struct super_block * sb)
616 {
617 struct ext2_super_block * es;
618
619 if (!(sb->s_flags & MS_RDONLY)) {
620 es = sb->u.ext2_sb.s_es;
621
622 ext2_debug ("setting valid to 0\n");
623
624 if (es->s_state & EXT2_VALID_FS) {
625 es->s_state &= ~EXT2_VALID_FS;
626 es->s_mtime = CURRENT_TIME;
627 }
628 ext2_commit_super (sb, es);
629 }
630 sb->s_dirt = 0;
631 }
632
633 int ext2_remount (struct super_block * sb, int * flags, char * data)
634 {
635 struct ext2_super_block * es;
636 unsigned short resuid = sb->u.ext2_sb.s_resuid;
637 unsigned short resgid = sb->u.ext2_sb.s_resgid;
638 unsigned long new_mount_opt;
639 unsigned long tmp;
640
641
642
643
644 set_opt (new_mount_opt, CHECK_NORMAL);
645 if (!parse_options (data, &tmp, &resuid, &resgid,
646 &new_mount_opt))
647 return -EINVAL;
648
649 sb->u.ext2_sb.s_mount_opt = new_mount_opt;
650 sb->u.ext2_sb.s_resuid = resuid;
651 sb->u.ext2_sb.s_resgid = resgid;
652 es = sb->u.ext2_sb.s_es;
653 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
654 return 0;
655 if (*flags & MS_RDONLY) {
656 if (es->s_state & EXT2_VALID_FS ||
657 !(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
658 return 0;
659
660
661
662
663 es->s_state = sb->u.ext2_sb.s_mount_state;
664 es->s_mtime = CURRENT_TIME;
665 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
666 sb->s_dirt = 1;
667 ext2_commit_super (sb, es);
668 }
669 else {
670
671
672
673
674
675 sb->u.ext2_sb.s_mount_state = es->s_state;
676 sb->s_flags &= ~MS_RDONLY;
677 ext2_setup_super (sb, es);
678 }
679 return 0;
680 }
681
682 #ifdef MODULE
683
684 static struct file_system_type ext2_fs_type = {
685 ext2_read_super, "ext2", 1, NULL
686 };
687
688 int init_module(void)
689 {
690 return register_filesystem(&ext2_fs_type);
691 }
692
693 void cleanup_module(void)
694 {
695 unregister_filesystem(&ext2_fs_type);
696 }
697
698 #endif
699
700 void ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
701 {
702 unsigned long overhead;
703 unsigned long overhead_per_group;
704 struct statfs tmp;
705
706 if (test_opt (sb, MINIX_DF))
707 overhead = 0;
708 else {
709
710
711
712 overhead_per_group = 1 +
713 sb->u.ext2_sb.s_db_per_group +
714 1 +
715 1 +
716 sb->u.ext2_sb.s_itb_per_group ;
717 overhead = sb->u.ext2_sb.s_es->s_first_data_block +
718 sb->u.ext2_sb.s_groups_count * overhead_per_group;
719 }
720
721 tmp.f_type = EXT2_SUPER_MAGIC;
722 tmp.f_bsize = sb->s_blocksize;
723 tmp.f_blocks = sb->u.ext2_sb.s_es->s_blocks_count - overhead;
724 tmp.f_bfree = ext2_count_free_blocks (sb);
725 tmp.f_bavail = tmp.f_bfree - sb->u.ext2_sb.s_es->s_r_blocks_count;
726 if (tmp.f_bfree < sb->u.ext2_sb.s_es->s_r_blocks_count)
727 tmp.f_bavail = 0;
728 tmp.f_files = sb->u.ext2_sb.s_es->s_inodes_count;
729 tmp.f_ffree = ext2_count_free_inodes (sb);
730 tmp.f_namelen = EXT2_NAME_LEN;
731 memcpy_tofs(buf, &tmp, bufsiz);
732 }