This source file includes following definitions.
- ext2_error
- ext2_panic
- ext2_warning
- ext2_put_super
- convert_pre_02b_fs
- parse_options
- ext2_read_super
- ext2_commit_super
- ext2_write_super
- ext2_remount
- ext2_statfs
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <stdarg.h>
14
15 #include <asm/segment.h>
16 #include <asm/system.h>
17
18 #include <linux/errno.h>
19 #include <linux/fs.h>
20 #include <linux/ext2_fs.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/stat.h>
24 #include <linux/string.h>
25 #include <linux/locks.h>
26
27 extern int vsprintf (char *, const char *, va_list);
28
29 void ext2_error (struct super_block * sb, const char * function,
30 const char * fmt, ...)
31 {
32 char buf[1024];
33 va_list args;
34
35 if (!(sb->s_flags & MS_RDONLY)) {
36 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
37 sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
38 sb->u.ext2_sb.s_sbh->b_dirt = 1;
39 sb->s_dirt = 1;
40 }
41 va_start (args, fmt);
42 vsprintf (buf, fmt, args);
43 va_end (args);
44 printk (
45 #ifdef KERN_ERR
46 KERN_ERR
47 #endif
48 "EXT2-fs error (device %d/%d): %s: %s\n",
49 MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);
50 }
51
52 volatile void ext2_panic (struct super_block * sb, const char * function,
53 const char * fmt, ...)
54 {
55 char buf[1024];
56 va_list args;
57
58 if (!(sb->s_flags & MS_RDONLY)) {
59 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
60 sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
61 sb->u.ext2_sb.s_sbh->b_dirt = 1;
62 sb->s_dirt = 1;
63 }
64 va_start (args, fmt);
65 vsprintf (buf, fmt, args);
66 va_end (args);
67 panic ("EXT2-fs panic (device %d/%d): %s: %s\n",
68 MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);
69 }
70
71 void ext2_warning (struct super_block * sb, const char * function,
72 const char * fmt, ...)
73 {
74 char buf[1024];
75 va_list args;
76
77 va_start (args, fmt);
78 vsprintf (buf, fmt, args);
79 va_end (args);
80 printk (
81 #ifdef KERN_WARNING
82 KERN_WARNING
83 #endif
84 "EXT2-fs warning (device %d/%d): %s: %s\n",
85 MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);
86 }
87
88 void ext2_put_super (struct super_block * sb)
89 {
90 int i;
91
92 lock_super (sb);
93 if (!(sb->s_flags & MS_RDONLY)) {
94 sb->u.ext2_sb.s_es->s_state = sb->u.ext2_sb.s_mount_state;
95 sb->u.ext2_sb.s_sbh->b_dirt = 1;
96 }
97 #ifndef DONT_USE_DCACHE
98 ext2_dcache_invalidate (sb->s_dev);
99 #endif
100 sb->s_dev = 0;
101 for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
102 if (sb->u.ext2_sb.s_group_desc[i])
103 brelse (sb->u.ext2_sb.s_group_desc[i]);
104 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
105 if (sb->u.ext2_sb.s_inode_bitmap[i])
106 brelse (sb->u.ext2_sb.s_inode_bitmap[i]);
107 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
108 if (sb->u.ext2_sb.s_block_bitmap[i])
109 brelse (sb->u.ext2_sb.s_block_bitmap[i]);
110 brelse (sb->u.ext2_sb.s_sbh);
111 unlock_super (sb);
112 return;
113 }
114
115 static struct super_operations ext2_sops = {
116 ext2_read_inode,
117 NULL,
118 ext2_write_inode,
119 ext2_put_inode,
120 ext2_put_super,
121 ext2_write_super,
122 ext2_statfs,
123 ext2_remount
124 };
125
126 #ifdef EXT2FS_PRE_02B_COMPAT
127
128 static int convert_pre_02b_fs (struct super_block * sb,
129 struct buffer_head * bh)
130 {
131 struct ext2_super_block * es;
132 struct ext2_old_group_desc old_group_desc [BLOCK_SIZE / sizeof (struct ext2_old_group_desc)];
133 struct ext2_group_desc * gdp;
134 struct buffer_head * bh2;
135 int groups_count;
136 int i;
137
138 es = (struct ext2_super_block *) bh->b_data;
139 bh2 = bread (sb->s_dev, 2, BLOCK_SIZE);
140 if (!bh2) {
141 printk ("Cannot read descriptor blocks while converting !\n");
142 return 0;
143 }
144 memcpy (old_group_desc, bh2->b_data, BLOCK_SIZE);
145 groups_count = (sb->u.ext2_sb.s_blocks_count -
146 sb->u.ext2_sb.s_first_data_block +
147 (EXT2_BLOCK_SIZE(sb) * 8) - 1) /
148 (EXT2_BLOCK_SIZE(sb) * 8);
149 memset (bh2->b_data, 0, BLOCK_SIZE);
150 gdp = (struct ext2_group_desc *) bh2->b_data;
151 for (i = 0; i < groups_count; i++) {
152 gdp[i].bg_block_bitmap = old_group_desc[i].bg_block_bitmap;
153 gdp[i].bg_inode_bitmap = old_group_desc[i].bg_inode_bitmap;
154 gdp[i].bg_inode_table = old_group_desc[i].bg_inode_table;
155 gdp[i].bg_free_blocks_count = old_group_desc[i].bg_free_blocks_count;
156 gdp[i].bg_free_inodes_count = old_group_desc[i].bg_free_inodes_count;
157 }
158 bh2->b_dirt = 1;
159 brelse (bh2);
160 es->s_magic = EXT2_SUPER_MAGIC;
161 bh->b_dirt = 1;
162 sb->s_magic = EXT2_SUPER_MAGIC;
163 return 1;
164 }
165
166 #endif
167
168
169
170
171 static int parse_options (char * options, unsigned long * sb_block,
172 unsigned long * mount_options)
173 {
174 char * this_char;
175 char * value;
176
177 if (!options)
178 return 1;
179 for (this_char = strtok (options, ",");
180 this_char != NULL;
181 this_char = strtok (NULL, ",")) {
182 if ((value = strchr (this_char, '=')) != NULL)
183 *value++ = 0;
184 if (!strcmp (this_char, "check"))
185 *mount_options |= EXT2_MOUNT_CHECK;
186 else if (!strcmp (this_char, "sb")) {
187 if (!value || !*value)
188 return 0;
189 *sb_block = simple_strtoul (value, &value, 0);
190 if (*value)
191 return 0;
192 }
193 else {
194 printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
195 return 0;
196 }
197 }
198 return 1;
199 }
200
201 struct super_block * ext2_read_super (struct super_block * s, void * data,
202 int silent)
203 {
204 struct buffer_head * bh;
205 struct ext2_super_block * es;
206 unsigned long sb_block = 1;
207 unsigned long logic_sb_block = 1;
208 int dev = s->s_dev;
209 int bh_count;
210 int i, j;
211 #ifdef EXT2FS_PRE_02B_COMPAT
212 int fs_converted = 0;
213 #endif
214
215 s->u.ext2_sb.s_mount_opt = 0;
216 if (!parse_options ((char *) data, &sb_block,
217 &s->u.ext2_sb.s_mount_opt)) {
218 s->s_dev = 0;
219 return NULL;
220 }
221
222 lock_super (s);
223 set_blocksize (dev, BLOCK_SIZE);
224 if (!(bh = bread (dev, sb_block, BLOCK_SIZE))) {
225 s->s_dev = 0;
226 unlock_super (s);
227 printk ("EXT2-fs: unable to read superblock\n");
228 return NULL;
229 }
230 es = (struct ext2_super_block *) bh->b_data;
231
232
233 s->u.ext2_sb.s_es = es;
234 s->s_magic = es->s_magic;
235 if (s->s_magic != EXT2_SUPER_MAGIC
236 #ifdef EXT2FS_PRE_02B_COMPAT
237 && s->s_magic != EXT2_PRE_02B_MAGIC
238 #endif
239 ) {
240 s->s_dev = 0;
241 unlock_super (s);
242 brelse (bh);
243 if (!silent)
244 printk ("VFS: Can't find an ext2 filesystem on dev 0x%04x.\n",
245 dev);
246 return NULL;
247 }
248 s->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
249 s->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(s);
250 if (s->s_blocksize != BLOCK_SIZE &&
251 (s->s_blocksize == 1024 || s->s_blocksize == 2048 ||
252 s->s_blocksize == 4096)) {
253 unsigned long offset;
254
255 brelse (bh);
256 set_blocksize (dev, s->s_blocksize);
257 logic_sb_block = sb_block / s->s_blocksize;
258 offset = sb_block % s->s_blocksize;
259 bh = bread (dev, logic_sb_block, s->s_blocksize);
260 if(!bh)
261 return NULL;
262 es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
263 s->u.ext2_sb.s_es = es;
264 if (es->s_magic != EXT2_SUPER_MAGIC) {
265 s->s_dev = 0;
266 unlock_super (s);
267 brelse (bh);
268 printk ("EXT2-fs: Magic mismatch, very weird !\n");
269 return NULL;
270 }
271 }
272 s->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
273 es->s_log_frag_size;
274 if (s->u.ext2_sb.s_frag_size)
275 s->u.ext2_sb.s_frags_per_block = s->s_blocksize /
276 s->u.ext2_sb.s_frag_size;
277 else
278 s->s_magic = 0;
279 s->u.ext2_sb.s_blocks_per_group = es->s_blocks_per_group;
280 s->u.ext2_sb.s_frags_per_group = es->s_frags_per_group;
281 s->u.ext2_sb.s_inodes_per_group = es->s_inodes_per_group;
282 s->u.ext2_sb.s_inodes_per_block = s->s_blocksize /
283 sizeof (struct ext2_inode);
284 s->u.ext2_sb.s_desc_per_block = s->s_blocksize /
285 sizeof (struct ext2_group_desc);
286 s->u.ext2_sb.s_sbh = bh;
287 s->u.ext2_sb.s_es = es;
288 s->u.ext2_sb.s_mount_state = es->s_state;
289 s->u.ext2_sb.s_rename_lock = 0;
290 s->u.ext2_sb.s_rename_wait = NULL;
291 #ifdef EXT2FS_PRE_02B_COMPAT
292 if (s->s_magic == EXT2_PRE_02B_MAGIC) {
293 if (es->s_blocks_count > 262144) {
294
295 s->s_dev = 0;
296 unlock_super (s);
297 brelse (bh);
298 printk ("EXT2-fs: trying to mount a pre-0.2b file"
299 "system which cannot be converted\n");
300 return NULL;
301 }
302 printk ("EXT2-fs: mounting a pre 0.2b file system, "
303 "will try to convert the structure\n");
304 if (!(s->s_flags & MS_RDONLY)) {
305 s->s_dev = 0;
306 unlock_super (s);
307 brelse (bh);
308 printk ("EXT2-fs: cannot convert a read-only fs\n");
309 return NULL;
310 }
311 if (!convert_pre_02b_fs (s, bh)) {
312 s->s_dev = 0;
313 unlock_super (s);
314 brelse (bh);
315 printk ("EXT2-fs: conversion failed !!!\n");
316 return NULL;
317 }
318 printk ("EXT2-fs: conversion succeeded !!!\n");
319 fs_converted = 1;
320 }
321 #endif
322 if (s->s_magic != EXT2_SUPER_MAGIC) {
323 s->s_dev = 0;
324 unlock_super (s);
325 brelse (bh);
326 if (!silent)
327 printk ("VFS: Can't find an ext2 filesystem on dev 0x%04x.\n",
328 dev);
329 return NULL;
330 }
331 if (s->s_blocksize != bh->b_size) {
332 s->s_dev = 0;
333 unlock_super (s);
334 brelse (bh);
335 if (!silent)
336 printk ("VFS: Unsupported blocksize on dev 0x%04x.\n",
337 dev);
338 return NULL;
339 }
340
341 if (s->s_blocksize != s->u.ext2_sb.s_frag_size) {
342 s->s_dev = 0;
343 unlock_super (s);
344 brelse (bh);
345 printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",
346 s->u.ext2_sb.s_frag_size, s->s_blocksize);
347 return NULL;
348 }
349
350 s->u.ext2_sb.s_groups_count = (es->s_blocks_count -
351 es->s_first_data_block +
352 EXT2_BLOCKS_PER_GROUP(s) - 1) /
353 EXT2_BLOCKS_PER_GROUP(s);
354 for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
355 s->u.ext2_sb.s_group_desc[i] = NULL;
356 bh_count = (s->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(s) - 1) /
357 EXT2_DESC_PER_BLOCK(s);
358 if (bh_count > EXT2_MAX_GROUP_DESC) {
359 s->s_dev = 0;
360 unlock_super (s);
361 brelse (bh);
362 printk ("EXT2-fs: file system is too big\n");
363 return NULL;
364 }
365 for (i = 0; i < bh_count; i++) {
366 s->u.ext2_sb.s_group_desc[i] = bread (dev, logic_sb_block + i + 1,
367 s->s_blocksize);
368 if (!s->u.ext2_sb.s_group_desc[i]) {
369 s->s_dev = 0;
370 unlock_super (s);
371 for (j = 0; j < i; j++)
372 brelse (s->u.ext2_sb.s_group_desc[i]);
373 brelse (bh);
374 printk ("EXT2-fs: unable to read group descriptors\n");
375 return NULL;
376 }
377 }
378 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
379 s->u.ext2_sb.s_inode_bitmap_number[i] = 0;
380 s->u.ext2_sb.s_inode_bitmap[i] = NULL;
381 s->u.ext2_sb.s_block_bitmap_number[i] = 0;
382 s->u.ext2_sb.s_block_bitmap[i] = NULL;
383 }
384 s->u.ext2_sb.s_loaded_inode_bitmaps = 0;
385 s->u.ext2_sb.s_loaded_block_bitmaps = 0;
386 unlock_super (s);
387
388 s->s_dev = dev;
389 s->s_op = &ext2_sops;
390 if (!(s->s_mounted = iget (s, EXT2_ROOT_INO))) {
391 s->s_dev = 0;
392 for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
393 if (s->u.ext2_sb.s_group_desc[i])
394 brelse (s->u.ext2_sb.s_group_desc[i]);
395 brelse (bh);
396 printk ("EXT2-fs: get root inode failed\n");
397 return NULL;
398 }
399 if (!(s->s_flags & MS_RDONLY)) {
400 es->s_state &= ~EXT2_VALID_FS;
401 if (!es->s_max_mnt_count)
402 es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
403 es->s_mnt_count++;
404 es->s_mtime = CURRENT_TIME;
405 bh->b_dirt = 1;
406 s->s_dirt = 1;
407 }
408 #ifdef EXT2FS_PRE_02B_COMPAT
409 if (fs_converted) {
410 for (i = 0; i < bh_count; i++)
411 s->u.ext2_sb.s_group_desc[i]->b_dirt = 1;
412 s->s_dirt = 1;
413 }
414 #endif
415 if (!(s->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
416 printk ("EXT2-fs warning: mounting unchecked file system, "
417 "running e2fsck is recommended\n");
418 else if (s->u.ext2_sb.s_mount_state & EXT2_ERROR_FS)
419 printk ("EXT2-fs warning: mounting file system with errors, "
420 "running e2fsck is recommended\n");
421 else if (es->s_mnt_count >= es->s_max_mnt_count)
422 printk ("EXT2-fs warning: maximal mount count reached, "
423 "running e2fsck is recommended\n");
424 if (s->u.ext2_sb.s_mount_opt & EXT2_MOUNT_CHECK) {
425 printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, bpg=%lu, ipg=%lu]\n",
426 EXT2FS_VERSION, EXT2FS_DATE, s->s_blocksize,
427 s->u.ext2_sb.s_frag_size, s->u.ext2_sb.s_groups_count,
428 EXT2_BLOCKS_PER_GROUP(s), EXT2_INODES_PER_GROUP(s));
429 ext2_check_blocks_bitmap (s);
430 ext2_check_inodes_bitmap (s);
431 }
432 return s;
433 }
434
435 static void ext2_commit_super (struct super_block * sb,
436 struct ext2_super_block * es)
437 {
438 es->s_wtime = CURRENT_TIME;
439 sb->u.ext2_sb.s_sbh->b_dirt = 1;
440 sb->s_dirt = 0;
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454 void ext2_write_super (struct super_block * sb)
455 {
456 struct ext2_super_block * es;
457
458 if (!(sb->s_flags & MS_RDONLY)) {
459 es = sb->u.ext2_sb.s_es;
460
461 ext2_debug ("setting valid to 0\n");
462
463 if (es->s_state & EXT2_VALID_FS) {
464 es->s_state &= ~EXT2_VALID_FS;
465 es->s_mtime = CURRENT_TIME;
466 }
467 ext2_commit_super (sb, es);
468 }
469 sb->s_dirt = 0;
470 }
471
472 int ext2_remount (struct super_block * sb, int * flags)
473 {
474 struct ext2_super_block * es;
475
476 es = sb->u.ext2_sb.s_es;
477 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
478 return 0;
479 if (*flags & MS_RDONLY) {
480 if (es->s_state & EXT2_VALID_FS ||
481 !(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
482 return 0;
483
484
485
486 es->s_state = sb->u.ext2_sb.s_mount_state;
487 es->s_mtime = CURRENT_TIME;
488 sb->u.ext2_sb.s_sbh->b_dirt = 1;
489 sb->s_dirt = 1;
490 ext2_commit_super (sb, es);
491 }
492 else {
493
494
495
496 sb->u.ext2_sb.s_mount_state = es->s_state;
497 es->s_state &= ~EXT2_VALID_FS;
498 if (!es->s_max_mnt_count)
499 es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
500 es->s_mnt_count++;
501 es->s_mtime = CURRENT_TIME;
502 sb->u.ext2_sb.s_sbh->b_dirt = 1;
503 sb->s_dirt = 1;
504 if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
505 printk ("EXT2-fs warning: remounting unchecked fs, "
506 "running e2fsck is recommended\n");
507 else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS))
508 printk ("EXT2-fs warning: remounting fs with errors, "
509 "running e2fsck is recommended\n");
510 else if (es->s_mnt_count >= es->s_max_mnt_count)
511 printk ("EXT2-fs warning: maximal mount count reached, "
512 "running e2fsck is recommended\n");
513 }
514 return 0;
515 }
516
517 void ext2_statfs (struct super_block * sb, struct statfs * buf)
518 {
519 long tmp;
520
521 put_fs_long (EXT2_SUPER_MAGIC, &buf->f_type);
522 put_fs_long (sb->s_blocksize, &buf->f_bsize);
523 put_fs_long (sb->u.ext2_sb.s_es->s_blocks_count, &buf->f_blocks);
524 tmp = ext2_count_free_blocks (sb);
525 put_fs_long (tmp, &buf->f_bfree);
526 if (tmp >= sb->u.ext2_sb.s_es->s_r_blocks_count)
527 put_fs_long (tmp - sb->u.ext2_sb.s_es->s_r_blocks_count,
528 &buf->f_bavail);
529 else
530 put_fs_long (0, &buf->f_bavail);
531 put_fs_long (sb->u.ext2_sb.s_es->s_inodes_count, &buf->f_files);
532 put_fs_long (ext2_count_free_inodes (sb), &buf->f_ffree);
533 put_fs_long (EXT2_NAME_LEN, &buf->f_namelen);
534
535 }