~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/ext2/super.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/fs/ext2/super.c
  3  *
  4  * Copyright (C) 1992, 1993, 1994, 1995
  5  * Remy Card (card@masi.ibp.fr)
  6  * Laboratoire MASI - Institut Blaise Pascal
  7  * Universite Pierre et Marie Curie (Paris VI)
  8  *
  9  *  from
 10  *
 11  *  linux/fs/minix/inode.c
 12  *
 13  *  Copyright (C) 1991, 1992  Linus Torvalds
 14  *
 15  *  Big-endian to little-endian byte-swapping/bitmaps by
 16  *        David S. Miller (davem@caip.rutgers.edu), 1995
 17  */
 18 
 19 #include <linux/config.h>
 20 #include <linux/module.h>
 21 #include <linux/string.h>
 22 #include <linux/fs.h>
 23 #include <linux/ext2_fs.h>
 24 #include <linux/slab.h>
 25 #include <linux/init.h>
 26 #include <linux/locks.h>
 27 #include <asm/uaccess.h>
 28 
 29 
 30 
 31 static char error_buf[1024];
 32 
 33 void ext2_error (struct super_block * sb, const char * function,
 34                  const char * fmt, ...)
 35 {
 36         va_list args;
 37 
 38         if (!(sb->s_flags & MS_RDONLY)) {
 39                 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
 40                 sb->u.ext2_sb.s_es->s_state =
 41                         cpu_to_le16(le16_to_cpu(sb->u.ext2_sb.s_es->s_state) | EXT2_ERROR_FS);
 42                 mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
 43                 sb->s_dirt = 1;
 44         }
 45         va_start (args, fmt);
 46         vsprintf (error_buf, fmt, args);
 47         va_end (args);
 48         if (test_opt (sb, ERRORS_PANIC) ||
 49             (le16_to_cpu(sb->u.ext2_sb.s_es->s_errors) == EXT2_ERRORS_PANIC &&
 50              !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_RO)))
 51                 panic ("EXT2-fs panic (device %s): %s: %s\n",
 52                        bdevname(sb->s_dev), function, error_buf);
 53         printk (KERN_CRIT "EXT2-fs error (device %s): %s: %s\n",
 54                 bdevname(sb->s_dev), function, error_buf);
 55         if (test_opt (sb, ERRORS_RO) ||
 56             (le16_to_cpu(sb->u.ext2_sb.s_es->s_errors) == EXT2_ERRORS_RO &&
 57              !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_PANIC))) {
 58                 printk ("Remounting filesystem read-only\n");
 59                 sb->s_flags |= MS_RDONLY;
 60         }
 61 }
 62 
 63 NORET_TYPE void ext2_panic (struct super_block * sb, const char * function,
 64                             const char * fmt, ...)
 65 {
 66         va_list args;
 67 
 68         if (!(sb->s_flags & MS_RDONLY)) {
 69                 sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
 70                 sb->u.ext2_sb.s_es->s_state =
 71                         cpu_to_le16(le16_to_cpu(sb->u.ext2_sb.s_es->s_state) | EXT2_ERROR_FS);
 72                 mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
 73                 sb->s_dirt = 1;
 74         }
 75         va_start (args, fmt);
 76         vsprintf (error_buf, fmt, args);
 77         va_end (args);
 78         /* this is to prevent panic from syncing this filesystem */
 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                bdevname(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                 bdevname(sb->s_dev), function, error_buf);
 96 }
 97 
 98 void ext2_update_dynamic_rev(struct super_block *sb)
 99 {
100         struct ext2_super_block *es = EXT2_SB(sb)->s_es;
101 
102         if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV)
103                 return;
104 
105         ext2_warning(sb, __FUNCTION__,
106                      "updating to rev %d because of new feature flag, "
107                      "running e2fsck is recommended",
108                      EXT2_DYNAMIC_REV);
109 
110         es->s_first_ino = cpu_to_le32(EXT2_GOOD_OLD_FIRST_INO);
111         es->s_inode_size = cpu_to_le16(EXT2_GOOD_OLD_INODE_SIZE);
112         es->s_rev_level = cpu_to_le32(EXT2_DYNAMIC_REV);
113         /* leave es->s_feature_*compat flags alone */
114         /* es->s_uuid will be set by e2fsck if empty */
115 
116         /*
117          * The rest of the superblock fields should be zero, and if not it
118          * means they are likely already in use, so leave them alone.  We
119          * can leave it up to e2fsck to clean up any inconsistencies there.
120          */
121 }
122 
123 void ext2_put_super (struct super_block * sb)
124 {
125         int db_count;
126         int i;
127 
128         if (!(sb->s_flags & MS_RDONLY)) {
129                 sb->u.ext2_sb.s_es->s_state = le16_to_cpu(sb->u.ext2_sb.s_mount_state);
130                 mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
131         }
132         db_count = EXT2_SB(sb)->s_gdb_count;
133         for (i = 0; i < db_count; i++)
134                 if (sb->u.ext2_sb.s_group_desc[i])
135                         brelse (sb->u.ext2_sb.s_group_desc[i]);
136         kfree(sb->u.ext2_sb.s_group_desc);
137         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
138                 if (sb->u.ext2_sb.s_inode_bitmap[i])
139                         brelse (sb->u.ext2_sb.s_inode_bitmap[i]);
140         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
141                 if (sb->u.ext2_sb.s_block_bitmap[i])
142                         brelse (sb->u.ext2_sb.s_block_bitmap[i]);
143         brelse (sb->u.ext2_sb.s_sbh);
144 
145         return;
146 }
147 
148 static struct super_operations ext2_sops = {
149         read_inode:     ext2_read_inode,
150         write_inode:    ext2_write_inode,
151         put_inode:      ext2_put_inode,
152         delete_inode:   ext2_delete_inode,
153         put_super:      ext2_put_super,
154         write_super:    ext2_write_super,
155         statfs:         ext2_statfs,
156         remount_fs:     ext2_remount,
157 };
158 
159 /*
160  * This function has been shamelessly adapted from the msdos fs
161  */
162 static int parse_options (char * options, unsigned long * sb_block,
163                           unsigned short *resuid, unsigned short * resgid,
164                           unsigned long * mount_options)
165 {
166         char * this_char;
167         char * value;
168 
169         if (!options)
170                 return 1;
171         for (this_char = strtok (options, ",");
172              this_char != NULL;
173              this_char = strtok (NULL, ",")) {
174                 if ((value = strchr (this_char, '=')) != NULL)
175                         *value++ = 0;
176                 if (!strcmp (this_char, "bsddf"))
177                         clear_opt (*mount_options, MINIX_DF);
178                 else if (!strcmp (this_char, "nouid32")) {
179                         set_opt (*mount_options, NO_UID32);
180                 }
181                 else if (!strcmp (this_char, "check")) {
182                         if (!value || !*value || !strcmp (value, "none"))
183                                 clear_opt (*mount_options, CHECK);
184                         else
185 #ifdef CONFIG_EXT2_CHECK
186                                 set_opt (*mount_options, CHECK);
187 #else
188                                 printk("EXT2 Check option not supported\n");
189 #endif
190                 }
191                 else if (!strcmp (this_char, "debug"))
192                         set_opt (*mount_options, DEBUG);
193                 else if (!strcmp (this_char, "errors")) {
194                         if (!value || !*value) {
195                                 printk ("EXT2-fs: the errors option requires "
196                                         "an argument\n");
197                                 return 0;
198                         }
199                         if (!strcmp (value, "continue")) {
200                                 clear_opt (*mount_options, ERRORS_RO);
201                                 clear_opt (*mount_options, ERRORS_PANIC);
202                                 set_opt (*mount_options, ERRORS_CONT);
203                         }
204                         else if (!strcmp (value, "remount-ro")) {
205                                 clear_opt (*mount_options, ERRORS_CONT);
206                                 clear_opt (*mount_options, ERRORS_PANIC);
207                                 set_opt (*mount_options, ERRORS_RO);
208                         }
209                         else if (!strcmp (value, "panic")) {
210                                 clear_opt (*mount_options, ERRORS_CONT);
211                                 clear_opt (*mount_options, ERRORS_RO);
212                                 set_opt (*mount_options, ERRORS_PANIC);
213                         }
214                         else {
215                                 printk ("EXT2-fs: Invalid errors option: %s\n",
216                                         value);
217                                 return 0;
218                         }
219                 }
220                 else if (!strcmp (this_char, "grpid") ||
221                          !strcmp (this_char, "bsdgroups"))
222                         set_opt (*mount_options, GRPID);
223                 else if (!strcmp (this_char, "minixdf"))
224                         set_opt (*mount_options, MINIX_DF);
225                 else if (!strcmp (this_char, "nocheck"))
226                         clear_opt (*mount_options, CHECK);
227                 else if (!strcmp (this_char, "nogrpid") ||
228                          !strcmp (this_char, "sysvgroups"))
229                         clear_opt (*mount_options, GRPID);
230                 else if (!strcmp (this_char, "resgid")) {
231                         if (!value || !*value) {
232                                 printk ("EXT2-fs: the resgid option requires "
233                                         "an argument\n");
234                                 return 0;
235                         }
236                         *resgid = simple_strtoul (value, &value, 0);
237                         if (*value) {
238                                 printk ("EXT2-fs: Invalid resgid option: %s\n",
239                                         value);
240                                 return 0;
241                         }
242                 }
243                 else if (!strcmp (this_char, "resuid")) {
244                         if (!value || !*value) {
245                                 printk ("EXT2-fs: the resuid option requires "
246                                         "an argument");
247                                 return 0;
248                         }
249                         *resuid = simple_strtoul (value, &value, 0);
250                         if (*value) {
251                                 printk ("EXT2-fs: Invalid resuid option: %s\n",
252                                         value);
253                                 return 0;
254                         }
255                 }
256                 else if (!strcmp (this_char, "sb")) {
257                         if (!value || !*value) {
258                                 printk ("EXT2-fs: the sb option requires "
259                                         "an argument");
260                                 return 0;
261                         }
262                         *sb_block = simple_strtoul (value, &value, 0);
263                         if (*value) {
264                                 printk ("EXT2-fs: Invalid sb option: %s\n",
265                                         value);
266                                 return 0;
267                         }
268                 }
269                 /* Silently ignore the quota options */
270                 else if (!strcmp (this_char, "grpquota")
271                          || !strcmp (this_char, "noquota")
272                          || !strcmp (this_char, "quota")
273                          || !strcmp (this_char, "usrquota"))
274                         /* Don't do anything ;-) */ ;
275                 else {
276                         printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
277                         return 0;
278                 }
279         }
280         return 1;
281 }
282 
283 static int ext2_setup_super (struct super_block * sb,
284                               struct ext2_super_block * es,
285                               int read_only)
286 {
287         int res = 0;
288         if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) {
289                 printk ("EXT2-fs warning: revision level too high, "
290                         "forcing read-only mode\n");
291                 res = MS_RDONLY;
292         }
293         if (read_only)
294                 return res;
295         if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
296                 printk ("EXT2-fs warning: mounting unchecked fs, "
297                         "running e2fsck is recommended\n");
298         else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS))
299                 printk ("EXT2-fs warning: mounting fs with errors, "
300                         "running e2fsck is recommended\n");
301         else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
302                  le16_to_cpu(es->s_mnt_count) >=
303                  (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
304                 printk ("EXT2-fs warning: maximal mount count reached, "
305                         "running e2fsck is recommended\n");
306         else if (le32_to_cpu(es->s_checkinterval) &&
307                 (le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= CURRENT_TIME))
308                 printk ("EXT2-fs warning: checktime reached, "
309                         "running e2fsck is recommended\n");
310         es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT2_VALID_FS);
311         if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
312                 es->s_max_mnt_count = (__s16) cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
313         es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1);
314         es->s_mtime = cpu_to_le32(CURRENT_TIME);
315         mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
316         sb->s_dirt = 1;
317         if (test_opt (sb, DEBUG))
318                 printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
319                         "bpg=%lu, ipg=%lu, mo=%04lx]\n",
320                         EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
321                         sb->u.ext2_sb.s_frag_size,
322                         sb->u.ext2_sb.s_groups_count,
323                         EXT2_BLOCKS_PER_GROUP(sb),
324                         EXT2_INODES_PER_GROUP(sb),
325                         sb->u.ext2_sb.s_mount_opt);
326 #ifdef CONFIG_EXT2_CHECK
327         if (test_opt (sb, CHECK)) {
328                 ext2_check_blocks_bitmap (sb);
329                 ext2_check_inodes_bitmap (sb);
330         }
331 #endif
332         return res;
333 }
334 
335 static int ext2_check_descriptors (struct super_block * sb)
336 {
337         int i;
338         int desc_block = 0;
339         unsigned long block = le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block);
340         struct ext2_group_desc * gdp = NULL;
341 
342         ext2_debug ("Checking group descriptors");
343 
344         for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++)
345         {
346                 if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
347                         gdp = (struct ext2_group_desc *) sb->u.ext2_sb.s_group_desc[desc_block++]->b_data;
348                 if (le32_to_cpu(gdp->bg_block_bitmap) < block ||
349                     le32_to_cpu(gdp->bg_block_bitmap) >= block + EXT2_BLOCKS_PER_GROUP(sb))
350                 {
351                         ext2_error (sb, "ext2_check_descriptors",
352                                     "Block bitmap for group %d"
353                                     " not in group (block %lu)!",
354                                     i, (unsigned long) le32_to_cpu(gdp->bg_block_bitmap));
355                         return 0;
356                 }
357                 if (le32_to_cpu(gdp->bg_inode_bitmap) < block ||
358                     le32_to_cpu(gdp->bg_inode_bitmap) >= block + EXT2_BLOCKS_PER_GROUP(sb))
359                 {
360                         ext2_error (sb, "ext2_check_descriptors",
361                                     "Inode bitmap for group %d"
362                                     " not in group (block %lu)!",
363                                     i, (unsigned long) le32_to_cpu(gdp->bg_inode_bitmap));
364                         return 0;
365                 }
366                 if (le32_to_cpu(gdp->bg_inode_table) < block ||
367                     le32_to_cpu(gdp->bg_inode_table) + sb->u.ext2_sb.s_itb_per_group >=
368                     block + EXT2_BLOCKS_PER_GROUP(sb))
369                 {
370                         ext2_error (sb, "ext2_check_descriptors",
371                                     "Inode table for group %d"
372                                     " not in group (block %lu)!",
373                                     i, (unsigned long) le32_to_cpu(gdp->bg_inode_table));
374                         return 0;
375                 }
376                 block += EXT2_BLOCKS_PER_GROUP(sb);
377                 gdp++;
378         }
379         return 1;
380 }
381 
382 #define log2(n) ffz(~(n))
383 
384 struct super_block * ext2_read_super (struct super_block * sb, void * data,
385                                       int silent)
386 {
387         struct buffer_head * bh;
388         struct ext2_super_block * es;
389         unsigned long sb_block = 1;
390         unsigned short resuid = EXT2_DEF_RESUID;
391         unsigned short resgid = EXT2_DEF_RESGID;
392         unsigned long logic_sb_block = 1;
393         unsigned long offset = 0;
394         kdev_t dev = sb->s_dev;
395         int blocksize = BLOCK_SIZE;
396         int hblock;
397         int db_count;
398         int i, j;
399 
400         /*
401          * See what the current blocksize for the device is, and
402          * use that as the blocksize.  Otherwise (or if the blocksize
403          * is smaller than the default) use the default.
404          * This is important for devices that have a hardware
405          * sectorsize that is larger than the default.
406          */
407         blocksize = get_hardblocksize(dev);
408         if( blocksize == 0 || blocksize < BLOCK_SIZE )
409           {
410             blocksize = BLOCK_SIZE;
411           }
412 
413         sb->u.ext2_sb.s_mount_opt = 0;
414         if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
415             &sb->u.ext2_sb.s_mount_opt)) {
416                 return NULL;
417         }
418 
419         set_blocksize (dev, blocksize);
420 
421         /*
422          * If the superblock doesn't start on a sector boundary,
423          * calculate the offset.  FIXME(eric) this doesn't make sense
424          * that we would have to do this.
425          */
426         if (blocksize != BLOCK_SIZE) {
427                 logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
428                 offset = (sb_block*BLOCK_SIZE) % blocksize;
429         }
430 
431         if (!(bh = bread (dev, logic_sb_block, blocksize))) {
432                 printk ("EXT2-fs: unable to read superblock\n");
433                 return NULL;
434         }
435         /*
436          * Note: s_es must be initialized s_es as soon as possible because
437          * some ext2 macro-instructions depend on its value
438          */
439         es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
440         sb->u.ext2_sb.s_es = es;
441         sb->s_magic = le16_to_cpu(es->s_magic);
442         if (sb->s_magic != EXT2_SUPER_MAGIC) {
443                 if (!silent)
444                         printk ("VFS: Can't find an ext2 filesystem on dev "
445                                 "%s.\n", bdevname(dev));
446         failed_mount:
447                 if (bh)
448                         brelse(bh);
449                 return NULL;
450         }
451         if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
452             (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
453              EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
454              EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U)))
455                 printk("EXT2-fs warning: feature flags set on rev 0 fs, "
456                        "running e2fsck is recommended\n");
457         /*
458          * Check feature flags regardless of the revision level, since we
459          * previously didn't change the revision level when setting the flags,
460          * so there is a chance incompat flags are set on a rev 0 filesystem.
461          */
462         if ((i = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP))) {
463                 printk("EXT2-fs: %s: couldn't mount because of "
464                        "unsupported optional features (%x).\n",
465                        bdevname(dev), i);
466                 goto failed_mount;
467         }
468         if (!(sb->s_flags & MS_RDONLY) &&
469             (i = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){
470                 printk("EXT2-fs: %s: couldn't mount RDWR because of "
471                        "unsupported optional features (%x).\n",
472                        bdevname(dev), i);
473                 goto failed_mount;
474         }
475         sb->s_blocksize_bits =
476                 le32_to_cpu(EXT2_SB(sb)->s_es->s_log_block_size) + 10;
477         sb->s_blocksize = 1 << sb->s_blocksize_bits;
478         if (sb->s_blocksize != BLOCK_SIZE &&
479             (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||
480              sb->s_blocksize == 4096)) {
481                 /*
482                  * Make sure the blocksize for the filesystem is larger
483                  * than the hardware sectorsize for the machine.
484                  */
485                 hblock = get_hardblocksize(dev);
486                 if(    (hblock != 0)
487                     && (sb->s_blocksize < hblock) )
488                 {
489                         printk("EXT2-fs: blocksize too small for device.\n");
490                         goto failed_mount;
491                 }
492 
493                 brelse (bh);
494                 set_blocksize (dev, sb->s_blocksize);
495                 logic_sb_block = (sb_block*BLOCK_SIZE) / sb->s_blocksize;
496                 offset = (sb_block*BLOCK_SIZE) % sb->s_blocksize;
497                 bh = bread (dev, logic_sb_block, sb->s_blocksize);
498                 if(!bh) {
499                         printk("EXT2-fs: Couldn't read superblock on "
500                                "2nd try.\n");
501                         goto failed_mount;
502                 }
503                 es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
504                 sb->u.ext2_sb.s_es = es;
505                 if (es->s_magic != le16_to_cpu(EXT2_SUPER_MAGIC)) {
506                         printk ("EXT2-fs: Magic mismatch, very weird !\n");
507                         goto failed_mount;
508                 }
509         }
510         if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {
511                 sb->u.ext2_sb.s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
512                 sb->u.ext2_sb.s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
513         } else {
514                 sb->u.ext2_sb.s_inode_size = le16_to_cpu(es->s_inode_size);
515                 sb->u.ext2_sb.s_first_ino = le32_to_cpu(es->s_first_ino);
516                 if (sb->u.ext2_sb.s_inode_size != EXT2_GOOD_OLD_INODE_SIZE) {
517                         printk ("EXT2-fs: unsupported inode size: %d\n",
518                                 sb->u.ext2_sb.s_inode_size);
519                         goto failed_mount;
520                 }
521         }
522         sb->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
523                                    le32_to_cpu(es->s_log_frag_size);
524         if (sb->u.ext2_sb.s_frag_size)
525                 sb->u.ext2_sb.s_frags_per_block = sb->s_blocksize /
526                                                   sb->u.ext2_sb.s_frag_size;
527         else
528                 sb->s_magic = 0;
529         sb->u.ext2_sb.s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
530         sb->u.ext2_sb.s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
531         sb->u.ext2_sb.s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
532         sb->u.ext2_sb.s_inodes_per_block = sb->s_blocksize /
533                                            EXT2_INODE_SIZE(sb);
534         sb->u.ext2_sb.s_itb_per_group = sb->u.ext2_sb.s_inodes_per_group /
535                                         sb->u.ext2_sb.s_inodes_per_block;
536         sb->u.ext2_sb.s_desc_per_block = sb->s_blocksize /
537                                          sizeof (struct ext2_group_desc);
538         sb->u.ext2_sb.s_sbh = bh;
539         if (resuid != EXT2_DEF_RESUID)
540                 sb->u.ext2_sb.s_resuid = resuid;
541         else
542                 sb->u.ext2_sb.s_resuid = le16_to_cpu(es->s_def_resuid);
543         if (resgid != EXT2_DEF_RESGID)
544                 sb->u.ext2_sb.s_resgid = resgid;
545         else
546                 sb->u.ext2_sb.s_resgid = le16_to_cpu(es->s_def_resgid);
547         sb->u.ext2_sb.s_mount_state = le16_to_cpu(es->s_state);
548         sb->u.ext2_sb.s_addr_per_block_bits =
549                 log2 (EXT2_ADDR_PER_BLOCK(sb));
550         sb->u.ext2_sb.s_desc_per_block_bits =
551                 log2 (EXT2_DESC_PER_BLOCK(sb));
552         if (sb->s_magic != EXT2_SUPER_MAGIC) {
553                 if (!silent)
554                         printk ("VFS: Can't find an ext2 filesystem on dev "
555                                 "%s.\n",
556                                 bdevname(dev));
557                 goto failed_mount;
558         }
559         if (sb->s_blocksize != bh->b_size) {
560                 if (!silent)
561                         printk ("VFS: Unsupported blocksize on dev "
562                                 "%s.\n", bdevname(dev));
563                 goto failed_mount;
564         }
565 
566         if (sb->s_blocksize != sb->u.ext2_sb.s_frag_size) {
567                 printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",
568                         sb->u.ext2_sb.s_frag_size, sb->s_blocksize);
569                 goto failed_mount;
570         }
571 
572         if (sb->u.ext2_sb.s_blocks_per_group > sb->s_blocksize * 8) {
573                 printk ("EXT2-fs: #blocks per group too big: %lu\n",
574                         sb->u.ext2_sb.s_blocks_per_group);
575                 goto failed_mount;
576         }
577         if (sb->u.ext2_sb.s_frags_per_group > sb->s_blocksize * 8) {
578                 printk ("EXT2-fs: #fragments per group too big: %lu\n",
579                         sb->u.ext2_sb.s_frags_per_group);
580                 goto failed_mount;
581         }
582         if (sb->u.ext2_sb.s_inodes_per_group > sb->s_blocksize * 8) {
583                 printk ("EXT2-fs: #inodes per group too big: %lu\n",
584                         sb->u.ext2_sb.s_inodes_per_group);
585                 goto failed_mount;
586         }
587 
588         sb->u.ext2_sb.s_groups_count = (le32_to_cpu(es->s_blocks_count) -
589                                         le32_to_cpu(es->s_first_data_block) +
590                                        EXT2_BLOCKS_PER_GROUP(sb) - 1) /
591                                        EXT2_BLOCKS_PER_GROUP(sb);
592         db_count = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
593                    EXT2_DESC_PER_BLOCK(sb);
594         sb->u.ext2_sb.s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL);
595         if (sb->u.ext2_sb.s_group_desc == NULL) {
596                 printk ("EXT2-fs: not enough memory\n");
597                 goto failed_mount;
598         }
599         for (i = 0; i < db_count; i++) {
600                 sb->u.ext2_sb.s_group_desc[i] = bread (dev, logic_sb_block + i + 1,
601                                                        sb->s_blocksize);
602                 if (!sb->u.ext2_sb.s_group_desc[i]) {
603                         for (j = 0; j < i; j++)
604                                 brelse (sb->u.ext2_sb.s_group_desc[j]);
605                         kfree(sb->u.ext2_sb.s_group_desc);
606                         printk ("EXT2-fs: unable to read group descriptors\n");
607                         goto failed_mount;
608                 }
609         }
610         if (!ext2_check_descriptors (sb)) {
611                 for (j = 0; j < db_count; j++)
612                         brelse (sb->u.ext2_sb.s_group_desc[j]);
613                 kfree(sb->u.ext2_sb.s_group_desc);
614                 printk ("EXT2-fs: group descriptors corrupted !\n");
615                 goto failed_mount;
616         }
617         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
618                 sb->u.ext2_sb.s_inode_bitmap_number[i] = 0;
619                 sb->u.ext2_sb.s_inode_bitmap[i] = NULL;
620                 sb->u.ext2_sb.s_block_bitmap_number[i] = 0;
621                 sb->u.ext2_sb.s_block_bitmap[i] = NULL;
622         }
623         sb->u.ext2_sb.s_loaded_inode_bitmaps = 0;
624         sb->u.ext2_sb.s_loaded_block_bitmaps = 0;
625         sb->u.ext2_sb.s_gdb_count = db_count;
626         /*
627          * set up enough so that it can read an inode
628          */
629         sb->s_op = &ext2_sops;
630         sb->s_root = d_alloc_root(iget(sb, EXT2_ROOT_INO));
631         if (!sb->s_root) {
632                 for (i = 0; i < db_count; i++)
633                         if (sb->u.ext2_sb.s_group_desc[i])
634                                 brelse (sb->u.ext2_sb.s_group_desc[i]);
635                 kfree(sb->u.ext2_sb.s_group_desc);
636                 brelse (bh);
637                 printk ("EXT2-fs: get root inode failed\n");
638                 return NULL;
639         }
640         ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
641         return sb;
642 }
643 
644 static void ext2_commit_super (struct super_block * sb,
645                                struct ext2_super_block * es)
646 {
647         es->s_wtime = cpu_to_le32(CURRENT_TIME);
648         mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
649         sb->s_dirt = 0;
650 }
651 
652 /*
653  * In the second extended file system, it is not necessary to
654  * write the super block since we use a mapping of the
655  * disk super block in a buffer.
656  *
657  * However, this function is still used to set the fs valid
658  * flags to 0.  We need to set this flag to 0 since the fs
659  * may have been checked while mounted and e2fsck may have
660  * set s_state to EXT2_VALID_FS after some corrections.
661  */
662 
663 void ext2_write_super (struct super_block * sb)
664 {
665         struct ext2_super_block * es;
666 
667         if (!(sb->s_flags & MS_RDONLY)) {
668                 es = sb->u.ext2_sb.s_es;
669 
670                 ext2_debug ("setting valid to 0\n");
671 
672                 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS) {
673                         es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT2_VALID_FS);
674                         es->s_mtime = cpu_to_le32(CURRENT_TIME);
675                 }
676                 ext2_commit_super (sb, es);
677         }
678         sb->s_dirt = 0;
679 }
680 
681 int ext2_remount (struct super_block * sb, int * flags, char * data)
682 {
683         struct ext2_super_block * es;
684         unsigned short resuid = sb->u.ext2_sb.s_resuid;
685         unsigned short resgid = sb->u.ext2_sb.s_resgid;
686         unsigned long new_mount_opt;
687         unsigned long tmp;
688 
689         /*
690          * Allow the "check" option to be passed as a remount option.
691          */
692         new_mount_opt = sb->u.ext2_sb.s_mount_opt;
693         if (!parse_options (data, &tmp, &resuid, &resgid,
694                             &new_mount_opt))
695                 return -EINVAL;
696 
697         sb->u.ext2_sb.s_mount_opt = new_mount_opt;
698         sb->u.ext2_sb.s_resuid = resuid;
699         sb->u.ext2_sb.s_resgid = resgid;
700         es = sb->u.ext2_sb.s_es;
701         if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
702                 return 0;
703         if (*flags & MS_RDONLY) {
704                 if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
705                     !(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
706                         return 0;
707                 /*
708                  * OK, we are remounting a valid rw partition rdonly, so set
709                  * the rdonly flag and then mark the partition as valid again.
710                  */
711                 es->s_state = cpu_to_le16(sb->u.ext2_sb.s_mount_state);
712                 es->s_mtime = cpu_to_le32(CURRENT_TIME);
713                 mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
714                 sb->s_dirt = 1;
715                 ext2_commit_super (sb, es);
716         }
717         else {
718                 int ret;
719                 if ((ret = EXT2_HAS_RO_COMPAT_FEATURE(sb,
720                                                ~EXT2_FEATURE_RO_COMPAT_SUPP))) {
721                         printk("EXT2-fs: %s: couldn't remount RDWR because of "
722                                "unsupported optional features (%x).\n",
723                                bdevname(sb->s_dev), ret);
724                         return -EROFS;
725                 }
726                 /*
727                  * Mounting a RDONLY partition read-write, so reread and
728                  * store the current valid flag.  (It may have been changed
729                  * by e2fsck since we originally mounted the partition.)
730                  */
731                 sb->u.ext2_sb.s_mount_state = le16_to_cpu(es->s_state);
732                 if (!ext2_setup_super (sb, es, 0))
733                         sb->s_flags &= ~MS_RDONLY;
734         }
735         return 0;
736 }
737 
738 int ext2_statfs (struct super_block * sb, struct statfs * buf)
739 {
740         unsigned long overhead;
741         int i;
742 
743         if (test_opt (sb, MINIX_DF))
744                 overhead = 0;
745         else {
746                 /*
747                  * Compute the overhead (FS structures)
748                  */
749 
750                 /*
751                  * All of the blocks before first_data_block are
752                  * overhead
753                  */
754                 overhead = le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block);
755 
756                 /*
757                  * Add the overhead attributed to the superblock and
758                  * block group descriptors.  If the sparse superblocks
759                  * feature is turned on, then not all groups have this.
760                  */
761                 for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++)
762                         overhead += ext2_bg_has_super(sb, i) +
763                                 ext2_bg_num_gdb(sb, i);
764 
765                 /*
766                  * Every block group has an inode bitmap, a block
767                  * bitmap, and an inode table.
768                  */
769                 overhead += (sb->u.ext2_sb.s_groups_count *
770                              (2 + sb->u.ext2_sb.s_itb_per_group));
771         }
772 
773         buf->f_type = EXT2_SUPER_MAGIC;
774         buf->f_bsize = sb->s_blocksize;
775         buf->f_blocks = le32_to_cpu(sb->u.ext2_sb.s_es->s_blocks_count) - overhead;
776         buf->f_bfree = ext2_count_free_blocks (sb);
777         buf->f_bavail = buf->f_bfree - le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count);
778         if (buf->f_bfree < le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count))
779                 buf->f_bavail = 0;
780         buf->f_files = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
781         buf->f_ffree = ext2_count_free_inodes (sb);
782         buf->f_namelen = EXT2_NAME_LEN;
783         return 0;
784 }
785 
786 static DECLARE_FSTYPE_DEV(ext2_fs_type, "ext2", ext2_read_super);
787 
788 static int __init init_ext2_fs(void)
789 {
790         return register_filesystem(&ext2_fs_type);
791 }
792 
793 static void __exit exit_ext2_fs(void)
794 {
795         unregister_filesystem(&ext2_fs_type);
796 }
797 
798 EXPORT_NO_SYMBOLS;
799 
800 module_init(init_ext2_fs)
801 module_exit(exit_ext2_fs)
802 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.