diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 437 |
1 files changed, 258 insertions, 179 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 566344b926b7..9b2b2bc4ec17 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
35 | #include <linux/quotaops.h> | 35 | #include <linux/quotaops.h> |
36 | #include <linux/seq_file.h> | 36 | #include <linux/seq_file.h> |
37 | #include <linux/proc_fs.h> | ||
38 | #include <linux/marker.h> | ||
37 | #include <linux/log2.h> | 39 | #include <linux/log2.h> |
38 | #include <linux/crc16.h> | 40 | #include <linux/crc16.h> |
39 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
@@ -45,6 +47,8 @@ | |||
45 | #include "namei.h" | 47 | #include "namei.h" |
46 | #include "group.h" | 48 | #include "group.h" |
47 | 49 | ||
50 | struct proc_dir_entry *ext4_proc_root; | ||
51 | |||
48 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, | 52 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, |
49 | unsigned long journal_devnum); | 53 | unsigned long journal_devnum); |
50 | static int ext4_create_journal(struct super_block *, struct ext4_super_block *, | 54 | static int ext4_create_journal(struct super_block *, struct ext4_super_block *, |
@@ -370,66 +374,6 @@ void ext4_update_dynamic_rev(struct super_block *sb) | |||
370 | */ | 374 | */ |
371 | } | 375 | } |
372 | 376 | ||
373 | int ext4_update_compat_feature(handle_t *handle, | ||
374 | struct super_block *sb, __u32 compat) | ||
375 | { | ||
376 | int err = 0; | ||
377 | if (!EXT4_HAS_COMPAT_FEATURE(sb, compat)) { | ||
378 | err = ext4_journal_get_write_access(handle, | ||
379 | EXT4_SB(sb)->s_sbh); | ||
380 | if (err) | ||
381 | return err; | ||
382 | EXT4_SET_COMPAT_FEATURE(sb, compat); | ||
383 | sb->s_dirt = 1; | ||
384 | handle->h_sync = 1; | ||
385 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, | ||
386 | "call ext4_journal_dirty_met adata"); | ||
387 | err = ext4_journal_dirty_metadata(handle, | ||
388 | EXT4_SB(sb)->s_sbh); | ||
389 | } | ||
390 | return err; | ||
391 | } | ||
392 | |||
393 | int ext4_update_rocompat_feature(handle_t *handle, | ||
394 | struct super_block *sb, __u32 rocompat) | ||
395 | { | ||
396 | int err = 0; | ||
397 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, rocompat)) { | ||
398 | err = ext4_journal_get_write_access(handle, | ||
399 | EXT4_SB(sb)->s_sbh); | ||
400 | if (err) | ||
401 | return err; | ||
402 | EXT4_SET_RO_COMPAT_FEATURE(sb, rocompat); | ||
403 | sb->s_dirt = 1; | ||
404 | handle->h_sync = 1; | ||
405 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, | ||
406 | "call ext4_journal_dirty_met adata"); | ||
407 | err = ext4_journal_dirty_metadata(handle, | ||
408 | EXT4_SB(sb)->s_sbh); | ||
409 | } | ||
410 | return err; | ||
411 | } | ||
412 | |||
413 | int ext4_update_incompat_feature(handle_t *handle, | ||
414 | struct super_block *sb, __u32 incompat) | ||
415 | { | ||
416 | int err = 0; | ||
417 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, incompat)) { | ||
418 | err = ext4_journal_get_write_access(handle, | ||
419 | EXT4_SB(sb)->s_sbh); | ||
420 | if (err) | ||
421 | return err; | ||
422 | EXT4_SET_INCOMPAT_FEATURE(sb, incompat); | ||
423 | sb->s_dirt = 1; | ||
424 | handle->h_sync = 1; | ||
425 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, | ||
426 | "call ext4_journal_dirty_met adata"); | ||
427 | err = ext4_journal_dirty_metadata(handle, | ||
428 | EXT4_SB(sb)->s_sbh); | ||
429 | } | ||
430 | return err; | ||
431 | } | ||
432 | |||
433 | /* | 377 | /* |
434 | * Open the external journal device | 378 | * Open the external journal device |
435 | */ | 379 | */ |
@@ -503,15 +447,18 @@ static void ext4_put_super(struct super_block *sb) | |||
503 | ext4_mb_release(sb); | 447 | ext4_mb_release(sb); |
504 | ext4_ext_release(sb); | 448 | ext4_ext_release(sb); |
505 | ext4_xattr_put_super(sb); | 449 | ext4_xattr_put_super(sb); |
506 | jbd2_journal_destroy(sbi->s_journal); | 450 | if (jbd2_journal_destroy(sbi->s_journal) < 0) |
451 | ext4_abort(sb, __func__, "Couldn't clean up the journal"); | ||
507 | sbi->s_journal = NULL; | 452 | sbi->s_journal = NULL; |
508 | if (!(sb->s_flags & MS_RDONLY)) { | 453 | if (!(sb->s_flags & MS_RDONLY)) { |
509 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 454 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
510 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 455 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
511 | BUFFER_TRACE(sbi->s_sbh, "marking dirty"); | ||
512 | mark_buffer_dirty(sbi->s_sbh); | ||
513 | ext4_commit_super(sb, es, 1); | 456 | ext4_commit_super(sb, es, 1); |
514 | } | 457 | } |
458 | if (sbi->s_proc) { | ||
459 | remove_proc_entry("inode_readahead_blks", sbi->s_proc); | ||
460 | remove_proc_entry(sb->s_id, ext4_proc_root); | ||
461 | } | ||
515 | 462 | ||
516 | for (i = 0; i < sbi->s_gdb_count; i++) | 463 | for (i = 0; i < sbi->s_gdb_count; i++) |
517 | brelse(sbi->s_group_desc[i]); | 464 | brelse(sbi->s_group_desc[i]); |
@@ -520,6 +467,7 @@ static void ext4_put_super(struct super_block *sb) | |||
520 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 467 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
521 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 468 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
522 | percpu_counter_destroy(&sbi->s_dirs_counter); | 469 | percpu_counter_destroy(&sbi->s_dirs_counter); |
470 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
523 | brelse(sbi->s_sbh); | 471 | brelse(sbi->s_sbh); |
524 | #ifdef CONFIG_QUOTA | 472 | #ifdef CONFIG_QUOTA |
525 | for (i = 0; i < MAXQUOTAS; i++) | 473 | for (i = 0; i < MAXQUOTAS; i++) |
@@ -562,11 +510,10 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
562 | ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); | 510 | ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); |
563 | if (!ei) | 511 | if (!ei) |
564 | return NULL; | 512 | return NULL; |
565 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL | 513 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
566 | ei->i_acl = EXT4_ACL_NOT_CACHED; | 514 | ei->i_acl = EXT4_ACL_NOT_CACHED; |
567 | ei->i_default_acl = EXT4_ACL_NOT_CACHED; | 515 | ei->i_default_acl = EXT4_ACL_NOT_CACHED; |
568 | #endif | 516 | #endif |
569 | ei->i_block_alloc_info = NULL; | ||
570 | ei->vfs_inode.i_version = 1; | 517 | ei->vfs_inode.i_version = 1; |
571 | ei->vfs_inode.i_data.writeback_index = 0; | 518 | ei->vfs_inode.i_data.writeback_index = 0; |
572 | memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); | 519 | memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); |
@@ -599,7 +546,7 @@ static void init_once(void *foo) | |||
599 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; | 546 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; |
600 | 547 | ||
601 | INIT_LIST_HEAD(&ei->i_orphan); | 548 | INIT_LIST_HEAD(&ei->i_orphan); |
602 | #ifdef CONFIG_EXT4DEV_FS_XATTR | 549 | #ifdef CONFIG_EXT4_FS_XATTR |
603 | init_rwsem(&ei->xattr_sem); | 550 | init_rwsem(&ei->xattr_sem); |
604 | #endif | 551 | #endif |
605 | init_rwsem(&ei->i_data_sem); | 552 | init_rwsem(&ei->i_data_sem); |
@@ -625,8 +572,7 @@ static void destroy_inodecache(void) | |||
625 | 572 | ||
626 | static void ext4_clear_inode(struct inode *inode) | 573 | static void ext4_clear_inode(struct inode *inode) |
627 | { | 574 | { |
628 | struct ext4_block_alloc_info *rsv = EXT4_I(inode)->i_block_alloc_info; | 575 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
629 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL | ||
630 | if (EXT4_I(inode)->i_acl && | 576 | if (EXT4_I(inode)->i_acl && |
631 | EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) { | 577 | EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) { |
632 | posix_acl_release(EXT4_I(inode)->i_acl); | 578 | posix_acl_release(EXT4_I(inode)->i_acl); |
@@ -638,10 +584,7 @@ static void ext4_clear_inode(struct inode *inode) | |||
638 | EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED; | 584 | EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED; |
639 | } | 585 | } |
640 | #endif | 586 | #endif |
641 | ext4_discard_reservation(inode); | 587 | ext4_discard_preallocations(inode); |
642 | EXT4_I(inode)->i_block_alloc_info = NULL; | ||
643 | if (unlikely(rsv)) | ||
644 | kfree(rsv); | ||
645 | jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, | 588 | jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, |
646 | &EXT4_I(inode)->jinode); | 589 | &EXT4_I(inode)->jinode); |
647 | } | 590 | } |
@@ -654,7 +597,7 @@ static inline void ext4_show_quota_options(struct seq_file *seq, | |||
654 | 597 | ||
655 | if (sbi->s_jquota_fmt) | 598 | if (sbi->s_jquota_fmt) |
656 | seq_printf(seq, ",jqfmt=%s", | 599 | seq_printf(seq, ",jqfmt=%s", |
657 | (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0"); | 600 | (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold" : "vfsv0"); |
658 | 601 | ||
659 | if (sbi->s_qf_names[USRQUOTA]) | 602 | if (sbi->s_qf_names[USRQUOTA]) |
660 | seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); | 603 | seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); |
@@ -718,7 +661,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
718 | seq_puts(seq, ",debug"); | 661 | seq_puts(seq, ",debug"); |
719 | if (test_opt(sb, OLDALLOC)) | 662 | if (test_opt(sb, OLDALLOC)) |
720 | seq_puts(seq, ",oldalloc"); | 663 | seq_puts(seq, ",oldalloc"); |
721 | #ifdef CONFIG_EXT4DEV_FS_XATTR | 664 | #ifdef CONFIG_EXT4_FS_XATTR |
722 | if (test_opt(sb, XATTR_USER) && | 665 | if (test_opt(sb, XATTR_USER) && |
723 | !(def_mount_opts & EXT4_DEFM_XATTR_USER)) | 666 | !(def_mount_opts & EXT4_DEFM_XATTR_USER)) |
724 | seq_puts(seq, ",user_xattr"); | 667 | seq_puts(seq, ",user_xattr"); |
@@ -727,7 +670,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
727 | seq_puts(seq, ",nouser_xattr"); | 670 | seq_puts(seq, ",nouser_xattr"); |
728 | } | 671 | } |
729 | #endif | 672 | #endif |
730 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL | 673 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
731 | if (test_opt(sb, POSIX_ACL) && !(def_mount_opts & EXT4_DEFM_ACL)) | 674 | if (test_opt(sb, POSIX_ACL) && !(def_mount_opts & EXT4_DEFM_ACL)) |
732 | seq_puts(seq, ",acl"); | 675 | seq_puts(seq, ",acl"); |
733 | if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL)) | 676 | if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL)) |
@@ -752,8 +695,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
752 | seq_puts(seq, ",nobh"); | 695 | seq_puts(seq, ",nobh"); |
753 | if (!test_opt(sb, EXTENTS)) | 696 | if (!test_opt(sb, EXTENTS)) |
754 | seq_puts(seq, ",noextents"); | 697 | seq_puts(seq, ",noextents"); |
755 | if (!test_opt(sb, MBALLOC)) | ||
756 | seq_puts(seq, ",nomballoc"); | ||
757 | if (test_opt(sb, I_VERSION)) | 698 | if (test_opt(sb, I_VERSION)) |
758 | seq_puts(seq, ",i_version"); | 699 | seq_puts(seq, ",i_version"); |
759 | if (!test_opt(sb, DELALLOC)) | 700 | if (!test_opt(sb, DELALLOC)) |
@@ -773,6 +714,13 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
773 | else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | 714 | else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) |
774 | seq_puts(seq, ",data=writeback"); | 715 | seq_puts(seq, ",data=writeback"); |
775 | 716 | ||
717 | if (sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS) | ||
718 | seq_printf(seq, ",inode_readahead_blks=%u", | ||
719 | sbi->s_inode_readahead_blks); | ||
720 | |||
721 | if (test_opt(sb, DATA_ERR_ABORT)) | ||
722 | seq_puts(seq, ",data_err=abort"); | ||
723 | |||
776 | ext4_show_quota_options(seq, sb); | 724 | ext4_show_quota_options(seq, sb); |
777 | return 0; | 725 | return 0; |
778 | } | 726 | } |
@@ -822,7 +770,7 @@ static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
822 | } | 770 | } |
823 | 771 | ||
824 | #ifdef CONFIG_QUOTA | 772 | #ifdef CONFIG_QUOTA |
825 | #define QTYPE2NAME(t) ((t) == USRQUOTA?"user":"group") | 773 | #define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group") |
826 | #define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) | 774 | #define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) |
827 | 775 | ||
828 | static int ext4_dquot_initialize(struct inode *inode, int type); | 776 | static int ext4_dquot_initialize(struct inode *inode, int type); |
@@ -896,20 +844,22 @@ static const struct export_operations ext4_export_ops = { | |||
896 | enum { | 844 | enum { |
897 | Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, | 845 | Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, |
898 | Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, | 846 | Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, |
899 | Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, | 847 | Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov, |
900 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, | 848 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, |
901 | Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, | 849 | Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, |
902 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, | 850 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, |
903 | Opt_journal_checksum, Opt_journal_async_commit, | 851 | Opt_journal_checksum, Opt_journal_async_commit, |
904 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, | 852 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, |
853 | Opt_data_err_abort, Opt_data_err_ignore, | ||
905 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 854 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
906 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 855 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
907 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 856 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
908 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, | 857 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, |
909 | Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 858 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
859 | Opt_inode_readahead_blks | ||
910 | }; | 860 | }; |
911 | 861 | ||
912 | static match_table_t tokens = { | 862 | static const match_table_t tokens = { |
913 | {Opt_bsd_df, "bsddf"}, | 863 | {Opt_bsd_df, "bsddf"}, |
914 | {Opt_minix_df, "minixdf"}, | 864 | {Opt_minix_df, "minixdf"}, |
915 | {Opt_grpid, "grpid"}, | 865 | {Opt_grpid, "grpid"}, |
@@ -923,8 +873,6 @@ static match_table_t tokens = { | |||
923 | {Opt_err_panic, "errors=panic"}, | 873 | {Opt_err_panic, "errors=panic"}, |
924 | {Opt_err_ro, "errors=remount-ro"}, | 874 | {Opt_err_ro, "errors=remount-ro"}, |
925 | {Opt_nouid32, "nouid32"}, | 875 | {Opt_nouid32, "nouid32"}, |
926 | {Opt_nocheck, "nocheck"}, | ||
927 | {Opt_nocheck, "check=none"}, | ||
928 | {Opt_debug, "debug"}, | 876 | {Opt_debug, "debug"}, |
929 | {Opt_oldalloc, "oldalloc"}, | 877 | {Opt_oldalloc, "oldalloc"}, |
930 | {Opt_orlov, "orlov"}, | 878 | {Opt_orlov, "orlov"}, |
@@ -947,6 +895,8 @@ static match_table_t tokens = { | |||
947 | {Opt_data_journal, "data=journal"}, | 895 | {Opt_data_journal, "data=journal"}, |
948 | {Opt_data_ordered, "data=ordered"}, | 896 | {Opt_data_ordered, "data=ordered"}, |
949 | {Opt_data_writeback, "data=writeback"}, | 897 | {Opt_data_writeback, "data=writeback"}, |
898 | {Opt_data_err_abort, "data_err=abort"}, | ||
899 | {Opt_data_err_ignore, "data_err=ignore"}, | ||
950 | {Opt_offusrjquota, "usrjquota="}, | 900 | {Opt_offusrjquota, "usrjquota="}, |
951 | {Opt_usrjquota, "usrjquota=%s"}, | 901 | {Opt_usrjquota, "usrjquota=%s"}, |
952 | {Opt_offgrpjquota, "grpjquota="}, | 902 | {Opt_offgrpjquota, "grpjquota="}, |
@@ -961,12 +911,11 @@ static match_table_t tokens = { | |||
961 | {Opt_extents, "extents"}, | 911 | {Opt_extents, "extents"}, |
962 | {Opt_noextents, "noextents"}, | 912 | {Opt_noextents, "noextents"}, |
963 | {Opt_i_version, "i_version"}, | 913 | {Opt_i_version, "i_version"}, |
964 | {Opt_mballoc, "mballoc"}, | ||
965 | {Opt_nomballoc, "nomballoc"}, | ||
966 | {Opt_stripe, "stripe=%u"}, | 914 | {Opt_stripe, "stripe=%u"}, |
967 | {Opt_resize, "resize"}, | 915 | {Opt_resize, "resize"}, |
968 | {Opt_delalloc, "delalloc"}, | 916 | {Opt_delalloc, "delalloc"}, |
969 | {Opt_nodelalloc, "nodelalloc"}, | 917 | {Opt_nodelalloc, "nodelalloc"}, |
918 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, | ||
970 | {Opt_err, NULL}, | 919 | {Opt_err, NULL}, |
971 | }; | 920 | }; |
972 | 921 | ||
@@ -981,7 +930,7 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
981 | /*todo: use simple_strtoll with >32bit ext4 */ | 930 | /*todo: use simple_strtoll with >32bit ext4 */ |
982 | sb_block = simple_strtoul(options, &options, 0); | 931 | sb_block = simple_strtoul(options, &options, 0); |
983 | if (*options && *options != ',') { | 932 | if (*options && *options != ',') { |
984 | printk("EXT4-fs: Invalid sb specification: %s\n", | 933 | printk(KERN_ERR "EXT4-fs: Invalid sb specification: %s\n", |
985 | (char *) *data); | 934 | (char *) *data); |
986 | return 1; | 935 | return 1; |
987 | } | 936 | } |
@@ -1060,9 +1009,6 @@ static int parse_options(char *options, struct super_block *sb, | |||
1060 | case Opt_nouid32: | 1009 | case Opt_nouid32: |
1061 | set_opt(sbi->s_mount_opt, NO_UID32); | 1010 | set_opt(sbi->s_mount_opt, NO_UID32); |
1062 | break; | 1011 | break; |
1063 | case Opt_nocheck: | ||
1064 | clear_opt(sbi->s_mount_opt, CHECK); | ||
1065 | break; | ||
1066 | case Opt_debug: | 1012 | case Opt_debug: |
1067 | set_opt(sbi->s_mount_opt, DEBUG); | 1013 | set_opt(sbi->s_mount_opt, DEBUG); |
1068 | break; | 1014 | break; |
@@ -1072,7 +1018,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
1072 | case Opt_orlov: | 1018 | case Opt_orlov: |
1073 | clear_opt(sbi->s_mount_opt, OLDALLOC); | 1019 | clear_opt(sbi->s_mount_opt, OLDALLOC); |
1074 | break; | 1020 | break; |
1075 | #ifdef CONFIG_EXT4DEV_FS_XATTR | 1021 | #ifdef CONFIG_EXT4_FS_XATTR |
1076 | case Opt_user_xattr: | 1022 | case Opt_user_xattr: |
1077 | set_opt(sbi->s_mount_opt, XATTR_USER); | 1023 | set_opt(sbi->s_mount_opt, XATTR_USER); |
1078 | break; | 1024 | break; |
@@ -1082,10 +1028,11 @@ static int parse_options(char *options, struct super_block *sb, | |||
1082 | #else | 1028 | #else |
1083 | case Opt_user_xattr: | 1029 | case Opt_user_xattr: |
1084 | case Opt_nouser_xattr: | 1030 | case Opt_nouser_xattr: |
1085 | printk("EXT4 (no)user_xattr options not supported\n"); | 1031 | printk(KERN_ERR "EXT4 (no)user_xattr options " |
1032 | "not supported\n"); | ||
1086 | break; | 1033 | break; |
1087 | #endif | 1034 | #endif |
1088 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL | 1035 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
1089 | case Opt_acl: | 1036 | case Opt_acl: |
1090 | set_opt(sbi->s_mount_opt, POSIX_ACL); | 1037 | set_opt(sbi->s_mount_opt, POSIX_ACL); |
1091 | break; | 1038 | break; |
@@ -1095,7 +1042,8 @@ static int parse_options(char *options, struct super_block *sb, | |||
1095 | #else | 1042 | #else |
1096 | case Opt_acl: | 1043 | case Opt_acl: |
1097 | case Opt_noacl: | 1044 | case Opt_noacl: |
1098 | printk("EXT4 (no)acl options not supported\n"); | 1045 | printk(KERN_ERR "EXT4 (no)acl options " |
1046 | "not supported\n"); | ||
1099 | break; | 1047 | break; |
1100 | #endif | 1048 | #endif |
1101 | case Opt_reservation: | 1049 | case Opt_reservation: |
@@ -1178,6 +1126,12 @@ static int parse_options(char *options, struct super_block *sb, | |||
1178 | sbi->s_mount_opt |= data_opt; | 1126 | sbi->s_mount_opt |= data_opt; |
1179 | } | 1127 | } |
1180 | break; | 1128 | break; |
1129 | case Opt_data_err_abort: | ||
1130 | set_opt(sbi->s_mount_opt, DATA_ERR_ABORT); | ||
1131 | break; | ||
1132 | case Opt_data_err_ignore: | ||
1133 | clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); | ||
1134 | break; | ||
1181 | #ifdef CONFIG_QUOTA | 1135 | #ifdef CONFIG_QUOTA |
1182 | case Opt_usrjquota: | 1136 | case Opt_usrjquota: |
1183 | qtype = USRQUOTA; | 1137 | qtype = USRQUOTA; |
@@ -1189,8 +1143,8 @@ set_qf_name: | |||
1189 | sb_any_quota_suspended(sb)) && | 1143 | sb_any_quota_suspended(sb)) && |
1190 | !sbi->s_qf_names[qtype]) { | 1144 | !sbi->s_qf_names[qtype]) { |
1191 | printk(KERN_ERR | 1145 | printk(KERN_ERR |
1192 | "EXT4-fs: Cannot change journaled " | 1146 | "EXT4-fs: Cannot change journaled " |
1193 | "quota options when quota turned on.\n"); | 1147 | "quota options when quota turned on.\n"); |
1194 | return 0; | 1148 | return 0; |
1195 | } | 1149 | } |
1196 | qname = match_strdup(&args[0]); | 1150 | qname = match_strdup(&args[0]); |
@@ -1357,12 +1311,6 @@ set_qf_format: | |||
1357 | case Opt_nodelalloc: | 1311 | case Opt_nodelalloc: |
1358 | clear_opt(sbi->s_mount_opt, DELALLOC); | 1312 | clear_opt(sbi->s_mount_opt, DELALLOC); |
1359 | break; | 1313 | break; |
1360 | case Opt_mballoc: | ||
1361 | set_opt(sbi->s_mount_opt, MBALLOC); | ||
1362 | break; | ||
1363 | case Opt_nomballoc: | ||
1364 | clear_opt(sbi->s_mount_opt, MBALLOC); | ||
1365 | break; | ||
1366 | case Opt_stripe: | 1314 | case Opt_stripe: |
1367 | if (match_int(&args[0], &option)) | 1315 | if (match_int(&args[0], &option)) |
1368 | return 0; | 1316 | return 0; |
@@ -1373,6 +1321,13 @@ set_qf_format: | |||
1373 | case Opt_delalloc: | 1321 | case Opt_delalloc: |
1374 | set_opt(sbi->s_mount_opt, DELALLOC); | 1322 | set_opt(sbi->s_mount_opt, DELALLOC); |
1375 | break; | 1323 | break; |
1324 | case Opt_inode_readahead_blks: | ||
1325 | if (match_int(&args[0], &option)) | ||
1326 | return 0; | ||
1327 | if (option < 0 || option > (1 << 30)) | ||
1328 | return 0; | ||
1329 | sbi->s_inode_readahead_blks = option; | ||
1330 | break; | ||
1376 | default: | 1331 | default: |
1377 | printk(KERN_ERR | 1332 | printk(KERN_ERR |
1378 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1333 | "EXT4-fs: Unrecognized mount option \"%s\" " |
@@ -1473,15 +1428,9 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, | |||
1473 | EXT4_INODES_PER_GROUP(sb), | 1428 | EXT4_INODES_PER_GROUP(sb), |
1474 | sbi->s_mount_opt); | 1429 | sbi->s_mount_opt); |
1475 | 1430 | ||
1476 | printk(KERN_INFO "EXT4 FS on %s, ", sb->s_id); | 1431 | printk(KERN_INFO "EXT4 FS on %s, %s journal on %s\n", |
1477 | if (EXT4_SB(sb)->s_journal->j_inode == NULL) { | 1432 | sb->s_id, EXT4_SB(sb)->s_journal->j_inode ? "internal" : |
1478 | char b[BDEVNAME_SIZE]; | 1433 | "external", EXT4_SB(sb)->s_journal->j_devname); |
1479 | |||
1480 | printk("external journal on %s\n", | ||
1481 | bdevname(EXT4_SB(sb)->s_journal->j_dev, b)); | ||
1482 | } else { | ||
1483 | printk("internal journal\n"); | ||
1484 | } | ||
1485 | return res; | 1434 | return res; |
1486 | } | 1435 | } |
1487 | 1436 | ||
@@ -1504,8 +1453,11 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1504 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; | 1453 | 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; | 1454 | groups_per_flex = 1 << sbi->s_log_groups_per_flex; |
1506 | 1455 | ||
1507 | flex_group_count = (sbi->s_groups_count + groups_per_flex - 1) / | 1456 | /* We allocate both existing and potentially added groups */ |
1508 | groups_per_flex; | 1457 | flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + |
1458 | ((sbi->s_es->s_reserved_gdt_blocks +1 ) << | ||
1459 | EXT4_DESC_PER_BLOCK_BITS(sb))) / | ||
1460 | groups_per_flex; | ||
1509 | sbi->s_flex_groups = kzalloc(flex_group_count * | 1461 | sbi->s_flex_groups = kzalloc(flex_group_count * |
1510 | sizeof(struct flex_groups), GFP_KERNEL); | 1462 | sizeof(struct flex_groups), GFP_KERNEL); |
1511 | if (sbi->s_flex_groups == NULL) { | 1463 | if (sbi->s_flex_groups == NULL) { |
@@ -1584,7 +1536,7 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1584 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) | 1536 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) |
1585 | flexbg_flag = 1; | 1537 | flexbg_flag = 1; |
1586 | 1538 | ||
1587 | ext4_debug ("Checking group descriptors"); | 1539 | ext4_debug("Checking group descriptors"); |
1588 | 1540 | ||
1589 | for (i = 0; i < sbi->s_groups_count; i++) { | 1541 | for (i = 0; i < sbi->s_groups_count; i++) { |
1590 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); | 1542 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); |
@@ -1599,14 +1551,14 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1599 | if (block_bitmap < first_block || block_bitmap > last_block) { | 1551 | if (block_bitmap < first_block || block_bitmap > last_block) { |
1600 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1552 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " |
1601 | "Block bitmap for group %lu not in group " | 1553 | "Block bitmap for group %lu not in group " |
1602 | "(block %llu)!", i, block_bitmap); | 1554 | "(block %llu)!\n", i, block_bitmap); |
1603 | return 0; | 1555 | return 0; |
1604 | } | 1556 | } |
1605 | inode_bitmap = ext4_inode_bitmap(sb, gdp); | 1557 | inode_bitmap = ext4_inode_bitmap(sb, gdp); |
1606 | if (inode_bitmap < first_block || inode_bitmap > last_block) { | 1558 | if (inode_bitmap < first_block || inode_bitmap > last_block) { |
1607 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1559 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " |
1608 | "Inode bitmap for group %lu not in group " | 1560 | "Inode bitmap for group %lu not in group " |
1609 | "(block %llu)!", i, inode_bitmap); | 1561 | "(block %llu)!\n", i, inode_bitmap); |
1610 | return 0; | 1562 | return 0; |
1611 | } | 1563 | } |
1612 | inode_table = ext4_inode_table(sb, gdp); | 1564 | inode_table = ext4_inode_table(sb, gdp); |
@@ -1614,7 +1566,7 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1614 | inode_table + sbi->s_itb_per_group - 1 > last_block) { | 1566 | inode_table + sbi->s_itb_per_group - 1 > last_block) { |
1615 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1567 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " |
1616 | "Inode table for group %lu not in group " | 1568 | "Inode table for group %lu not in group " |
1617 | "(block %llu)!", i, inode_table); | 1569 | "(block %llu)!\n", i, inode_table); |
1618 | return 0; | 1570 | return 0; |
1619 | } | 1571 | } |
1620 | spin_lock(sb_bgl_lock(sbi, i)); | 1572 | spin_lock(sb_bgl_lock(sbi, i)); |
@@ -1623,8 +1575,10 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1623 | "Checksum for group %lu failed (%u!=%u)\n", | 1575 | "Checksum for group %lu failed (%u!=%u)\n", |
1624 | i, le16_to_cpu(ext4_group_desc_csum(sbi, i, | 1576 | i, le16_to_cpu(ext4_group_desc_csum(sbi, i, |
1625 | gdp)), le16_to_cpu(gdp->bg_checksum)); | 1577 | gdp)), le16_to_cpu(gdp->bg_checksum)); |
1626 | if (!(sb->s_flags & MS_RDONLY)) | 1578 | if (!(sb->s_flags & MS_RDONLY)) { |
1579 | spin_unlock(sb_bgl_lock(sbi, i)); | ||
1627 | return 0; | 1580 | return 0; |
1581 | } | ||
1628 | } | 1582 | } |
1629 | spin_unlock(sb_bgl_lock(sbi, i)); | 1583 | spin_unlock(sb_bgl_lock(sbi, i)); |
1630 | if (!flexbg_flag) | 1584 | if (!flexbg_flag) |
@@ -1714,9 +1668,9 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1714 | DQUOT_INIT(inode); | 1668 | DQUOT_INIT(inode); |
1715 | if (inode->i_nlink) { | 1669 | if (inode->i_nlink) { |
1716 | printk(KERN_DEBUG | 1670 | printk(KERN_DEBUG |
1717 | "%s: truncating inode %lu to %Ld bytes\n", | 1671 | "%s: truncating inode %lu to %lld bytes\n", |
1718 | __func__, inode->i_ino, inode->i_size); | 1672 | __func__, inode->i_ino, inode->i_size); |
1719 | jbd_debug(2, "truncating inode %lu to %Ld bytes\n", | 1673 | jbd_debug(2, "truncating inode %lu to %lld bytes\n", |
1720 | inode->i_ino, inode->i_size); | 1674 | inode->i_ino, inode->i_size); |
1721 | ext4_truncate(inode); | 1675 | ext4_truncate(inode); |
1722 | nr_truncates++; | 1676 | nr_truncates++; |
@@ -1757,13 +1711,13 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1757 | * | 1711 | * |
1758 | * Note, this does *not* consider any metadata overhead for vfs i_blocks. | 1712 | * Note, this does *not* consider any metadata overhead for vfs i_blocks. |
1759 | */ | 1713 | */ |
1760 | static loff_t ext4_max_size(int blkbits) | 1714 | static loff_t ext4_max_size(int blkbits, int has_huge_files) |
1761 | { | 1715 | { |
1762 | loff_t res; | 1716 | loff_t res; |
1763 | loff_t upper_limit = MAX_LFS_FILESIZE; | 1717 | loff_t upper_limit = MAX_LFS_FILESIZE; |
1764 | 1718 | ||
1765 | /* small i_blocks in vfs inode? */ | 1719 | /* small i_blocks in vfs inode? */ |
1766 | if (sizeof(blkcnt_t) < sizeof(u64)) { | 1720 | if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { |
1767 | /* | 1721 | /* |
1768 | * CONFIG_LSF is not enabled implies the inode | 1722 | * CONFIG_LSF is not enabled implies the inode |
1769 | * i_block represent total blocks in 512 bytes | 1723 | * i_block represent total blocks in 512 bytes |
@@ -1793,7 +1747,7 @@ static loff_t ext4_max_size(int blkbits) | |||
1793 | * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks. | 1747 | * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks. |
1794 | * We need to be 1 filesystem block less than the 2^48 sector limit. | 1748 | * We need to be 1 filesystem block less than the 2^48 sector limit. |
1795 | */ | 1749 | */ |
1796 | static loff_t ext4_max_bitmap_size(int bits) | 1750 | static loff_t ext4_max_bitmap_size(int bits, int has_huge_files) |
1797 | { | 1751 | { |
1798 | loff_t res = EXT4_NDIR_BLOCKS; | 1752 | loff_t res = EXT4_NDIR_BLOCKS; |
1799 | int meta_blocks; | 1753 | int meta_blocks; |
@@ -1806,11 +1760,11 @@ static loff_t ext4_max_bitmap_size(int bits) | |||
1806 | * total number of 512 bytes blocks of the file | 1760 | * total number of 512 bytes blocks of the file |
1807 | */ | 1761 | */ |
1808 | 1762 | ||
1809 | if (sizeof(blkcnt_t) < sizeof(u64)) { | 1763 | if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { |
1810 | /* | 1764 | /* |
1811 | * CONFIG_LSF is not enabled implies the inode | 1765 | * !has_huge_files or CONFIG_LSF is not enabled |
1812 | * i_block represent total blocks in 512 bytes | 1766 | * implies the inode i_block represent total blocks in |
1813 | * 32 == size of vfs inode i_blocks * 8 | 1767 | * 512 bytes 32 == size of vfs inode i_blocks * 8 |
1814 | */ | 1768 | */ |
1815 | upper_limit = (1LL << 32) - 1; | 1769 | upper_limit = (1LL << 32) - 1; |
1816 | 1770 | ||
@@ -1914,11 +1868,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
1914 | unsigned long journal_devnum = 0; | 1868 | unsigned long journal_devnum = 0; |
1915 | unsigned long def_mount_opts; | 1869 | unsigned long def_mount_opts; |
1916 | struct inode *root; | 1870 | struct inode *root; |
1871 | char *cp; | ||
1917 | int ret = -EINVAL; | 1872 | int ret = -EINVAL; |
1918 | int blocksize; | 1873 | int blocksize; |
1919 | int db_count; | 1874 | int db_count; |
1920 | int i; | 1875 | int i; |
1921 | int needs_recovery; | 1876 | int needs_recovery, has_huge_files; |
1922 | __le32 features; | 1877 | __le32 features; |
1923 | __u64 blocks_count; | 1878 | __u64 blocks_count; |
1924 | int err; | 1879 | int err; |
@@ -1930,10 +1885,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
1930 | sbi->s_mount_opt = 0; | 1885 | sbi->s_mount_opt = 0; |
1931 | sbi->s_resuid = EXT4_DEF_RESUID; | 1886 | sbi->s_resuid = EXT4_DEF_RESUID; |
1932 | sbi->s_resgid = EXT4_DEF_RESGID; | 1887 | sbi->s_resgid = EXT4_DEF_RESGID; |
1888 | sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS; | ||
1933 | sbi->s_sb_block = sb_block; | 1889 | sbi->s_sb_block = sb_block; |
1934 | 1890 | ||
1935 | unlock_kernel(); | 1891 | unlock_kernel(); |
1936 | 1892 | ||
1893 | /* Cleanup superblock name */ | ||
1894 | for (cp = sb->s_id; (cp = strchr(cp, '/'));) | ||
1895 | *cp = '!'; | ||
1896 | |||
1937 | blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); | 1897 | blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); |
1938 | if (!blocksize) { | 1898 | if (!blocksize) { |
1939 | printk(KERN_ERR "EXT4-fs: unable to set blocksize\n"); | 1899 | printk(KERN_ERR "EXT4-fs: unable to set blocksize\n"); |
@@ -1973,11 +1933,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
1973 | set_opt(sbi->s_mount_opt, GRPID); | 1933 | set_opt(sbi->s_mount_opt, GRPID); |
1974 | if (def_mount_opts & EXT4_DEFM_UID16) | 1934 | if (def_mount_opts & EXT4_DEFM_UID16) |
1975 | set_opt(sbi->s_mount_opt, NO_UID32); | 1935 | set_opt(sbi->s_mount_opt, NO_UID32); |
1976 | #ifdef CONFIG_EXT4DEV_FS_XATTR | 1936 | #ifdef CONFIG_EXT4_FS_XATTR |
1977 | if (def_mount_opts & EXT4_DEFM_XATTR_USER) | 1937 | if (def_mount_opts & EXT4_DEFM_XATTR_USER) |
1978 | set_opt(sbi->s_mount_opt, XATTR_USER); | 1938 | set_opt(sbi->s_mount_opt, XATTR_USER); |
1979 | #endif | 1939 | #endif |
1980 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL | 1940 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
1981 | if (def_mount_opts & EXT4_DEFM_ACL) | 1941 | if (def_mount_opts & EXT4_DEFM_ACL) |
1982 | set_opt(sbi->s_mount_opt, POSIX_ACL); | 1942 | set_opt(sbi->s_mount_opt, POSIX_ACL); |
1983 | #endif | 1943 | #endif |
@@ -2012,11 +1972,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2012 | ext4_warning(sb, __func__, | 1972 | ext4_warning(sb, __func__, |
2013 | "extents feature not enabled on this filesystem, " | 1973 | "extents feature not enabled on this filesystem, " |
2014 | "use tune2fs.\n"); | 1974 | "use tune2fs.\n"); |
2015 | /* | ||
2016 | * turn on mballoc code by default in ext4 filesystem | ||
2017 | * Use -o nomballoc to turn it off | ||
2018 | */ | ||
2019 | set_opt(sbi->s_mount_opt, MBALLOC); | ||
2020 | 1975 | ||
2021 | /* | 1976 | /* |
2022 | * enable delayed allocation by default | 1977 | * enable delayed allocation by default |
@@ -2041,16 +1996,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2041 | "running e2fsck is recommended\n"); | 1996 | "running e2fsck is recommended\n"); |
2042 | 1997 | ||
2043 | /* | 1998 | /* |
2044 | * Since ext4 is still considered development code, we require | ||
2045 | * that the TEST_FILESYS flag in s->flags be set. | ||
2046 | */ | ||
2047 | if (!(le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS)) { | ||
2048 | printk(KERN_WARNING "EXT4-fs: %s: not marked " | ||
2049 | "OK to use with test code.\n", sb->s_id); | ||
2050 | goto failed_mount; | ||
2051 | } | ||
2052 | |||
2053 | /* | ||
2054 | * Check feature flags regardless of the revision level, since we | 1999 | * Check feature flags regardless of the revision level, since we |
2055 | * previously didn't change the revision level when setting the flags, | 2000 | * previously didn't change the revision level when setting the flags, |
2056 | * so there is a chance incompat flags are set on a rev 0 filesystem. | 2001 | * so there is a chance incompat flags are set on a rev 0 filesystem. |
@@ -2069,7 +2014,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2069 | sb->s_id, le32_to_cpu(features)); | 2014 | sb->s_id, le32_to_cpu(features)); |
2070 | goto failed_mount; | 2015 | goto failed_mount; |
2071 | } | 2016 | } |
2072 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) { | 2017 | has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb, |
2018 | EXT4_FEATURE_RO_COMPAT_HUGE_FILE); | ||
2019 | if (has_huge_files) { | ||
2073 | /* | 2020 | /* |
2074 | * Large file size enabled file system can only be | 2021 | * Large file size enabled file system can only be |
2075 | * mount if kernel is build with CONFIG_LSF | 2022 | * mount if kernel is build with CONFIG_LSF |
@@ -2119,8 +2066,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2119 | } | 2066 | } |
2120 | } | 2067 | } |
2121 | 2068 | ||
2122 | sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits); | 2069 | sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits, |
2123 | sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits); | 2070 | has_huge_files); |
2071 | sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files); | ||
2124 | 2072 | ||
2125 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { | 2073 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { |
2126 | sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE; | 2074 | sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE; |
@@ -2219,6 +2167,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2219 | goto failed_mount; | 2167 | goto failed_mount; |
2220 | } | 2168 | } |
2221 | 2169 | ||
2170 | #ifdef CONFIG_PROC_FS | ||
2171 | if (ext4_proc_root) | ||
2172 | sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); | ||
2173 | |||
2174 | if (sbi->s_proc) | ||
2175 | proc_create_data("inode_readahead_blks", 0644, sbi->s_proc, | ||
2176 | &ext4_ui_proc_fops, | ||
2177 | &sbi->s_inode_readahead_blks); | ||
2178 | #endif | ||
2179 | |||
2222 | bgl_lock_init(&sbi->s_blockgroup_lock); | 2180 | bgl_lock_init(&sbi->s_blockgroup_lock); |
2223 | 2181 | ||
2224 | for (i = 0; i < db_count; i++) { | 2182 | for (i = 0; i < db_count; i++) { |
@@ -2257,24 +2215,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2257 | err = percpu_counter_init(&sbi->s_dirs_counter, | 2215 | err = percpu_counter_init(&sbi->s_dirs_counter, |
2258 | ext4_count_dirs(sb)); | 2216 | ext4_count_dirs(sb)); |
2259 | } | 2217 | } |
2218 | if (!err) { | ||
2219 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | ||
2220 | } | ||
2260 | if (err) { | 2221 | if (err) { |
2261 | printk(KERN_ERR "EXT4-fs: insufficient memory\n"); | 2222 | printk(KERN_ERR "EXT4-fs: insufficient memory\n"); |
2262 | goto failed_mount3; | 2223 | goto failed_mount3; |
2263 | } | 2224 | } |
2264 | 2225 | ||
2265 | /* per fileystem reservation list head & lock */ | ||
2266 | spin_lock_init(&sbi->s_rsv_window_lock); | ||
2267 | sbi->s_rsv_window_root = RB_ROOT; | ||
2268 | /* Add a single, static dummy reservation to the start of the | ||
2269 | * reservation window list --- it gives us a placeholder for | ||
2270 | * append-at-start-of-list which makes the allocation logic | ||
2271 | * _much_ simpler. */ | ||
2272 | sbi->s_rsv_window_head.rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; | ||
2273 | sbi->s_rsv_window_head.rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; | ||
2274 | sbi->s_rsv_window_head.rsv_alloc_hit = 0; | ||
2275 | sbi->s_rsv_window_head.rsv_goal_size = 0; | ||
2276 | ext4_rsv_window_add(sb, &sbi->s_rsv_window_head); | ||
2277 | |||
2278 | sbi->s_stripe = ext4_get_stripe_size(sbi); | 2226 | sbi->s_stripe = ext4_get_stripe_size(sbi); |
2279 | 2227 | ||
2280 | /* | 2228 | /* |
@@ -2444,6 +2392,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2444 | "available.\n"); | 2392 | "available.\n"); |
2445 | } | 2393 | } |
2446 | 2394 | ||
2395 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
2396 | printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " | ||
2397 | "requested data journaling mode\n"); | ||
2398 | clear_opt(sbi->s_mount_opt, DELALLOC); | ||
2399 | } else if (test_opt(sb, DELALLOC)) | ||
2400 | printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); | ||
2401 | |||
2402 | ext4_ext_init(sb); | ||
2403 | err = ext4_mb_init(sb, needs_recovery); | ||
2404 | if (err) { | ||
2405 | printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n", | ||
2406 | err); | ||
2407 | goto failed_mount4; | ||
2408 | } | ||
2409 | |||
2447 | /* | 2410 | /* |
2448 | * akpm: core read_super() calls in here with the superblock locked. | 2411 | * akpm: core read_super() calls in here with the superblock locked. |
2449 | * That deadlocks, because orphan cleanup needs to lock the superblock | 2412 | * That deadlocks, because orphan cleanup needs to lock the superblock |
@@ -2463,16 +2426,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2463 | test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": | 2426 | test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": |
2464 | "writeback"); | 2427 | "writeback"); |
2465 | 2428 | ||
2466 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
2467 | printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " | ||
2468 | "requested data journaling mode\n"); | ||
2469 | clear_opt(sbi->s_mount_opt, DELALLOC); | ||
2470 | } else if (test_opt(sb, DELALLOC)) | ||
2471 | printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); | ||
2472 | |||
2473 | ext4_ext_init(sb); | ||
2474 | ext4_mb_init(sb, needs_recovery); | ||
2475 | |||
2476 | lock_kernel(); | 2429 | lock_kernel(); |
2477 | return 0; | 2430 | return 0; |
2478 | 2431 | ||
@@ -2489,11 +2442,16 @@ failed_mount3: | |||
2489 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 2442 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
2490 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 2443 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
2491 | percpu_counter_destroy(&sbi->s_dirs_counter); | 2444 | percpu_counter_destroy(&sbi->s_dirs_counter); |
2445 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
2492 | failed_mount2: | 2446 | failed_mount2: |
2493 | for (i = 0; i < db_count; i++) | 2447 | for (i = 0; i < db_count; i++) |
2494 | brelse(sbi->s_group_desc[i]); | 2448 | brelse(sbi->s_group_desc[i]); |
2495 | kfree(sbi->s_group_desc); | 2449 | kfree(sbi->s_group_desc); |
2496 | failed_mount: | 2450 | failed_mount: |
2451 | if (sbi->s_proc) { | ||
2452 | remove_proc_entry("inode_readahead_blks", sbi->s_proc); | ||
2453 | remove_proc_entry(sb->s_id, ext4_proc_root); | ||
2454 | } | ||
2497 | #ifdef CONFIG_QUOTA | 2455 | #ifdef CONFIG_QUOTA |
2498 | for (i = 0; i < MAXQUOTAS; i++) | 2456 | for (i = 0; i < MAXQUOTAS; i++) |
2499 | kfree(sbi->s_qf_names[i]); | 2457 | kfree(sbi->s_qf_names[i]); |
@@ -2527,6 +2485,10 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal) | |||
2527 | journal->j_flags |= JBD2_BARRIER; | 2485 | journal->j_flags |= JBD2_BARRIER; |
2528 | else | 2486 | else |
2529 | journal->j_flags &= ~JBD2_BARRIER; | 2487 | journal->j_flags &= ~JBD2_BARRIER; |
2488 | if (test_opt(sb, DATA_ERR_ABORT)) | ||
2489 | journal->j_flags |= JBD2_ABORT_ON_SYNCDATA_ERR; | ||
2490 | else | ||
2491 | journal->j_flags &= ~JBD2_ABORT_ON_SYNCDATA_ERR; | ||
2530 | spin_unlock(&journal->j_state_lock); | 2492 | spin_unlock(&journal->j_state_lock); |
2531 | } | 2493 | } |
2532 | 2494 | ||
@@ -2552,7 +2514,7 @@ static journal_t *ext4_get_journal(struct super_block *sb, | |||
2552 | return NULL; | 2514 | return NULL; |
2553 | } | 2515 | } |
2554 | 2516 | ||
2555 | jbd_debug(2, "Journal inode found at %p: %Ld bytes\n", | 2517 | jbd_debug(2, "Journal inode found at %p: %lld bytes\n", |
2556 | journal_inode, journal_inode->i_size); | 2518 | journal_inode, journal_inode->i_size); |
2557 | if (!S_ISREG(journal_inode->i_mode)) { | 2519 | if (!S_ISREG(journal_inode->i_mode)) { |
2558 | printk(KERN_ERR "EXT4-fs: invalid journal inode.\n"); | 2520 | printk(KERN_ERR "EXT4-fs: invalid journal inode.\n"); |
@@ -2715,6 +2677,11 @@ static int ext4_load_journal(struct super_block *sb, | |||
2715 | return -EINVAL; | 2677 | return -EINVAL; |
2716 | } | 2678 | } |
2717 | 2679 | ||
2680 | if (journal->j_flags & JBD2_BARRIER) | ||
2681 | printk(KERN_INFO "EXT4-fs: barriers enabled\n"); | ||
2682 | else | ||
2683 | printk(KERN_INFO "EXT4-fs: barriers disabled\n"); | ||
2684 | |||
2718 | if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { | 2685 | if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { |
2719 | err = jbd2_journal_update_format(journal); | 2686 | err = jbd2_journal_update_format(journal); |
2720 | if (err) { | 2687 | if (err) { |
@@ -2799,13 +2766,34 @@ static void ext4_commit_super(struct super_block *sb, | |||
2799 | 2766 | ||
2800 | if (!sbh) | 2767 | if (!sbh) |
2801 | return; | 2768 | return; |
2769 | if (buffer_write_io_error(sbh)) { | ||
2770 | /* | ||
2771 | * Oh, dear. A previous attempt to write the | ||
2772 | * superblock failed. This could happen because the | ||
2773 | * USB device was yanked out. Or it could happen to | ||
2774 | * be a transient write error and maybe the block will | ||
2775 | * be remapped. Nothing we can do but to retry the | ||
2776 | * write and hope for the best. | ||
2777 | */ | ||
2778 | printk(KERN_ERR "ext4: previous I/O error to " | ||
2779 | "superblock detected for %s.\n", sb->s_id); | ||
2780 | clear_buffer_write_io_error(sbh); | ||
2781 | set_buffer_uptodate(sbh); | ||
2782 | } | ||
2802 | es->s_wtime = cpu_to_le32(get_seconds()); | 2783 | es->s_wtime = cpu_to_le32(get_seconds()); |
2803 | ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb)); | 2784 | ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb)); |
2804 | es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); | 2785 | es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); |
2805 | BUFFER_TRACE(sbh, "marking dirty"); | 2786 | BUFFER_TRACE(sbh, "marking dirty"); |
2806 | mark_buffer_dirty(sbh); | 2787 | mark_buffer_dirty(sbh); |
2807 | if (sync) | 2788 | if (sync) { |
2808 | sync_dirty_buffer(sbh); | 2789 | sync_dirty_buffer(sbh); |
2790 | if (buffer_write_io_error(sbh)) { | ||
2791 | printk(KERN_ERR "ext4: I/O error while writing " | ||
2792 | "superblock for %s.\n", sb->s_id); | ||
2793 | clear_buffer_write_io_error(sbh); | ||
2794 | set_buffer_uptodate(sbh); | ||
2795 | } | ||
2796 | } | ||
2809 | } | 2797 | } |
2810 | 2798 | ||
2811 | 2799 | ||
@@ -2820,7 +2808,9 @@ static void ext4_mark_recovery_complete(struct super_block *sb, | |||
2820 | journal_t *journal = EXT4_SB(sb)->s_journal; | 2808 | journal_t *journal = EXT4_SB(sb)->s_journal; |
2821 | 2809 | ||
2822 | jbd2_journal_lock_updates(journal); | 2810 | jbd2_journal_lock_updates(journal); |
2823 | jbd2_journal_flush(journal); | 2811 | if (jbd2_journal_flush(journal) < 0) |
2812 | goto out; | ||
2813 | |||
2824 | lock_super(sb); | 2814 | lock_super(sb); |
2825 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && | 2815 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && |
2826 | sb->s_flags & MS_RDONLY) { | 2816 | sb->s_flags & MS_RDONLY) { |
@@ -2829,6 +2819,8 @@ static void ext4_mark_recovery_complete(struct super_block *sb, | |||
2829 | ext4_commit_super(sb, es, 1); | 2819 | ext4_commit_super(sb, es, 1); |
2830 | } | 2820 | } |
2831 | unlock_super(sb); | 2821 | unlock_super(sb); |
2822 | |||
2823 | out: | ||
2832 | jbd2_journal_unlock_updates(journal); | 2824 | jbd2_journal_unlock_updates(journal); |
2833 | } | 2825 | } |
2834 | 2826 | ||
@@ -2907,6 +2899,7 @@ static int ext4_sync_fs(struct super_block *sb, int wait) | |||
2907 | { | 2899 | { |
2908 | tid_t target; | 2900 | tid_t target; |
2909 | 2901 | ||
2902 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); | ||
2910 | sb->s_dirt = 0; | 2903 | sb->s_dirt = 0; |
2911 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { | 2904 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { |
2912 | if (wait) | 2905 | if (wait) |
@@ -2928,7 +2921,13 @@ static void ext4_write_super_lockfs(struct super_block *sb) | |||
2928 | 2921 | ||
2929 | /* Now we set up the journal barrier. */ | 2922 | /* Now we set up the journal barrier. */ |
2930 | jbd2_journal_lock_updates(journal); | 2923 | jbd2_journal_lock_updates(journal); |
2931 | jbd2_journal_flush(journal); | 2924 | |
2925 | /* | ||
2926 | * We don't want to clear needs_recovery flag when we failed | ||
2927 | * to flush the journal. | ||
2928 | */ | ||
2929 | if (jbd2_journal_flush(journal) < 0) | ||
2930 | return; | ||
2932 | 2931 | ||
2933 | /* Journal blocked and flushed, clear needs_recovery flag. */ | 2932 | /* Journal blocked and flushed, clear needs_recovery flag. */ |
2934 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 2933 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
@@ -3162,7 +3161,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3162 | buf->f_type = EXT4_SUPER_MAGIC; | 3161 | buf->f_type = EXT4_SUPER_MAGIC; |
3163 | buf->f_bsize = sb->s_blocksize; | 3162 | buf->f_bsize = sb->s_blocksize; |
3164 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; | 3163 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
3165 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter); | 3164 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - |
3165 | percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); | ||
3166 | ext4_free_blocks_count_set(es, buf->f_bfree); | 3166 | ext4_free_blocks_count_set(es, buf->f_bfree); |
3167 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); | 3167 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
3168 | if (buf->f_bfree < ext4_r_blocks_count(es)) | 3168 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
@@ -3367,8 +3367,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
3367 | * otherwise be livelocked... | 3367 | * otherwise be livelocked... |
3368 | */ | 3368 | */ |
3369 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 3369 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
3370 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 3370 | err = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
3371 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 3371 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
3372 | if (err) { | ||
3373 | path_put(&nd.path); | ||
3374 | return err; | ||
3375 | } | ||
3372 | } | 3376 | } |
3373 | 3377 | ||
3374 | err = vfs_quota_on_path(sb, type, format_id, &nd.path); | 3378 | err = vfs_quota_on_path(sb, type, format_id, &nd.path); |
@@ -3432,7 +3436,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3432 | handle_t *handle = journal_current_handle(); | 3436 | handle_t *handle = journal_current_handle(); |
3433 | 3437 | ||
3434 | if (!handle) { | 3438 | if (!handle) { |
3435 | printk(KERN_WARNING "EXT4-fs: Quota write (off=%Lu, len=%Lu)" | 3439 | printk(KERN_WARNING "EXT4-fs: Quota write (off=%llu, len=%llu)" |
3436 | " cancelled because transaction is not started.\n", | 3440 | " cancelled because transaction is not started.\n", |
3437 | (unsigned long long)off, (unsigned long long)len); | 3441 | (unsigned long long)off, (unsigned long long)len); |
3438 | return -EIO; | 3442 | return -EIO; |
@@ -3493,18 +3497,82 @@ static int ext4_get_sb(struct file_system_type *fs_type, | |||
3493 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt); | 3497 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt); |
3494 | } | 3498 | } |
3495 | 3499 | ||
3500 | #ifdef CONFIG_PROC_FS | ||
3501 | static int ext4_ui_proc_show(struct seq_file *m, void *v) | ||
3502 | { | ||
3503 | unsigned int *p = m->private; | ||
3504 | |||
3505 | seq_printf(m, "%u\n", *p); | ||
3506 | return 0; | ||
3507 | } | ||
3508 | |||
3509 | static int ext4_ui_proc_open(struct inode *inode, struct file *file) | ||
3510 | { | ||
3511 | return single_open(file, ext4_ui_proc_show, PDE(inode)->data); | ||
3512 | } | ||
3513 | |||
3514 | static ssize_t ext4_ui_proc_write(struct file *file, const char __user *buf, | ||
3515 | size_t cnt, loff_t *ppos) | ||
3516 | { | ||
3517 | unsigned int *p = PDE(file->f_path.dentry->d_inode)->data; | ||
3518 | char str[32]; | ||
3519 | unsigned long value; | ||
3520 | |||
3521 | if (cnt >= sizeof(str)) | ||
3522 | return -EINVAL; | ||
3523 | if (copy_from_user(str, buf, cnt)) | ||
3524 | return -EFAULT; | ||
3525 | value = simple_strtol(str, NULL, 0); | ||
3526 | if (value < 0) | ||
3527 | return -ERANGE; | ||
3528 | *p = value; | ||
3529 | return cnt; | ||
3530 | } | ||
3531 | |||
3532 | const struct file_operations ext4_ui_proc_fops = { | ||
3533 | .owner = THIS_MODULE, | ||
3534 | .open = ext4_ui_proc_open, | ||
3535 | .read = seq_read, | ||
3536 | .llseek = seq_lseek, | ||
3537 | .release = single_release, | ||
3538 | .write = ext4_ui_proc_write, | ||
3539 | }; | ||
3540 | #endif | ||
3541 | |||
3542 | static struct file_system_type ext4_fs_type = { | ||
3543 | .owner = THIS_MODULE, | ||
3544 | .name = "ext4", | ||
3545 | .get_sb = ext4_get_sb, | ||
3546 | .kill_sb = kill_block_super, | ||
3547 | .fs_flags = FS_REQUIRES_DEV, | ||
3548 | }; | ||
3549 | |||
3550 | #ifdef CONFIG_EXT4DEV_COMPAT | ||
3551 | static int ext4dev_get_sb(struct file_system_type *fs_type, | ||
3552 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | ||
3553 | { | ||
3554 | printk(KERN_WARNING "EXT4-fs: Update your userspace programs " | ||
3555 | "to mount using ext4\n"); | ||
3556 | printk(KERN_WARNING "EXT4-fs: ext4dev backwards compatibility " | ||
3557 | "will go away by 2.6.31\n"); | ||
3558 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt); | ||
3559 | } | ||
3560 | |||
3496 | static struct file_system_type ext4dev_fs_type = { | 3561 | static struct file_system_type ext4dev_fs_type = { |
3497 | .owner = THIS_MODULE, | 3562 | .owner = THIS_MODULE, |
3498 | .name = "ext4dev", | 3563 | .name = "ext4dev", |
3499 | .get_sb = ext4_get_sb, | 3564 | .get_sb = ext4dev_get_sb, |
3500 | .kill_sb = kill_block_super, | 3565 | .kill_sb = kill_block_super, |
3501 | .fs_flags = FS_REQUIRES_DEV, | 3566 | .fs_flags = FS_REQUIRES_DEV, |
3502 | }; | 3567 | }; |
3568 | MODULE_ALIAS("ext4dev"); | ||
3569 | #endif | ||
3503 | 3570 | ||
3504 | static int __init init_ext4_fs(void) | 3571 | static int __init init_ext4_fs(void) |
3505 | { | 3572 | { |
3506 | int err; | 3573 | int err; |
3507 | 3574 | ||
3575 | ext4_proc_root = proc_mkdir("fs/ext4", NULL); | ||
3508 | err = init_ext4_mballoc(); | 3576 | err = init_ext4_mballoc(); |
3509 | if (err) | 3577 | if (err) |
3510 | return err; | 3578 | return err; |
@@ -3515,9 +3583,16 @@ static int __init init_ext4_fs(void) | |||
3515 | err = init_inodecache(); | 3583 | err = init_inodecache(); |
3516 | if (err) | 3584 | if (err) |
3517 | goto out1; | 3585 | goto out1; |
3518 | err = register_filesystem(&ext4dev_fs_type); | 3586 | err = register_filesystem(&ext4_fs_type); |
3519 | if (err) | 3587 | if (err) |
3520 | goto out; | 3588 | goto out; |
3589 | #ifdef CONFIG_EXT4DEV_COMPAT | ||
3590 | err = register_filesystem(&ext4dev_fs_type); | ||
3591 | if (err) { | ||
3592 | unregister_filesystem(&ext4_fs_type); | ||
3593 | goto out; | ||
3594 | } | ||
3595 | #endif | ||
3521 | return 0; | 3596 | return 0; |
3522 | out: | 3597 | out: |
3523 | destroy_inodecache(); | 3598 | destroy_inodecache(); |
@@ -3530,10 +3605,14 @@ out2: | |||
3530 | 3605 | ||
3531 | static void __exit exit_ext4_fs(void) | 3606 | static void __exit exit_ext4_fs(void) |
3532 | { | 3607 | { |
3608 | unregister_filesystem(&ext4_fs_type); | ||
3609 | #ifdef CONFIG_EXT4DEV_COMPAT | ||
3533 | unregister_filesystem(&ext4dev_fs_type); | 3610 | unregister_filesystem(&ext4dev_fs_type); |
3611 | #endif | ||
3534 | destroy_inodecache(); | 3612 | destroy_inodecache(); |
3535 | exit_ext4_xattr(); | 3613 | exit_ext4_xattr(); |
3536 | exit_ext4_mballoc(); | 3614 | exit_ext4_mballoc(); |
3615 | remove_proc_entry("fs/ext4", NULL); | ||
3537 | } | 3616 | } |
3538 | 3617 | ||
3539 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); | 3618 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); |