diff options
Diffstat (limited to 'fs/ext4/resize.c')
-rw-r--r-- | fs/ext4/resize.c | 49 |
1 files changed, 8 insertions, 41 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 526db73701b4..92034d2c8a73 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -748,6 +748,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
748 | struct inode *inode = NULL; | 748 | struct inode *inode = NULL; |
749 | handle_t *handle; | 749 | handle_t *handle; |
750 | int gdb_off, gdb_num; | 750 | int gdb_off, gdb_num; |
751 | int num_grp_locked = 0; | ||
751 | int err, err2; | 752 | int err, err2; |
752 | 753 | ||
753 | gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb); | 754 | gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb); |
@@ -788,6 +789,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
788 | } | 789 | } |
789 | } | 790 | } |
790 | 791 | ||
792 | |||
791 | if ((err = verify_group_input(sb, input))) | 793 | if ((err = verify_group_input(sb, input))) |
792 | goto exit_put; | 794 | goto exit_put; |
793 | 795 | ||
@@ -856,6 +858,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
856 | * using the new disk blocks. | 858 | * using the new disk blocks. |
857 | */ | 859 | */ |
858 | 860 | ||
861 | num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, input->group); | ||
859 | /* Update group descriptor block for new group */ | 862 | /* Update group descriptor block for new group */ |
860 | gdp = (struct ext4_group_desc *)((char *)primary->b_data + | 863 | gdp = (struct ext4_group_desc *)((char *)primary->b_data + |
861 | gdb_off * EXT4_DESC_SIZE(sb)); | 864 | gdb_off * EXT4_DESC_SIZE(sb)); |
@@ -872,9 +875,11 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
872 | * We can allocate memory for mb_alloc based on the new group | 875 | * We can allocate memory for mb_alloc based on the new group |
873 | * descriptor | 876 | * descriptor |
874 | */ | 877 | */ |
875 | err = ext4_mb_add_more_groupinfo(sb, input->group, gdp); | 878 | err = ext4_mb_add_groupinfo(sb, input->group, gdp); |
876 | if (err) | 879 | if (err) { |
880 | ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked); | ||
877 | goto exit_journal; | 881 | goto exit_journal; |
882 | } | ||
878 | 883 | ||
879 | /* | 884 | /* |
880 | * Make the new blocks and inodes valid next. We do this before | 885 | * Make the new blocks and inodes valid next. We do this before |
@@ -916,6 +921,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
916 | 921 | ||
917 | /* Update the global fs size fields */ | 922 | /* Update the global fs size fields */ |
918 | sbi->s_groups_count++; | 923 | sbi->s_groups_count++; |
924 | ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked); | ||
919 | 925 | ||
920 | ext4_handle_dirty_metadata(handle, NULL, primary); | 926 | ext4_handle_dirty_metadata(handle, NULL, primary); |
921 | 927 | ||
@@ -1082,45 +1088,6 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1082 | if ((err = ext4_journal_stop(handle))) | 1088 | if ((err = ext4_journal_stop(handle))) |
1083 | goto exit_put; | 1089 | goto exit_put; |
1084 | 1090 | ||
1085 | /* | ||
1086 | * Mark mballoc pages as not up to date so that they will be updated | ||
1087 | * next time they are loaded by ext4_mb_load_buddy. | ||
1088 | * | ||
1089 | * XXX Bad, Bad, BAD!!! We should not be overloading the | ||
1090 | * Uptodate flag, particularly on thte bitmap bh, as way of | ||
1091 | * hinting to ext4_mb_load_buddy() that it needs to be | ||
1092 | * overloaded. A user could take a LVM snapshot, then do an | ||
1093 | * on-line fsck, and clear the uptodate flag, and this would | ||
1094 | * not be a bug in userspace, but a bug in the kernel. FIXME!!! | ||
1095 | */ | ||
1096 | { | ||
1097 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1098 | struct inode *inode = sbi->s_buddy_cache; | ||
1099 | int blocks_per_page; | ||
1100 | int block; | ||
1101 | int pnum; | ||
1102 | struct page *page; | ||
1103 | |||
1104 | /* Set buddy page as not up to date */ | ||
1105 | blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; | ||
1106 | block = group * 2; | ||
1107 | pnum = block / blocks_per_page; | ||
1108 | page = find_get_page(inode->i_mapping, pnum); | ||
1109 | if (page != NULL) { | ||
1110 | ClearPageUptodate(page); | ||
1111 | page_cache_release(page); | ||
1112 | } | ||
1113 | |||
1114 | /* Set bitmap page as not up to date */ | ||
1115 | block++; | ||
1116 | pnum = block / blocks_per_page; | ||
1117 | page = find_get_page(inode->i_mapping, pnum); | ||
1118 | if (page != NULL) { | ||
1119 | ClearPageUptodate(page); | ||
1120 | page_cache_release(page); | ||
1121 | } | ||
1122 | } | ||
1123 | |||
1124 | if (test_opt(sb, DEBUG)) | 1091 | if (test_opt(sb, DEBUG)) |
1125 | printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", | 1092 | printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", |
1126 | ext4_blocks_count(es)); | 1093 | ext4_blocks_count(es)); |