diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 101 |
1 files changed, 86 insertions, 15 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 175b68c60968..75adbb64e028 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -29,12 +29,14 @@ | |||
29 | #include <linux/parser.h> | 29 | #include <linux/parser.h> |
30 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
31 | #include <linux/buffer_head.h> | 31 | #include <linux/buffer_head.h> |
32 | #include <linux/exportfs.h> | ||
32 | #include <linux/vfs.h> | 33 | #include <linux/vfs.h> |
33 | #include <linux/random.h> | 34 | #include <linux/random.h> |
34 | #include <linux/mount.h> | 35 | #include <linux/mount.h> |
35 | #include <linux/namei.h> | 36 | #include <linux/namei.h> |
36 | #include <linux/quotaops.h> | 37 | #include <linux/quotaops.h> |
37 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/log2.h> | ||
38 | 40 | ||
39 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
40 | 42 | ||
@@ -510,6 +512,14 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
510 | 512 | ||
511 | static void ext4_destroy_inode(struct inode *inode) | 513 | static void ext4_destroy_inode(struct inode *inode) |
512 | { | 514 | { |
515 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | ||
516 | printk("EXT4 Inode %p: orphan list check failed!\n", | ||
517 | EXT4_I(inode)); | ||
518 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4, | ||
519 | EXT4_I(inode), sizeof(struct ext4_inode_info), | ||
520 | true); | ||
521 | dump_stack(); | ||
522 | } | ||
513 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); | 523 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); |
514 | } | 524 | } |
515 | 525 | ||
@@ -531,7 +541,7 @@ static int init_inodecache(void) | |||
531 | sizeof(struct ext4_inode_info), | 541 | sizeof(struct ext4_inode_info), |
532 | 0, (SLAB_RECLAIM_ACCOUNT| | 542 | 0, (SLAB_RECLAIM_ACCOUNT| |
533 | SLAB_MEM_SPREAD), | 543 | SLAB_MEM_SPREAD), |
534 | init_once, NULL); | 544 | init_once); |
535 | if (ext4_inode_cachep == NULL) | 545 | if (ext4_inode_cachep == NULL) |
536 | return -ENOMEM; | 546 | return -ENOMEM; |
537 | return 0; | 547 | return 0; |
@@ -725,7 +735,7 @@ enum { | |||
725 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 735 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
726 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 736 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
727 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 737 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
728 | Opt_grpquota, Opt_extents, | 738 | Opt_grpquota, Opt_extents, Opt_noextents, |
729 | }; | 739 | }; |
730 | 740 | ||
731 | static match_table_t tokens = { | 741 | static match_table_t tokens = { |
@@ -776,6 +786,7 @@ static match_table_t tokens = { | |||
776 | {Opt_usrquota, "usrquota"}, | 786 | {Opt_usrquota, "usrquota"}, |
777 | {Opt_barrier, "barrier=%u"}, | 787 | {Opt_barrier, "barrier=%u"}, |
778 | {Opt_extents, "extents"}, | 788 | {Opt_extents, "extents"}, |
789 | {Opt_noextents, "noextents"}, | ||
779 | {Opt_err, NULL}, | 790 | {Opt_err, NULL}, |
780 | {Opt_resize, "resize"}, | 791 | {Opt_resize, "resize"}, |
781 | }; | 792 | }; |
@@ -1111,6 +1122,9 @@ clear_qf_name: | |||
1111 | case Opt_extents: | 1122 | case Opt_extents: |
1112 | set_opt (sbi->s_mount_opt, EXTENTS); | 1123 | set_opt (sbi->s_mount_opt, EXTENTS); |
1113 | break; | 1124 | break; |
1125 | case Opt_noextents: | ||
1126 | clear_opt (sbi->s_mount_opt, EXTENTS); | ||
1127 | break; | ||
1114 | default: | 1128 | default: |
1115 | printk (KERN_ERR | 1129 | printk (KERN_ERR |
1116 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1130 | "EXT4-fs: Unrecognized mount option \"%s\" " |
@@ -1542,6 +1556,12 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1542 | 1556 | ||
1543 | set_opt(sbi->s_mount_opt, RESERVATION); | 1557 | set_opt(sbi->s_mount_opt, RESERVATION); |
1544 | 1558 | ||
1559 | /* | ||
1560 | * turn on extents feature by default in ext4 filesystem | ||
1561 | * User -o noextents to turn it off | ||
1562 | */ | ||
1563 | set_opt(sbi->s_mount_opt, EXTENTS); | ||
1564 | |||
1545 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, | 1565 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, |
1546 | NULL, 0)) | 1566 | NULL, 0)) |
1547 | goto failed_mount; | 1567 | goto failed_mount; |
@@ -1625,13 +1645,15 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1625 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); | 1645 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); |
1626 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); | 1646 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); |
1627 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || | 1647 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || |
1628 | (sbi->s_inode_size & (sbi->s_inode_size - 1)) || | 1648 | (!is_power_of_2(sbi->s_inode_size)) || |
1629 | (sbi->s_inode_size > blocksize)) { | 1649 | (sbi->s_inode_size > blocksize)) { |
1630 | printk (KERN_ERR | 1650 | printk (KERN_ERR |
1631 | "EXT4-fs: unsupported inode size: %d\n", | 1651 | "EXT4-fs: unsupported inode size: %d\n", |
1632 | sbi->s_inode_size); | 1652 | sbi->s_inode_size); |
1633 | goto failed_mount; | 1653 | goto failed_mount; |
1634 | } | 1654 | } |
1655 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) | ||
1656 | sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); | ||
1635 | } | 1657 | } |
1636 | sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << | 1658 | sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << |
1637 | le32_to_cpu(es->s_log_frag_size); | 1659 | le32_to_cpu(es->s_log_frag_size); |
@@ -1794,6 +1816,13 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1794 | goto failed_mount3; | 1816 | goto failed_mount3; |
1795 | } | 1817 | } |
1796 | 1818 | ||
1819 | if (ext4_blocks_count(es) > 0xffffffffULL && | ||
1820 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, | ||
1821 | JBD2_FEATURE_INCOMPAT_64BIT)) { | ||
1822 | printk(KERN_ERR "ext4: Failed to set 64-bit journal feature\n"); | ||
1823 | goto failed_mount4; | ||
1824 | } | ||
1825 | |||
1797 | /* We have now updated the journal if required, so we can | 1826 | /* We have now updated the journal if required, so we can |
1798 | * validate the data journaling mode. */ | 1827 | * validate the data journaling mode. */ |
1799 | switch (test_opt(sb, DATA_FLAGS)) { | 1828 | switch (test_opt(sb, DATA_FLAGS)) { |
@@ -1848,6 +1877,32 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1848 | } | 1877 | } |
1849 | 1878 | ||
1850 | ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY); | 1879 | ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY); |
1880 | |||
1881 | /* determine the minimum size of new large inodes, if present */ | ||
1882 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) { | ||
1883 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - | ||
1884 | EXT4_GOOD_OLD_INODE_SIZE; | ||
1885 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, | ||
1886 | EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) { | ||
1887 | if (sbi->s_want_extra_isize < | ||
1888 | le16_to_cpu(es->s_want_extra_isize)) | ||
1889 | sbi->s_want_extra_isize = | ||
1890 | le16_to_cpu(es->s_want_extra_isize); | ||
1891 | if (sbi->s_want_extra_isize < | ||
1892 | le16_to_cpu(es->s_min_extra_isize)) | ||
1893 | sbi->s_want_extra_isize = | ||
1894 | le16_to_cpu(es->s_min_extra_isize); | ||
1895 | } | ||
1896 | } | ||
1897 | /* Check if enough inode space is available */ | ||
1898 | if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize > | ||
1899 | sbi->s_inode_size) { | ||
1900 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - | ||
1901 | EXT4_GOOD_OLD_INODE_SIZE; | ||
1902 | printk(KERN_INFO "EXT4-fs: required extra inode space not" | ||
1903 | "available.\n"); | ||
1904 | } | ||
1905 | |||
1851 | /* | 1906 | /* |
1852 | * akpm: core read_super() calls in here with the superblock locked. | 1907 | * akpm: core read_super() calls in here with the superblock locked. |
1853 | * That deadlocks, because orphan cleanup needs to lock the superblock | 1908 | * That deadlocks, because orphan cleanup needs to lock the superblock |
@@ -2150,6 +2205,7 @@ static int ext4_create_journal(struct super_block * sb, | |||
2150 | unsigned int journal_inum) | 2205 | unsigned int journal_inum) |
2151 | { | 2206 | { |
2152 | journal_t *journal; | 2207 | journal_t *journal; |
2208 | int err; | ||
2153 | 2209 | ||
2154 | if (sb->s_flags & MS_RDONLY) { | 2210 | if (sb->s_flags & MS_RDONLY) { |
2155 | printk(KERN_ERR "EXT4-fs: readonly filesystem when trying to " | 2211 | printk(KERN_ERR "EXT4-fs: readonly filesystem when trying to " |
@@ -2157,13 +2213,15 @@ static int ext4_create_journal(struct super_block * sb, | |||
2157 | return -EROFS; | 2213 | return -EROFS; |
2158 | } | 2214 | } |
2159 | 2215 | ||
2160 | if (!(journal = ext4_get_journal(sb, journal_inum))) | 2216 | journal = ext4_get_journal(sb, journal_inum); |
2217 | if (!journal) | ||
2161 | return -EINVAL; | 2218 | return -EINVAL; |
2162 | 2219 | ||
2163 | printk(KERN_INFO "EXT4-fs: creating new journal on inode %u\n", | 2220 | printk(KERN_INFO "EXT4-fs: creating new journal on inode %u\n", |
2164 | journal_inum); | 2221 | journal_inum); |
2165 | 2222 | ||
2166 | if (jbd2_journal_create(journal)) { | 2223 | err = jbd2_journal_create(journal); |
2224 | if (err) { | ||
2167 | printk(KERN_ERR "EXT4-fs: error creating journal.\n"); | 2225 | printk(KERN_ERR "EXT4-fs: error creating journal.\n"); |
2168 | jbd2_journal_destroy(journal); | 2226 | jbd2_journal_destroy(journal); |
2169 | return -EIO; | 2227 | return -EIO; |
@@ -2214,12 +2272,14 @@ static void ext4_mark_recovery_complete(struct super_block * sb, | |||
2214 | 2272 | ||
2215 | jbd2_journal_lock_updates(journal); | 2273 | jbd2_journal_lock_updates(journal); |
2216 | jbd2_journal_flush(journal); | 2274 | jbd2_journal_flush(journal); |
2275 | lock_super(sb); | ||
2217 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && | 2276 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && |
2218 | sb->s_flags & MS_RDONLY) { | 2277 | sb->s_flags & MS_RDONLY) { |
2219 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 2278 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
2220 | sb->s_dirt = 0; | 2279 | sb->s_dirt = 0; |
2221 | ext4_commit_super(sb, es, 1); | 2280 | ext4_commit_super(sb, es, 1); |
2222 | } | 2281 | } |
2282 | unlock_super(sb); | ||
2223 | jbd2_journal_unlock_updates(journal); | 2283 | jbd2_journal_unlock_updates(journal); |
2224 | } | 2284 | } |
2225 | 2285 | ||
@@ -2408,7 +2468,13 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data) | |||
2408 | (sbi->s_mount_state & EXT4_VALID_FS)) | 2468 | (sbi->s_mount_state & EXT4_VALID_FS)) |
2409 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 2469 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
2410 | 2470 | ||
2471 | /* | ||
2472 | * We have to unlock super so that we can wait for | ||
2473 | * transactions. | ||
2474 | */ | ||
2475 | unlock_super(sb); | ||
2411 | ext4_mark_recovery_complete(sb, es); | 2476 | ext4_mark_recovery_complete(sb, es); |
2477 | lock_super(sb); | ||
2412 | } else { | 2478 | } else { |
2413 | __le32 ret; | 2479 | __le32 ret; |
2414 | if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, | 2480 | if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, |
@@ -2481,19 +2547,19 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2481 | struct super_block *sb = dentry->d_sb; | 2547 | struct super_block *sb = dentry->d_sb; |
2482 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2548 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2483 | struct ext4_super_block *es = sbi->s_es; | 2549 | struct ext4_super_block *es = sbi->s_es; |
2484 | ext4_fsblk_t overhead; | ||
2485 | int i; | ||
2486 | u64 fsid; | 2550 | u64 fsid; |
2487 | 2551 | ||
2488 | if (test_opt (sb, MINIX_DF)) | 2552 | if (test_opt(sb, MINIX_DF)) { |
2489 | overhead = 0; | 2553 | sbi->s_overhead_last = 0; |
2490 | else { | 2554 | } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { |
2491 | unsigned long ngroups; | 2555 | unsigned long ngroups = sbi->s_groups_count, i; |
2492 | ngroups = EXT4_SB(sb)->s_groups_count; | 2556 | ext4_fsblk_t overhead = 0; |
2493 | smp_rmb(); | 2557 | smp_rmb(); |
2494 | 2558 | ||
2495 | /* | 2559 | /* |
2496 | * Compute the overhead (FS structures) | 2560 | * Compute the overhead (FS structures). This is constant |
2561 | * for a given filesystem unless the number of block groups | ||
2562 | * changes so we cache the previous value until it does. | ||
2497 | */ | 2563 | */ |
2498 | 2564 | ||
2499 | /* | 2565 | /* |
@@ -2517,18 +2583,23 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2517 | * Every block group has an inode bitmap, a block | 2583 | * Every block group has an inode bitmap, a block |
2518 | * bitmap, and an inode table. | 2584 | * bitmap, and an inode table. |
2519 | */ | 2585 | */ |
2520 | overhead += (ngroups * (2 + EXT4_SB(sb)->s_itb_per_group)); | 2586 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
2587 | sbi->s_overhead_last = overhead; | ||
2588 | smp_wmb(); | ||
2589 | sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); | ||
2521 | } | 2590 | } |
2522 | 2591 | ||
2523 | buf->f_type = EXT4_SUPER_MAGIC; | 2592 | buf->f_type = EXT4_SUPER_MAGIC; |
2524 | buf->f_bsize = sb->s_blocksize; | 2593 | buf->f_bsize = sb->s_blocksize; |
2525 | buf->f_blocks = ext4_blocks_count(es) - overhead; | 2594 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
2526 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); | 2595 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); |
2596 | es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); | ||
2527 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); | 2597 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
2528 | if (buf->f_bfree < ext4_r_blocks_count(es)) | 2598 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
2529 | buf->f_bavail = 0; | 2599 | buf->f_bavail = 0; |
2530 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2600 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2531 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2601 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2602 | es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); | ||
2532 | buf->f_namelen = EXT4_NAME_LEN; | 2603 | buf->f_namelen = EXT4_NAME_LEN; |
2533 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | 2604 | fsid = le64_to_cpup((void *)es->s_uuid) ^ |
2534 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | 2605 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |