diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 146 |
1 files changed, 131 insertions, 15 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index cb96f127c366..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); |
@@ -3337,8 +3451,10 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3337 | blk++; | 3451 | blk++; |
3338 | } | 3452 | } |
3339 | out: | 3453 | out: |
3340 | if (len == towrite) | 3454 | if (len == towrite) { |
3455 | mutex_unlock(&inode->i_mutex); | ||
3341 | return err; | 3456 | return err; |
3457 | } | ||
3342 | if (inode->i_size < off+len-towrite) { | 3458 | if (inode->i_size < off+len-towrite) { |
3343 | i_size_write(inode, off+len-towrite); | 3459 | i_size_write(inode, off+len-towrite); |
3344 | EXT4_I(inode)->i_disksize = inode->i_size; | 3460 | EXT4_I(inode)->i_disksize = inode->i_size; |