diff options
Diffstat (limited to 'fs/ext4/super.c')
| -rw-r--r-- | fs/ext4/super.c | 142 |
1 files changed, 128 insertions, 14 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 02bf24343979..1cb371dcd609 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -506,6 +506,7 @@ static void ext4_put_super (struct super_block * sb) | |||
| 506 | ext4_ext_release(sb); | 506 | ext4_ext_release(sb); |
| 507 | ext4_xattr_put_super(sb); | 507 | ext4_xattr_put_super(sb); |
| 508 | jbd2_journal_destroy(sbi->s_journal); | 508 | jbd2_journal_destroy(sbi->s_journal); |
| 509 | sbi->s_journal = NULL; | ||
| 509 | if (!(sb->s_flags & MS_RDONLY)) { | 510 | if (!(sb->s_flags & MS_RDONLY)) { |
| 510 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 511 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
| 511 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 512 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
| @@ -517,6 +518,7 @@ static void ext4_put_super (struct super_block * sb) | |||
| 517 | for (i = 0; i < sbi->s_gdb_count; i++) | 518 | for (i = 0; i < sbi->s_gdb_count; i++) |
| 518 | brelse(sbi->s_group_desc[i]); | 519 | brelse(sbi->s_group_desc[i]); |
| 519 | kfree(sbi->s_group_desc); | 520 | kfree(sbi->s_group_desc); |
| 521 | kfree(sbi->s_flex_groups); | ||
| 520 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 522 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
| 521 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 523 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
| 522 | percpu_counter_destroy(&sbi->s_dirs_counter); | 524 | percpu_counter_destroy(&sbi->s_dirs_counter); |
| @@ -571,6 +573,12 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
| 571 | memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); | 573 | memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); |
| 572 | INIT_LIST_HEAD(&ei->i_prealloc_list); | 574 | INIT_LIST_HEAD(&ei->i_prealloc_list); |
| 573 | spin_lock_init(&ei->i_prealloc_lock); | 575 | spin_lock_init(&ei->i_prealloc_lock); |
| 576 | jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode); | ||
| 577 | ei->i_reserved_data_blocks = 0; | ||
| 578 | ei->i_reserved_meta_blocks = 0; | ||
| 579 | ei->i_allocated_meta_blocks = 0; | ||
| 580 | ei->i_delalloc_reserved_flag = 0; | ||
| 581 | spin_lock_init(&(ei->i_block_reservation_lock)); | ||
| 574 | return &ei->vfs_inode; | 582 | return &ei->vfs_inode; |
| 575 | } | 583 | } |
| 576 | 584 | ||
| @@ -635,6 +643,8 @@ static void ext4_clear_inode(struct inode *inode) | |||
| 635 | EXT4_I(inode)->i_block_alloc_info = NULL; | 643 | EXT4_I(inode)->i_block_alloc_info = NULL; |
| 636 | if (unlikely(rsv)) | 644 | if (unlikely(rsv)) |
| 637 | kfree(rsv); | 645 | kfree(rsv); |
| 646 | jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, | ||
| 647 | &EXT4_I(inode)->jinode); | ||
| 638 | } | 648 | } |
| 639 | 649 | ||
| 640 | static inline void ext4_show_quota_options(struct seq_file *seq, struct super_block *sb) | 650 | static inline void ext4_show_quota_options(struct seq_file *seq, struct super_block *sb) |
| @@ -671,7 +681,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 671 | unsigned long def_mount_opts; | 681 | unsigned long def_mount_opts; |
| 672 | struct super_block *sb = vfs->mnt_sb; | 682 | struct super_block *sb = vfs->mnt_sb; |
| 673 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 683 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 674 | journal_t *journal = sbi->s_journal; | ||
| 675 | struct ext4_super_block *es = sbi->s_es; | 684 | struct ext4_super_block *es = sbi->s_es; |
| 676 | 685 | ||
| 677 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); | 686 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); |
| @@ -747,6 +756,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 747 | seq_puts(seq, ",nomballoc"); | 756 | seq_puts(seq, ",nomballoc"); |
| 748 | if (test_opt(sb, I_VERSION)) | 757 | if (test_opt(sb, I_VERSION)) |
| 749 | seq_puts(seq, ",i_version"); | 758 | seq_puts(seq, ",i_version"); |
| 759 | if (!test_opt(sb, DELALLOC)) | ||
| 760 | seq_puts(seq, ",nodelalloc"); | ||
| 761 | |||
| 750 | 762 | ||
| 751 | if (sbi->s_stripe) | 763 | if (sbi->s_stripe) |
| 752 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | 764 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); |
| @@ -894,7 +906,7 @@ enum { | |||
| 894 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 906 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
| 895 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 907 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
| 896 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, | 908 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, |
| 897 | Opt_mballoc, Opt_nomballoc, Opt_stripe, | 909 | Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
| 898 | }; | 910 | }; |
| 899 | 911 | ||
| 900 | static match_table_t tokens = { | 912 | static match_table_t tokens = { |
| @@ -953,6 +965,8 @@ static match_table_t tokens = { | |||
| 953 | {Opt_nomballoc, "nomballoc"}, | 965 | {Opt_nomballoc, "nomballoc"}, |
| 954 | {Opt_stripe, "stripe=%u"}, | 966 | {Opt_stripe, "stripe=%u"}, |
| 955 | {Opt_resize, "resize"}, | 967 | {Opt_resize, "resize"}, |
| 968 | {Opt_delalloc, "delalloc"}, | ||
| 969 | {Opt_nodelalloc, "nodelalloc"}, | ||
| 956 | {Opt_err, NULL}, | 970 | {Opt_err, NULL}, |
| 957 | }; | 971 | }; |
| 958 | 972 | ||
| @@ -990,6 +1004,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
| 990 | int qtype, qfmt; | 1004 | int qtype, qfmt; |
| 991 | char *qname; | 1005 | char *qname; |
| 992 | #endif | 1006 | #endif |
| 1007 | ext4_fsblk_t last_block; | ||
| 993 | 1008 | ||
| 994 | if (!options) | 1009 | if (!options) |
| 995 | return 1; | 1010 | return 1; |
| @@ -1309,15 +1324,39 @@ set_qf_format: | |||
| 1309 | clear_opt(sbi->s_mount_opt, NOBH); | 1324 | clear_opt(sbi->s_mount_opt, NOBH); |
| 1310 | break; | 1325 | break; |
| 1311 | case Opt_extents: | 1326 | case Opt_extents: |
| 1327 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, | ||
| 1328 | EXT4_FEATURE_INCOMPAT_EXTENTS)) { | ||
| 1329 | ext4_warning(sb, __func__, | ||
| 1330 | "extents feature not enabled " | ||
| 1331 | "on this filesystem, use tune2fs\n"); | ||
| 1332 | return 0; | ||
| 1333 | } | ||
| 1312 | set_opt (sbi->s_mount_opt, EXTENTS); | 1334 | set_opt (sbi->s_mount_opt, EXTENTS); |
| 1313 | break; | 1335 | break; |
| 1314 | case Opt_noextents: | 1336 | case Opt_noextents: |
| 1337 | /* | ||
| 1338 | * When e2fsprogs support resizing an already existing | ||
| 1339 | * ext3 file system to greater than 2**32 we need to | ||
| 1340 | * add support to block allocator to handle growing | ||
| 1341 | * already existing block mapped inode so that blocks | ||
| 1342 | * allocated for them fall within 2**32 | ||
| 1343 | */ | ||
| 1344 | last_block = ext4_blocks_count(sbi->s_es) - 1; | ||
| 1345 | if (last_block > 0xffffffffULL) { | ||
| 1346 | printk(KERN_ERR "EXT4-fs: Filesystem too " | ||
| 1347 | "large to mount with " | ||
| 1348 | "-o noextents options\n"); | ||
| 1349 | return 0; | ||
| 1350 | } | ||
| 1315 | clear_opt (sbi->s_mount_opt, EXTENTS); | 1351 | clear_opt (sbi->s_mount_opt, EXTENTS); |
| 1316 | break; | 1352 | break; |
| 1317 | case Opt_i_version: | 1353 | case Opt_i_version: |
| 1318 | set_opt(sbi->s_mount_opt, I_VERSION); | 1354 | set_opt(sbi->s_mount_opt, I_VERSION); |
| 1319 | sb->s_flags |= MS_I_VERSION; | 1355 | sb->s_flags |= MS_I_VERSION; |
| 1320 | break; | 1356 | break; |
| 1357 | case Opt_nodelalloc: | ||
| 1358 | clear_opt(sbi->s_mount_opt, DELALLOC); | ||
| 1359 | break; | ||
| 1321 | case Opt_mballoc: | 1360 | case Opt_mballoc: |
| 1322 | set_opt(sbi->s_mount_opt, MBALLOC); | 1361 | set_opt(sbi->s_mount_opt, MBALLOC); |
| 1323 | break; | 1362 | break; |
| @@ -1331,6 +1370,9 @@ set_qf_format: | |||
| 1331 | return 0; | 1370 | return 0; |
| 1332 | sbi->s_stripe = option; | 1371 | sbi->s_stripe = option; |
| 1333 | break; | 1372 | break; |
| 1373 | case Opt_delalloc: | ||
| 1374 | set_opt(sbi->s_mount_opt, DELALLOC); | ||
| 1375 | break; | ||
| 1334 | default: | 1376 | default: |
| 1335 | printk (KERN_ERR | 1377 | printk (KERN_ERR |
| 1336 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1378 | "EXT4-fs: Unrecognized mount option \"%s\" " |
| @@ -1443,6 +1485,54 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, | |||
| 1443 | return res; | 1485 | return res; |
| 1444 | } | 1486 | } |
| 1445 | 1487 | ||
| 1488 | static int ext4_fill_flex_info(struct super_block *sb) | ||
| 1489 | { | ||
| 1490 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 1491 | struct ext4_group_desc *gdp = NULL; | ||
| 1492 | struct buffer_head *bh; | ||
| 1493 | ext4_group_t flex_group_count; | ||
| 1494 | ext4_group_t flex_group; | ||
| 1495 | int groups_per_flex = 0; | ||
| 1496 | __u64 block_bitmap = 0; | ||
| 1497 | int i; | ||
| 1498 | |||
| 1499 | if (!sbi->s_es->s_log_groups_per_flex) { | ||
| 1500 | sbi->s_log_groups_per_flex = 0; | ||
| 1501 | return 1; | ||
| 1502 | } | ||
| 1503 | |||
| 1504 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; | ||
| 1505 | groups_per_flex = 1 << sbi->s_log_groups_per_flex; | ||
| 1506 | |||
| 1507 | flex_group_count = (sbi->s_groups_count + groups_per_flex - 1) / | ||
| 1508 | groups_per_flex; | ||
| 1509 | sbi->s_flex_groups = kmalloc(flex_group_count * | ||
| 1510 | sizeof(struct flex_groups), GFP_KERNEL); | ||
| 1511 | if (sbi->s_flex_groups == NULL) { | ||
| 1512 | printk(KERN_ERR "EXT4-fs: not enough memory\n"); | ||
| 1513 | goto failed; | ||
| 1514 | } | ||
| 1515 | memset(sbi->s_flex_groups, 0, flex_group_count * | ||
| 1516 | sizeof(struct flex_groups)); | ||
| 1517 | |||
| 1518 | gdp = ext4_get_group_desc(sb, 1, &bh); | ||
| 1519 | block_bitmap = ext4_block_bitmap(sb, gdp) - 1; | ||
| 1520 | |||
| 1521 | for (i = 0; i < sbi->s_groups_count; i++) { | ||
| 1522 | gdp = ext4_get_group_desc(sb, i, &bh); | ||
| 1523 | |||
| 1524 | flex_group = ext4_flex_group(sbi, i); | ||
| 1525 | sbi->s_flex_groups[flex_group].free_inodes += | ||
| 1526 | le16_to_cpu(gdp->bg_free_inodes_count); | ||
| 1527 | sbi->s_flex_groups[flex_group].free_blocks += | ||
| 1528 | le16_to_cpu(gdp->bg_free_blocks_count); | ||
| 1529 | } | ||
| 1530 | |||
| 1531 | return 1; | ||
| 1532 | failed: | ||
| 1533 | return 0; | ||
| 1534 | } | ||
| 1535 | |||
| 1446 | __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, | 1536 | __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, |
| 1447 | struct ext4_group_desc *gdp) | 1537 | struct ext4_group_desc *gdp) |
| 1448 | { | 1538 | { |
| @@ -1810,8 +1900,8 @@ static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi) | |||
| 1810 | } | 1900 | } |
| 1811 | 1901 | ||
| 1812 | static int ext4_fill_super (struct super_block *sb, void *data, int silent) | 1902 | static int ext4_fill_super (struct super_block *sb, void *data, int silent) |
| 1813 | __releases(kernel_sem) | 1903 | __releases(kernel_lock) |
| 1814 | __acquires(kernel_sem) | 1904 | __acquires(kernel_lock) |
| 1815 | 1905 | ||
| 1816 | { | 1906 | { |
| 1817 | struct buffer_head * bh; | 1907 | struct buffer_head * bh; |
| @@ -1851,11 +1941,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
| 1851 | goto out_fail; | 1941 | goto out_fail; |
| 1852 | } | 1942 | } |
| 1853 | 1943 | ||
| 1854 | if (!sb_set_blocksize(sb, blocksize)) { | ||
| 1855 | printk(KERN_ERR "EXT4-fs: bad blocksize %d.\n", blocksize); | ||
| 1856 | goto out_fail; | ||
| 1857 | } | ||
| 1858 | |||
| 1859 | /* | 1944 | /* |
| 1860 | * The ext4 superblock will not be buffer aligned for other than 1kB | 1945 | * The ext4 superblock will not be buffer aligned for other than 1kB |
| 1861 | * block sizes. We need to calculate the offset from buffer start. | 1946 | * block sizes. We need to calculate the offset from buffer start. |
| @@ -1919,15 +2004,28 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
| 1919 | 2004 | ||
| 1920 | /* | 2005 | /* |
| 1921 | * turn on extents feature by default in ext4 filesystem | 2006 | * turn on extents feature by default in ext4 filesystem |
| 1922 | * User -o noextents to turn it off | 2007 | * only if feature flag already set by mkfs or tune2fs. |
| 2008 | * Use -o noextents to turn it off | ||
| 1923 | */ | 2009 | */ |
| 1924 | set_opt(sbi->s_mount_opt, EXTENTS); | 2010 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) |
| 2011 | set_opt(sbi->s_mount_opt, EXTENTS); | ||
| 2012 | else | ||
| 2013 | ext4_warning(sb, __func__, | ||
| 2014 | "extents feature not enabled on this filesystem, " | ||
| 2015 | "use tune2fs.\n"); | ||
| 1925 | /* | 2016 | /* |
| 1926 | * turn on mballoc feature by default in ext4 filesystem | 2017 | * turn on mballoc code by default in ext4 filesystem |
| 1927 | * User -o nomballoc to turn it off | 2018 | * Use -o nomballoc to turn it off |
| 1928 | */ | 2019 | */ |
| 1929 | set_opt(sbi->s_mount_opt, MBALLOC); | 2020 | set_opt(sbi->s_mount_opt, MBALLOC); |
| 1930 | 2021 | ||
| 2022 | /* | ||
| 2023 | * enable delayed allocation by default | ||
| 2024 | * Use -o nodelalloc to turn it off | ||
| 2025 | */ | ||
| 2026 | set_opt(sbi->s_mount_opt, DELALLOC); | ||
| 2027 | |||
| 2028 | |||
| 1931 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, | 2029 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, |
| 1932 | NULL, 0)) | 2030 | NULL, 0)) |
| 1933 | goto failed_mount; | 2031 | goto failed_mount; |
| @@ -2138,6 +2236,14 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
| 2138 | printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n"); | 2236 | printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n"); |
| 2139 | goto failed_mount2; | 2237 | goto failed_mount2; |
| 2140 | } | 2238 | } |
| 2239 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) | ||
| 2240 | if (!ext4_fill_flex_info(sb)) { | ||
| 2241 | printk(KERN_ERR | ||
| 2242 | "EXT4-fs: unable to initialize " | ||
| 2243 | "flex_bg meta info!\n"); | ||
| 2244 | goto failed_mount2; | ||
| 2245 | } | ||
| 2246 | |||
| 2141 | sbi->s_gdb_count = db_count; | 2247 | sbi->s_gdb_count = db_count; |
| 2142 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 2248 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
| 2143 | spin_lock_init(&sbi->s_next_gen_lock); | 2249 | spin_lock_init(&sbi->s_next_gen_lock); |
| @@ -2358,6 +2464,13 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
| 2358 | test_opt(sb,DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": | 2464 | test_opt(sb,DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": |
| 2359 | "writeback"); | 2465 | "writeback"); |
| 2360 | 2466 | ||
| 2467 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
| 2468 | printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " | ||
| 2469 | "requested data journaling mode\n"); | ||
| 2470 | clear_opt(sbi->s_mount_opt, DELALLOC); | ||
| 2471 | } else if (test_opt(sb, DELALLOC)) | ||
| 2472 | printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); | ||
| 2473 | |||
| 2361 | ext4_ext_init(sb); | 2474 | ext4_ext_init(sb); |
| 2362 | ext4_mb_init(sb, needs_recovery); | 2475 | ext4_mb_init(sb, needs_recovery); |
| 2363 | 2476 | ||
| @@ -2372,6 +2485,7 @@ cantfind_ext4: | |||
| 2372 | 2485 | ||
| 2373 | failed_mount4: | 2486 | failed_mount4: |
| 2374 | jbd2_journal_destroy(sbi->s_journal); | 2487 | jbd2_journal_destroy(sbi->s_journal); |
| 2488 | sbi->s_journal = NULL; | ||
| 2375 | failed_mount3: | 2489 | failed_mount3: |
| 2376 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 2490 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
| 2377 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 2491 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
| @@ -3325,7 +3439,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
| 3325 | err = ext4_journal_dirty_metadata(handle, bh); | 3439 | err = ext4_journal_dirty_metadata(handle, bh); |
| 3326 | else { | 3440 | else { |
| 3327 | /* Always do at least ordered writes for quotas */ | 3441 | /* Always do at least ordered writes for quotas */ |
| 3328 | err = ext4_journal_dirty_data(handle, bh); | 3442 | err = ext4_jbd2_file_inode(handle, inode); |
| 3329 | mark_buffer_dirty(bh); | 3443 | mark_buffer_dirty(bh); |
| 3330 | } | 3444 | } |
| 3331 | brelse(bh); | 3445 | brelse(bh); |
