diff options
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index a367dd044280..2fedaf8b5012 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -411,9 +411,6 @@ static void ext3_put_super (struct super_block * sb) | |||
411 | int i, err; | 411 | int i, err; |
412 | 412 | ||
413 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | 413 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); |
414 | |||
415 | lock_kernel(); | ||
416 | |||
417 | ext3_xattr_put_super(sb); | 414 | ext3_xattr_put_super(sb); |
418 | err = journal_destroy(sbi->s_journal); | 415 | err = journal_destroy(sbi->s_journal); |
419 | sbi->s_journal = NULL; | 416 | sbi->s_journal = NULL; |
@@ -462,8 +459,6 @@ static void ext3_put_super (struct super_block * sb) | |||
462 | sb->s_fs_info = NULL; | 459 | sb->s_fs_info = NULL; |
463 | kfree(sbi->s_blockgroup_lock); | 460 | kfree(sbi->s_blockgroup_lock); |
464 | kfree(sbi); | 461 | kfree(sbi); |
465 | |||
466 | unlock_kernel(); | ||
467 | } | 462 | } |
468 | 463 | ||
469 | static struct kmem_cache *ext3_inode_cachep; | 464 | static struct kmem_cache *ext3_inode_cachep; |
@@ -1306,9 +1301,9 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es, | |||
1306 | ext3_msg(sb, KERN_WARNING, | 1301 | ext3_msg(sb, KERN_WARNING, |
1307 | "warning: mounting fs with errors, " | 1302 | "warning: mounting fs with errors, " |
1308 | "running e2fsck is recommended"); | 1303 | "running e2fsck is recommended"); |
1309 | else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 && | 1304 | else if ((__s16) le16_to_cpu(es->s_max_mnt_count) > 0 && |
1310 | le16_to_cpu(es->s_mnt_count) >= | 1305 | le16_to_cpu(es->s_mnt_count) >= |
1311 | (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count)) | 1306 | le16_to_cpu(es->s_max_mnt_count)) |
1312 | ext3_msg(sb, KERN_WARNING, | 1307 | ext3_msg(sb, KERN_WARNING, |
1313 | "warning: maximal mount count reached, " | 1308 | "warning: maximal mount count reached, " |
1314 | "running e2fsck is recommended"); | 1309 | "running e2fsck is recommended"); |
@@ -1325,7 +1320,7 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es, | |||
1325 | valid forever! :) */ | 1320 | valid forever! :) */ |
1326 | es->s_state &= cpu_to_le16(~EXT3_VALID_FS); | 1321 | es->s_state &= cpu_to_le16(~EXT3_VALID_FS); |
1327 | #endif | 1322 | #endif |
1328 | if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) | 1323 | if (!le16_to_cpu(es->s_max_mnt_count)) |
1329 | es->s_max_mnt_count = cpu_to_le16(EXT3_DFL_MAX_MNT_COUNT); | 1324 | es->s_max_mnt_count = cpu_to_le16(EXT3_DFL_MAX_MNT_COUNT); |
1330 | le16_add_cpu(&es->s_mnt_count, 1); | 1325 | le16_add_cpu(&es->s_mnt_count, 1); |
1331 | es->s_mtime = cpu_to_le32(get_seconds()); | 1326 | es->s_mtime = cpu_to_le32(get_seconds()); |
@@ -1627,8 +1622,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1627 | sbi->s_resgid = EXT3_DEF_RESGID; | 1622 | sbi->s_resgid = EXT3_DEF_RESGID; |
1628 | sbi->s_sb_block = sb_block; | 1623 | sbi->s_sb_block = sb_block; |
1629 | 1624 | ||
1630 | unlock_kernel(); | ||
1631 | |||
1632 | blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE); | 1625 | blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE); |
1633 | if (!blocksize) { | 1626 | if (!blocksize) { |
1634 | ext3_msg(sb, KERN_ERR, "error: unable to set blocksize"); | 1627 | ext3_msg(sb, KERN_ERR, "error: unable to set blocksize"); |
@@ -1654,7 +1647,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1654 | * Note: s_es must be initialized as soon as possible because | 1647 | * Note: s_es must be initialized as soon as possible because |
1655 | * some ext3 macro-instructions depend on its value | 1648 | * some ext3 macro-instructions depend on its value |
1656 | */ | 1649 | */ |
1657 | es = (struct ext3_super_block *) (((char *)bh->b_data) + offset); | 1650 | es = (struct ext3_super_block *) (bh->b_data + offset); |
1658 | sbi->s_es = es; | 1651 | sbi->s_es = es; |
1659 | sb->s_magic = le16_to_cpu(es->s_magic); | 1652 | sb->s_magic = le16_to_cpu(es->s_magic); |
1660 | if (sb->s_magic != EXT3_SUPER_MAGIC) | 1653 | if (sb->s_magic != EXT3_SUPER_MAGIC) |
@@ -1765,7 +1758,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1765 | "error: can't read superblock on 2nd try"); | 1758 | "error: can't read superblock on 2nd try"); |
1766 | goto failed_mount; | 1759 | goto failed_mount; |
1767 | } | 1760 | } |
1768 | es = (struct ext3_super_block *)(((char *)bh->b_data) + offset); | 1761 | es = (struct ext3_super_block *)(bh->b_data + offset); |
1769 | sbi->s_es = es; | 1762 | sbi->s_es = es; |
1770 | if (es->s_magic != cpu_to_le16(EXT3_SUPER_MAGIC)) { | 1763 | if (es->s_magic != cpu_to_le16(EXT3_SUPER_MAGIC)) { |
1771 | ext3_msg(sb, KERN_ERR, | 1764 | ext3_msg(sb, KERN_ERR, |
@@ -1864,13 +1857,13 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1864 | sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) - | 1857 | sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) - |
1865 | le32_to_cpu(es->s_first_data_block) - 1) | 1858 | le32_to_cpu(es->s_first_data_block) - 1) |
1866 | / EXT3_BLOCKS_PER_GROUP(sb)) + 1; | 1859 | / EXT3_BLOCKS_PER_GROUP(sb)) + 1; |
1867 | db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) / | 1860 | db_count = DIV_ROUND_UP(sbi->s_groups_count, EXT3_DESC_PER_BLOCK(sb)); |
1868 | EXT3_DESC_PER_BLOCK(sb); | ||
1869 | sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *), | 1861 | sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *), |
1870 | GFP_KERNEL); | 1862 | GFP_KERNEL); |
1871 | if (sbi->s_group_desc == NULL) { | 1863 | if (sbi->s_group_desc == NULL) { |
1872 | ext3_msg(sb, KERN_ERR, | 1864 | ext3_msg(sb, KERN_ERR, |
1873 | "error: not enough memory"); | 1865 | "error: not enough memory"); |
1866 | ret = -ENOMEM; | ||
1874 | goto failed_mount; | 1867 | goto failed_mount; |
1875 | } | 1868 | } |
1876 | 1869 | ||
@@ -1958,6 +1951,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1958 | } | 1951 | } |
1959 | if (err) { | 1952 | if (err) { |
1960 | ext3_msg(sb, KERN_ERR, "error: insufficient memory"); | 1953 | ext3_msg(sb, KERN_ERR, "error: insufficient memory"); |
1954 | ret = err; | ||
1961 | goto failed_mount3; | 1955 | goto failed_mount3; |
1962 | } | 1956 | } |
1963 | 1957 | ||
@@ -2025,7 +2019,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
2025 | test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": | 2019 | test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": |
2026 | "writeback"); | 2020 | "writeback"); |
2027 | 2021 | ||
2028 | lock_kernel(); | ||
2029 | return 0; | 2022 | return 0; |
2030 | 2023 | ||
2031 | cantfind_ext3: | 2024 | cantfind_ext3: |
@@ -2055,7 +2048,6 @@ out_fail: | |||
2055 | sb->s_fs_info = NULL; | 2048 | sb->s_fs_info = NULL; |
2056 | kfree(sbi->s_blockgroup_lock); | 2049 | kfree(sbi->s_blockgroup_lock); |
2057 | kfree(sbi); | 2050 | kfree(sbi); |
2058 | lock_kernel(); | ||
2059 | return ret; | 2051 | return ret; |
2060 | } | 2052 | } |
2061 | 2053 | ||
@@ -2168,7 +2160,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb, | |||
2168 | goto out_bdev; | 2160 | goto out_bdev; |
2169 | } | 2161 | } |
2170 | 2162 | ||
2171 | es = (struct ext3_super_block *) (((char *)bh->b_data) + offset); | 2163 | es = (struct ext3_super_block *) (bh->b_data + offset); |
2172 | if ((le16_to_cpu(es->s_magic) != EXT3_SUPER_MAGIC) || | 2164 | if ((le16_to_cpu(es->s_magic) != EXT3_SUPER_MAGIC) || |
2173 | !(le32_to_cpu(es->s_feature_incompat) & | 2165 | !(le32_to_cpu(es->s_feature_incompat) & |
2174 | EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { | 2166 | EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { |
@@ -2361,6 +2353,21 @@ static int ext3_commit_super(struct super_block *sb, | |||
2361 | 2353 | ||
2362 | if (!sbh) | 2354 | if (!sbh) |
2363 | return error; | 2355 | return error; |
2356 | |||
2357 | if (buffer_write_io_error(sbh)) { | ||
2358 | /* | ||
2359 | * Oh, dear. A previous attempt to write the | ||
2360 | * superblock failed. This could happen because the | ||
2361 | * USB device was yanked out. Or it could happen to | ||
2362 | * be a transient write error and maybe the block will | ||
2363 | * be remapped. Nothing we can do but to retry the | ||
2364 | * write and hope for the best. | ||
2365 | */ | ||
2366 | ext3_msg(sb, KERN_ERR, "previous I/O error to " | ||
2367 | "superblock detected"); | ||
2368 | clear_buffer_write_io_error(sbh); | ||
2369 | set_buffer_uptodate(sbh); | ||
2370 | } | ||
2364 | /* | 2371 | /* |
2365 | * If the file system is mounted read-only, don't update the | 2372 | * If the file system is mounted read-only, don't update the |
2366 | * superblock write time. This avoids updating the superblock | 2373 | * superblock write time. This avoids updating the superblock |
@@ -2377,8 +2384,15 @@ static int ext3_commit_super(struct super_block *sb, | |||
2377 | es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); | 2384 | es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); |
2378 | BUFFER_TRACE(sbh, "marking dirty"); | 2385 | BUFFER_TRACE(sbh, "marking dirty"); |
2379 | mark_buffer_dirty(sbh); | 2386 | mark_buffer_dirty(sbh); |
2380 | if (sync) | 2387 | if (sync) { |
2381 | error = sync_dirty_buffer(sbh); | 2388 | error = sync_dirty_buffer(sbh); |
2389 | if (buffer_write_io_error(sbh)) { | ||
2390 | ext3_msg(sb, KERN_ERR, "I/O error while writing " | ||
2391 | "superblock"); | ||
2392 | clear_buffer_write_io_error(sbh); | ||
2393 | set_buffer_uptodate(sbh); | ||
2394 | } | ||
2395 | } | ||
2382 | return error; | 2396 | return error; |
2383 | } | 2397 | } |
2384 | 2398 | ||
@@ -2538,8 +2552,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2538 | int i; | 2552 | int i; |
2539 | #endif | 2553 | #endif |
2540 | 2554 | ||
2541 | lock_kernel(); | ||
2542 | |||
2543 | /* Store the original options */ | 2555 | /* Store the original options */ |
2544 | lock_super(sb); | 2556 | lock_super(sb); |
2545 | old_sb_flags = sb->s_flags; | 2557 | old_sb_flags = sb->s_flags; |
@@ -2648,7 +2660,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2648 | kfree(old_opts.s_qf_names[i]); | 2660 | kfree(old_opts.s_qf_names[i]); |
2649 | #endif | 2661 | #endif |
2650 | unlock_super(sb); | 2662 | unlock_super(sb); |
2651 | unlock_kernel(); | ||
2652 | 2663 | ||
2653 | if (enable_quota) | 2664 | if (enable_quota) |
2654 | dquot_resume(sb, -1); | 2665 | dquot_resume(sb, -1); |
@@ -2669,7 +2680,6 @@ restore_opts: | |||
2669 | } | 2680 | } |
2670 | #endif | 2681 | #endif |
2671 | unlock_super(sb); | 2682 | unlock_super(sb); |
2672 | unlock_kernel(); | ||
2673 | return err; | 2683 | return err; |
2674 | } | 2684 | } |
2675 | 2685 | ||
@@ -3010,16 +3020,16 @@ out: | |||
3010 | 3020 | ||
3011 | #endif | 3021 | #endif |
3012 | 3022 | ||
3013 | static int ext3_get_sb(struct file_system_type *fs_type, | 3023 | static struct dentry *ext3_mount(struct file_system_type *fs_type, |
3014 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 3024 | int flags, const char *dev_name, void *data) |
3015 | { | 3025 | { |
3016 | return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super, mnt); | 3026 | return mount_bdev(fs_type, flags, dev_name, data, ext3_fill_super); |
3017 | } | 3027 | } |
3018 | 3028 | ||
3019 | static struct file_system_type ext3_fs_type = { | 3029 | static struct file_system_type ext3_fs_type = { |
3020 | .owner = THIS_MODULE, | 3030 | .owner = THIS_MODULE, |
3021 | .name = "ext3", | 3031 | .name = "ext3", |
3022 | .get_sb = ext3_get_sb, | 3032 | .mount = ext3_mount, |
3023 | .kill_sb = kill_block_super, | 3033 | .kill_sb = kill_block_super, |
3024 | .fs_flags = FS_REQUIRES_DEV, | 3034 | .fs_flags = FS_REQUIRES_DEV, |
3025 | }; | 3035 | }; |