diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 17:17:53 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 17:17:53 +0000 |
commit | b2ad5f821b1381492d792ca10b1eb7a107b48f14 (patch) | |
tree | 954a648692e7da983db1d2470953705f6a729264 /fs/ext2 | |
parent | c9c06167e7933d93a6e396174c68abf242294abb (diff) |
Merge with Linux 2.4.0-prerelease. Big Makefile rewrite, test your
Makefiles.
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/Makefile | 5 | ||||
-rw-r--r-- | fs/ext2/balloc.c | 70 | ||||
-rw-r--r-- | fs/ext2/inode.c | 10 | ||||
-rw-r--r-- | fs/ext2/super.c | 105 |
4 files changed, 127 insertions, 63 deletions
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile index 7321f45c8..aa8560f07 100644 --- a/fs/ext2/Makefile +++ b/fs/ext2/Makefile @@ -8,8 +8,9 @@ # Note 2! The CFLAGS definitions are now in the main makefile... O_TARGET := ext2.o -O_OBJS := acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ + +obj-y := acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ioctl.o namei.o super.o symlink.o -M_OBJS := $(O_TARGET) +obj-m := $(O_TARGET) include $(TOPDIR)/Rules.make diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 81448e71b..e592850db 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -663,7 +663,7 @@ static inline int block_in_use (unsigned long block, EXT2_BLOCKS_PER_GROUP(sb), map); } -static int test_root(int a, int b) +static inline int test_root(int a, int b) { if (a == 0) return 1; @@ -682,24 +682,55 @@ int ext2_group_sparse(int group) test_root(group, 7)); } +/** + * ext2_bg_has_super - number of blocks used by the superblock in group + * @sb: superblock for filesystem + * @group: group number to check + * + * Return the number of blocks used by the superblock (primary or backup) + * in this group. Currently this will be only 0 or 1. + */ +int ext2_bg_has_super(struct super_block *sb, int group) +{ + if (EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)&& + !ext2_group_sparse(group)) + return 0; + return 1; +} + +/** + * ext2_bg_num_gdb - number of blocks used by the group table in group + * @sb: superblock for filesystem + * @group: group number to check + * + * Return the number of blocks used by the group descriptor table + * (primary or backup) in this group. In the future there may be a + * different number of descriptor blocks in each group. + */ +unsigned long ext2_bg_num_gdb(struct super_block *sb, int group) +{ + if (EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)&& + !ext2_group_sparse(group)) + return 0; + return EXT2_SB(sb)->s_gdb_count; +} + #ifdef CONFIG_EXT2_CHECK /* Called at mount-time, super-block is locked */ void ext2_check_blocks_bitmap (struct super_block * sb) { struct buffer_head * bh; struct ext2_super_block * es; - unsigned long desc_count, bitmap_count, x; + unsigned long desc_count, bitmap_count, x, j; unsigned long desc_blocks; int bitmap_nr; struct ext2_group_desc * gdp; - int i, j; + int i; es = sb->u.ext2_sb.s_es; desc_count = 0; bitmap_count = 0; gdp = NULL; - desc_blocks = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / - EXT2_DESC_PER_BLOCK(sb); for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) { gdp = ext2_get_group_desc (sb, i, NULL); if (!gdp) @@ -708,24 +739,19 @@ void ext2_check_blocks_bitmap (struct super_block * sb) bitmap_nr = load_block_bitmap (sb, i); if (bitmap_nr < 0) continue; - - bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr]; - if (!(sb->u.ext2_sb.s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) || - ext2_group_sparse(i)) { - if (!ext2_test_bit (0, bh->b_data)) - ext2_error (sb, "ext2_check_blocks_bitmap", - "Superblock in group %d " - "is marked free", i); - - for (j = 0; j < desc_blocks; j++) - if (!ext2_test_bit (j + 1, bh->b_data)) - ext2_error (sb, - "ext2_check_blocks_bitmap", - "Descriptor block #%d in group " - "%d is marked free", j, i); - } + bh = EXT2_SB(sb)->s_block_bitmap[bitmap_nr]; + + if (ext2_bg_has_super(sb, i) && !ext2_test_bit(0, bh->b_data)) + ext2_error(sb, __FUNCTION__, + "Superblock in group %d is marked free", i); + + desc_blocks = ext2_bg_num_gdb(sb, i); + for (j = 0; j < desc_blocks; j++) + if (!ext2_test_bit(j + 1, bh->b_data)) + ext2_error(sb, __FUNCTION__, + "Descriptor block #%ld in group " + "%d is marked free", j, i); if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap), sb, bh->b_data)) ext2_error (sb, "ext2_check_blocks_bitmap", diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 658a06416..fd54c3040 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1190,13 +1190,17 @@ static int ext2_update_inode(struct inode * inode, int do_sync) raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32); if (raw_inode->i_size_high) { struct super_block *sb = inode->i_sb; - struct ext2_super_block *es = sb->u.ext2_sb.s_es; - if (!(es->s_feature_ro_compat & cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE))) { + if (!EXT2_HAS_RO_COMPAT_FEATURE(sb, + EXT2_FEATURE_RO_COMPAT_LARGE_FILE) || + EXT2_SB(sb)->s_es->s_rev_level == + cpu_to_le32(EXT2_GOOD_OLD_REV)) { /* If this is the first large file * created, add a flag to the superblock. */ lock_kernel(); - es->s_feature_ro_compat |= cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE); + ext2_update_dynamic_rev(sb); + EXT2_SET_RO_COMPAT_FEATURE(sb, + EXT2_FEATURE_RO_COMPAT_LARGE_FILE); unlock_kernel(); ext2_write_super(sb); } diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 4d2dfedbf..7b88355f8 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -95,6 +95,31 @@ void ext2_warning (struct super_block * sb, const char * function, bdevname(sb->s_dev), function, error_buf); } +void ext2_update_dynamic_rev(struct super_block *sb) +{ + struct ext2_super_block *es = EXT2_SB(sb)->s_es; + + if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV) + return; + + ext2_warning(sb, __FUNCTION__, + "updating to rev %d because of new feature flag, " + "running e2fsck is recommended", + EXT2_DYNAMIC_REV); + + es->s_first_ino = cpu_to_le32(EXT2_GOOD_OLD_FIRST_INO); + es->s_inode_size = cpu_to_le16(EXT2_GOOD_OLD_INODE_SIZE); + es->s_rev_level = cpu_to_le32(EXT2_DYNAMIC_REV); + /* leave es->s_feature_*compat flags alone */ + /* es->s_uuid will be set by e2fsck if empty */ + + /* + * The rest of the superblock fields should be zero, and if not it + * means they are likely already in use, so leave them alone. We + * can leave it up to e2fsck to clean up any inconsistencies there. + */ +} + void ext2_put_super (struct super_block * sb) { int db_count; @@ -104,7 +129,7 @@ void ext2_put_super (struct super_block * sb) sb->u.ext2_sb.s_es->s_state = le16_to_cpu(sb->u.ext2_sb.s_mount_state); mark_buffer_dirty(sb->u.ext2_sb.s_sbh); } - db_count = sb->u.ext2_sb.s_db_per_group; + db_count = EXT2_SB(sb)->s_gdb_count; for (i = 0; i < db_count; i++) if (sb->u.ext2_sb.s_group_desc[i]) brelse (sb->u.ext2_sb.s_group_desc[i]); @@ -261,9 +286,9 @@ static int ext2_setup_super (struct super_block * sb, { int res = 0; if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) { - printk ("EXT2-fs warning: revision level too high, " - "forcing read/only mode\n"); - res = MS_RDONLY; + printk ("EXT2-fs warning: revision level too high, " + "forcing read-only mode\n"); + res = MS_RDONLY; } if (read_only) return res; @@ -423,22 +448,32 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, brelse(bh); return NULL; } - if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV) { - if (le32_to_cpu(es->s_feature_incompat) & ~EXT2_FEATURE_INCOMPAT_SUPP) { - printk("EXT2-fs: %s: couldn't mount because of " - "unsupported optional features.\n", - bdevname(dev)); - goto failed_mount; - } - if (!(sb->s_flags & MS_RDONLY) && - (le32_to_cpu(es->s_feature_ro_compat) & ~EXT2_FEATURE_RO_COMPAT_SUPP)) { - printk("EXT2-fs: %s: couldn't mount RDWR because of " - "unsupported optional features.\n", - bdevname(dev)); - goto failed_mount; - } + if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV && + (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) || + EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) || + EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U))) + printk("EXT2-fs warning: feature flags set on rev 0 fs, " + "running e2fsck is recommended\n"); + /* + * Check feature flags regardless of the revision level, since we + * previously didn't change the revision level when setting the flags, + * so there is a chance incompat flags are set on a rev 0 filesystem. + */ + if ((i = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP))) { + printk("EXT2-fs: %s: couldn't mount because of " + "unsupported optional features (%x).\n", + bdevname(dev), i); + goto failed_mount; + } + if (!(sb->s_flags & MS_RDONLY) && + (i = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){ + printk("EXT2-fs: %s: couldn't mount RDWR because of " + "unsupported optional features (%x).\n", + bdevname(dev), i); + goto failed_mount; } - sb->s_blocksize_bits = le32_to_cpu(sb->u.ext2_sb.s_es->s_log_block_size) + 10; + sb->s_blocksize_bits = + le32_to_cpu(EXT2_SB(sb)->s_es->s_log_block_size) + 10; sb->s_blocksize = 1 << sb->s_blocksize_bits; if (sb->s_blocksize != BLOCK_SIZE && (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 || @@ -484,9 +519,6 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, goto failed_mount; } } - sb->u.ext2_sb.s_feature_compat = le32_to_cpu(es->s_feature_compat); - sb->u.ext2_sb.s_feature_incompat = le32_to_cpu(es->s_feature_incompat); - sb->u.ext2_sb.s_feature_ro_compat = le32_to_cpu(es->s_feature_ro_compat); sb->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE << le32_to_cpu(es->s_log_frag_size); if (sb->u.ext2_sb.s_frag_size) @@ -590,7 +622,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, } sb->u.ext2_sb.s_loaded_inode_bitmaps = 0; sb->u.ext2_sb.s_loaded_block_bitmaps = 0; - sb->u.ext2_sb.s_db_per_group = db_count; + sb->u.ext2_sb.s_gdb_count = db_count; /* * set up enough so that it can read an inode */ @@ -683,6 +715,14 @@ int ext2_remount (struct super_block * sb, int * flags, char * data) ext2_commit_super (sb, es); } else { + int ret; + if ((ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, + ~EXT2_FEATURE_RO_COMPAT_SUPP))) { + printk("EXT2-fs: %s: couldn't remount RDWR because of " + "unsupported optional features (%x).\n", + bdevname(sb->s_dev), ret); + return -EROFS; + } /* * Mounting a RDONLY partition read-write, so reread and * store the current valid flag. (It may have been changed @@ -698,7 +738,7 @@ int ext2_remount (struct super_block * sb, int * flags, char * data) int ext2_statfs (struct super_block * sb, struct statfs * buf) { unsigned long overhead; - int ngroups, i; + int i; if (test_opt (sb, MINIX_DF)) overhead = 0; @@ -715,19 +755,12 @@ int ext2_statfs (struct super_block * sb, struct statfs * buf) /* * Add the overhead attributed to the superblock and - * block group descriptors. If this is sparse - * superblocks is turned on, then not all groups have - * this. + * block group descriptors. If the sparse superblocks + * feature is turned on, then not all groups have this. */ - if (sb->u.ext2_sb.s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) { - ngroups = 0; - for (i=0 ; i < sb->u.ext2_sb.s_groups_count; i++) - if (ext2_group_sparse(i)) - ngroups++; - } else - ngroups = sb->u.ext2_sb.s_groups_count; - overhead += ngroups * (1 + sb->u.ext2_sb.s_db_per_group); + for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) + overhead += ext2_bg_has_super(sb, i) + + ext2_bg_num_gdb(sb, i); /* * Every block group has an inode bitmap, a block |