X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fext2%2Fsuper.c;h=ef50cbc792db94668b9d7deecc22c50076511fe4;hb=2283af5b0b99565f516eacd756df2b1ddf9f4f85;hp=154e25f13d772235e7c7d242a0b5e6fdbf977cd7;hpb=37e58df30063e229ee5157f9d1c1fa1d749917c2;p=linux-2.6 diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 154e25f13d..ef50cbc792 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -51,8 +51,7 @@ void ext2_error (struct super_block * sb, const char * function, if (!(sb->s_flags & MS_RDONLY)) { sbi->s_mount_state |= EXT2_ERROR_FS; - es->s_state = - cpu_to_le16(le16_to_cpu(es->s_state) | EXT2_ERROR_FS); + es->s_state |= cpu_to_le16(EXT2_ERROR_FS); ext2_sync_super(sb, es); } @@ -90,7 +89,7 @@ void ext2_update_dynamic_rev(struct super_block *sb) if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV) return; - ext2_warning(sb, __FUNCTION__, + ext2_warning(sb, __func__, "updating to rev %d because of new feature flag, " "running e2fsck is recommended", EXT2_DYNAMIC_REV); @@ -234,16 +233,16 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) { seq_printf(seq, ",resgid=%u", sbi->s_resgid); } - if (test_opt(sb, ERRORS_CONT)) { + if (test_opt(sb, ERRORS_RO)) { int def_errors = le16_to_cpu(es->s_errors); if (def_errors == EXT2_ERRORS_PANIC || - def_errors == EXT2_ERRORS_RO) { - seq_puts(seq, ",errors=continue"); + def_errors == EXT2_ERRORS_CONTINUE) { + seq_puts(seq, ",errors=remount-ro"); } } - if (test_opt(sb, ERRORS_RO)) - seq_puts(seq, ",errors=remount-ro"); + if (test_opt(sb, ERRORS_CONT)) + seq_puts(seq, ",errors=continue"); if (test_opt(sb, ERRORS_PANIC)) seq_puts(seq, ",errors=panic"); if (test_opt(sb, NO_UID32)) @@ -285,6 +284,9 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) seq_puts(seq, ",xip"); #endif + if (!test_opt(sb, RESERVATION)) + seq_puts(seq, ",noreservation"); + return 0; } @@ -296,7 +298,6 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *da static const struct super_operations ext2_sops = { .alloc_inode = ext2_alloc_inode, .destroy_inode = ext2_destroy_inode, - .read_inode = ext2_read_inode, .write_inode = ext2_write_inode, .delete_inode = ext2_delete_inode, .put_super = ext2_put_super, @@ -326,11 +327,10 @@ static struct inode *ext2_nfs_get_inode(struct super_block *sb, * it might be "neater" to call ext2_get_inode first and check * if the inode is valid..... */ - inode = iget(sb, ino); - if (inode == NULL) - return ERR_PTR(-ENOMEM); - if (is_bad_inode(inode) || - (generation && inode->i_generation != generation)) { + inode = ext2_iget(sb, ino); + if (IS_ERR(inode)) + return ERR_CAST(inode); + if (generation && inode->i_generation != generation) { /* we didn't find the right inode.. */ iput(inode); return ERR_PTR(-ESTALE); @@ -603,7 +603,7 @@ static int ext2_setup_super (struct super_block * sb, "running e2fsck is recommended\n"); if (!le16_to_cpu(es->s_max_mnt_count)) es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); - es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1); + le16_add_cpu(&es->s_mnt_count, 1); ext2_write_super(sb); if (test_opt (sb, DEBUG)) printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, " @@ -617,27 +617,24 @@ static int ext2_setup_super (struct super_block * sb, return res; } -static int ext2_check_descriptors (struct super_block * sb) +static int ext2_check_descriptors(struct super_block *sb) { int i; - int desc_block = 0; struct ext2_sb_info *sbi = EXT2_SB(sb); - unsigned long first_block = le32_to_cpu(sbi->s_es->s_first_data_block); - unsigned long last_block; - struct ext2_group_desc * gdp = NULL; ext2_debug ("Checking group descriptors"); - for (i = 0; i < sbi->s_groups_count; i++) - { + for (i = 0; i < sbi->s_groups_count; i++) { + struct ext2_group_desc *gdp = ext2_get_group_desc(sb, i, NULL); + ext2_fsblk_t first_block = ext2_group_first_block_no(sb, i); + ext2_fsblk_t last_block; + if (i == sbi->s_groups_count - 1) last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; else last_block = first_block + (EXT2_BLOCKS_PER_GROUP(sb) - 1); - if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) - gdp = (struct ext2_group_desc *) sbi->s_group_desc[desc_block++]->b_data; if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || le32_to_cpu(gdp->bg_block_bitmap) > last_block) { @@ -666,8 +663,6 @@ static int ext2_check_descriptors (struct super_block * sb) i, (unsigned long) le32_to_cpu(gdp->bg_inode_table)); return 0; } - first_block += EXT2_BLOCKS_PER_GROUP(sb); - gdp++; } return 1; } @@ -680,11 +675,31 @@ static int ext2_check_descriptors (struct super_block * sb) static loff_t ext2_max_size(int bits) { loff_t res = EXT2_NDIR_BLOCKS; - /* This constant is calculated to be the largest file size for a - * dense, 4k-blocksize file such that the total number of + int meta_blocks; + loff_t upper_limit; + + /* This is calculated to be the largest file size for a + * dense, file such that the total number of * sectors in the file, including data and all indirect blocks, - * does not exceed 2^32. */ - const loff_t upper_limit = 0x1ff7fffd000LL; + * does not exceed 2^32 -1 + * __u32 i_blocks representing the total number of + * 512 bytes blocks of the file + */ + upper_limit = (1LL << 32) - 1; + + /* total blocks in file system block size */ + upper_limit >>= (bits - 9); + + + /* indirect blocks */ + meta_blocks = 1; + /* double indirect blocks */ + meta_blocks += 1 + (1LL << (bits-2)); + /* tripple indirect blocks */ + meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2))); + + upper_limit -= meta_blocks; + upper_limit <<= bits; res += 1LL << (bits-2); res += 1LL << (2*(bits-2)); @@ -692,6 +707,10 @@ static loff_t ext2_max_size(int bits) res <<= bits; if (res > upper_limit) res = upper_limit; + + if (res > MAX_LFS_FILESIZE) + res = MAX_LFS_FILESIZE; + return res; } @@ -700,10 +719,9 @@ static unsigned long descriptor_loc(struct super_block *sb, int nr) { struct ext2_sb_info *sbi = EXT2_SB(sb); - unsigned long bg, first_data_block, first_meta_bg; + unsigned long bg, first_meta_bg; int has_super = 0; - first_data_block = le32_to_cpu(sbi->s_es->s_first_data_block); first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg); if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_META_BG) || @@ -712,7 +730,8 @@ static unsigned long descriptor_loc(struct super_block *sb, bg = sbi->s_desc_per_block * nr; if (ext2_bg_has_super(sb, bg)) has_super = 1; - return (first_data_block + has_super + (bg * sbi->s_blocks_per_group)); + + return ext2_group_first_block_no(sb, bg) + has_super; } static int ext2_fill_super(struct super_block *sb, void *data, int silent) @@ -726,6 +745,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) unsigned long logic_sb_block; unsigned long offset = 0; unsigned long def_mount_opts; + long ret = -EINVAL; int blocksize = BLOCK_SIZE; int db_count; int i, j; @@ -796,10 +816,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC) set_opt(sbi->s_mount_opt, ERRORS_PANIC); - else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO) - set_opt(sbi->s_mount_opt, ERRORS_RO); - else + else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE) set_opt(sbi->s_mount_opt, ERRORS_CONT); + else + set_opt(sbi->s_mount_opt, ERRORS_RO); sbi->s_resuid = le16_to_cpu(es->s_def_resuid); sbi->s_resgid = le16_to_cpu(es->s_def_resgid); @@ -844,8 +864,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); - if ((ext2_use_xip(sb)) && ((blocksize != PAGE_SIZE) || - (sb->s_blocksize != blocksize))) { + if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) { if (!silent) printk("XIP: Unsupported blocksize\n"); goto failed_mount; @@ -1022,21 +1041,26 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) sb->s_op = &ext2_sops; sb->s_export_op = &ext2_export_ops; sb->s_xattr = ext2_xattr_handlers; - root = iget(sb, EXT2_ROOT_INO); - sb->s_root = d_alloc_root(root); - if (!sb->s_root) { - iput(root); - printk(KERN_ERR "EXT2-fs: get root inode failed\n"); + root = ext2_iget(sb, EXT2_ROOT_INO); + if (IS_ERR(root)) { + ret = PTR_ERR(root); goto failed_mount3; } if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { - dput(sb->s_root); - sb->s_root = NULL; + iput(root); printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); goto failed_mount3; } + + sb->s_root = d_alloc_root(root); + if (!sb->s_root) { + iput(root); + printk(KERN_ERR "EXT2-fs: get root inode failed\n"); + ret = -ENOMEM; + goto failed_mount3; + } if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) - ext2_warning(sb, __FUNCTION__, + ext2_warning(sb, __func__, "mounting ext3 filesystem as ext2"); ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); return 0; @@ -1061,7 +1085,7 @@ failed_mount: failed_sbi: sb->s_fs_info = NULL; kfree(sbi); - return -EINVAL; + return ret; } static void ext2_commit_super (struct super_block * sb, @@ -1100,10 +1124,9 @@ void ext2_write_super (struct super_block * sb) if (!(sb->s_flags & MS_RDONLY)) { es = EXT2_SB(sb)->s_es; - if (le16_to_cpu(es->s_state) & EXT2_VALID_FS) { + if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { ext2_debug ("setting valid to 0\n"); - es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & - ~EXT2_VALID_FS); + es->s_state &= cpu_to_le16(~EXT2_VALID_FS); es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); es->s_mtime = cpu_to_le32(get_seconds()); @@ -1154,7 +1177,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != (old_mount_opt & EXT2_MOUNT_XIP)) && invalidate_inodes(sb)) - ext2_warning(sb, __FUNCTION__, "busy inodes while remounting "\ + ext2_warning(sb, __func__, "busy inodes while remounting "\ "xip remain in cache (no functional problem)"); if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0;