aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/ialloc.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2013-04-19 13:38:14 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-04-19 13:38:14 -0400
commiteb9cc7e16b32c898a1d715733c590f115aa0a099 (patch)
tree0a8343dc815ce3480c2dbed7707126e15113de5d /fs/ext4/ialloc.c
parentfd03d8daf417fffbcb27fdb30d60f6c81ed813c8 (diff)
ext4: move quota initialization out of inode allocation transaction
Inode allocation transaction is pretty heavy (246 credits with quotas and extents before previous patch, still around 200 after it). This is mostly due to credits required for allocation of quota structures (credits there are heavily overestimated but it's difficult to make better estimates if we don't want to wire non-trivial assumptions about quota format into filesystem). So move quota initialization out of allocation transaction. That way transaction for quota structure allocation will be started only if we need to look up quota structure on disk (rare) and furthermore it will be started for each quota type separately, not for all of them at once. This reduces maximum transaction size to 34 is most cases and to 73 in the worst case. [ Modified by tytso to clean up the cleanup paths for error handling. Also use a separate call to ext4_std_error() for each failure so it is easier for someone who is debugging a problem in this function to determine which function call failed. ] Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r--fs/ext4/ialloc.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 4c358f711cef..18d36d85f5c9 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -666,6 +666,23 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
666 ei = EXT4_I(inode); 666 ei = EXT4_I(inode);
667 sbi = EXT4_SB(sb); 667 sbi = EXT4_SB(sb);
668 668
669 /*
670 * Initalize owners and quota early so that we don't have to account
671 * for quota initialization worst case in standard inode creating
672 * transaction
673 */
674 if (owner) {
675 inode->i_mode = mode;
676 i_uid_write(inode, owner[0]);
677 i_gid_write(inode, owner[1]);
678 } else if (test_opt(sb, GRPID)) {
679 inode->i_mode = mode;
680 inode->i_uid = current_fsuid();
681 inode->i_gid = dir->i_gid;
682 } else
683 inode_init_owner(inode, dir, mode);
684 dquot_initialize(inode);
685
669 if (!goal) 686 if (!goal)
670 goal = sbi->s_inode_goal; 687 goal = sbi->s_inode_goal;
671 688
@@ -697,7 +714,7 @@ got_group:
697 714
698 gdp = ext4_get_group_desc(sb, group, &group_desc_bh); 715 gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
699 if (!gdp) 716 if (!gdp)
700 goto fail; 717 goto out;
701 718
702 /* 719 /*
703 * Check free inodes count before loading bitmap. 720 * Check free inodes count before loading bitmap.
@@ -711,7 +728,7 @@ got_group:
711 brelse(inode_bitmap_bh); 728 brelse(inode_bitmap_bh);
712 inode_bitmap_bh = ext4_read_inode_bitmap(sb, group); 729 inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
713 if (!inode_bitmap_bh) 730 if (!inode_bitmap_bh)
714 goto fail; 731 goto out;
715 732
716repeat_in_this_group: 733repeat_in_this_group:
717 ino = ext4_find_next_zero_bit((unsigned long *) 734 ino = ext4_find_next_zero_bit((unsigned long *)
@@ -733,13 +750,16 @@ repeat_in_this_group:
733 handle_type, nblocks); 750 handle_type, nblocks);
734 if (IS_ERR(handle)) { 751 if (IS_ERR(handle)) {
735 err = PTR_ERR(handle); 752 err = PTR_ERR(handle);
736 goto fail; 753 ext4_std_error(sb, err);
754 goto out;
737 } 755 }
738 } 756 }
739 BUFFER_TRACE(inode_bitmap_bh, "get_write_access"); 757 BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
740 err = ext4_journal_get_write_access(handle, inode_bitmap_bh); 758 err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
741 if (err) 759 if (err) {
742 goto fail; 760 ext4_std_error(sb, err);
761 goto out;
762 }
743 ext4_lock_group(sb, group); 763 ext4_lock_group(sb, group);
744 ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data); 764 ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data);
745 ext4_unlock_group(sb, group); 765 ext4_unlock_group(sb, group);
@@ -755,8 +775,10 @@ repeat_in_this_group:
755got: 775got:
756 BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata"); 776 BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
757 err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh); 777 err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
758 if (err) 778 if (err) {
759 goto fail; 779 ext4_std_error(sb, err);
780 goto out;
781 }
760 782
761 /* We may have to initialize the block bitmap if it isn't already */ 783 /* We may have to initialize the block bitmap if it isn't already */
762 if (ext4_has_group_desc_csum(sb) && 784 if (ext4_has_group_desc_csum(sb) &&
@@ -768,7 +790,8 @@ got:
768 err = ext4_journal_get_write_access(handle, block_bitmap_bh); 790 err = ext4_journal_get_write_access(handle, block_bitmap_bh);
769 if (err) { 791 if (err) {
770 brelse(block_bitmap_bh); 792 brelse(block_bitmap_bh);
771 goto fail; 793 ext4_std_error(sb, err);
794 goto out;
772 } 795 }
773 796
774 BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap"); 797 BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap");
@@ -787,14 +810,18 @@ got:
787 ext4_unlock_group(sb, group); 810 ext4_unlock_group(sb, group);
788 brelse(block_bitmap_bh); 811 brelse(block_bitmap_bh);
789 812
790 if (err) 813 if (err) {
791 goto fail; 814 ext4_std_error(sb, err);
815 goto out;
816 }
792 } 817 }
793 818
794 BUFFER_TRACE(group_desc_bh, "get_write_access"); 819 BUFFER_TRACE(group_desc_bh, "get_write_access");
795 err = ext4_journal_get_write_access(handle, group_desc_bh); 820 err = ext4_journal_get_write_access(handle, group_desc_bh);
796 if (err) 821 if (err) {
797 goto fail; 822 ext4_std_error(sb, err);
823 goto out;
824 }
798 825
799 /* Update the relevant bg descriptor fields */ 826 /* Update the relevant bg descriptor fields */
800 if (ext4_has_group_desc_csum(sb)) { 827 if (ext4_has_group_desc_csum(sb)) {
@@ -840,8 +867,10 @@ got:
840 867
841 BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata"); 868 BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
842 err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh); 869 err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);
843 if (err) 870 if (err) {
844 goto fail; 871 ext4_std_error(sb, err);
872 goto out;
873 }
845 874
846 percpu_counter_dec(&sbi->s_freeinodes_counter); 875 percpu_counter_dec(&sbi->s_freeinodes_counter);
847 if (S_ISDIR(mode)) 876 if (S_ISDIR(mode))
@@ -851,16 +880,6 @@ got:
851 flex_group = ext4_flex_group(sbi, group); 880 flex_group = ext4_flex_group(sbi, group);
852 atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); 881 atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes);
853 } 882 }
854 if (owner) {
855 inode->i_mode = mode;
856 i_uid_write(inode, owner[0]);
857 i_gid_write(inode, owner[1]);
858 } else if (test_opt(sb, GRPID)) {
859 inode->i_mode = mode;
860 inode->i_uid = current_fsuid();
861 inode->i_gid = dir->i_gid;
862 } else
863 inode_init_owner(inode, dir, mode);
864 883
865 inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); 884 inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
866 /* This is the optimal IO size (for stat), not the fs block size */ 885 /* This is the optimal IO size (for stat), not the fs block size */
@@ -889,7 +908,9 @@ got:
889 * twice. 908 * twice.
890 */ 909 */
891 err = -EIO; 910 err = -EIO;
892 goto fail; 911 ext4_error(sb, "failed to insert inode %lu: doubly allocated?",
912 inode->i_ino);
913 goto out;
893 } 914 }
894 spin_lock(&sbi->s_next_gen_lock); 915 spin_lock(&sbi->s_next_gen_lock);
895 inode->i_generation = sbi->s_next_generation++; 916 inode->i_generation = sbi->s_next_generation++;
@@ -917,7 +938,6 @@ got:
917 ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); 938 ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
918 939
919 ret = inode; 940 ret = inode;
920 dquot_initialize(inode);
921 err = dquot_alloc_inode(inode); 941 err = dquot_alloc_inode(inode);
922 if (err) 942 if (err)
923 goto fail_drop; 943 goto fail_drop;
@@ -951,24 +971,17 @@ got:
951 971
952 ext4_debug("allocating inode %lu\n", inode->i_ino); 972 ext4_debug("allocating inode %lu\n", inode->i_ino);
953 trace_ext4_allocate_inode(inode, dir, mode); 973 trace_ext4_allocate_inode(inode, dir, mode);
954 goto really_out;
955fail:
956 ext4_std_error(sb, err);
957out:
958 iput(inode);
959 ret = ERR_PTR(err);
960really_out:
961 brelse(inode_bitmap_bh); 974 brelse(inode_bitmap_bh);
962 return ret; 975 return ret;
963 976
964fail_free_drop: 977fail_free_drop:
965 dquot_free_inode(inode); 978 dquot_free_inode(inode);
966
967fail_drop: 979fail_drop:
968 dquot_drop(inode);
969 inode->i_flags |= S_NOQUOTA;
970 clear_nlink(inode); 980 clear_nlink(inode);
971 unlock_new_inode(inode); 981 unlock_new_inode(inode);
982out:
983 dquot_drop(inode);
984 inode->i_flags |= S_NOQUOTA;
972 iput(inode); 985 iput(inode);
973 brelse(inode_bitmap_bh); 986 brelse(inode_bitmap_bh);
974 return ERR_PTR(err); 987 return ERR_PTR(err);