diff options
Diffstat (limited to 'fs/ext4/resize.c')
| -rw-r--r-- | fs/ext4/resize.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9ecb92f68543..f000fbe2cd93 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
| @@ -855,7 +855,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
| 855 | */ | 855 | */ |
| 856 | 856 | ||
| 857 | /* Update group descriptor block for new group */ | 857 | /* Update group descriptor block for new group */ |
| 858 | gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; | 858 | gdp = (struct ext4_group_desc *)((char *)primary->b_data + |
| 859 | gdb_off * EXT4_DESC_SIZE(sb)); | ||
| 859 | 860 | ||
| 860 | ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ | 861 | ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ |
| 861 | ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ | 862 | ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ |
| @@ -865,6 +866,15 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
| 865 | gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); | 866 | gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); |
| 866 | 867 | ||
| 867 | /* | 868 | /* |
| 869 | * We can allocate memory for mb_alloc based on the new group | ||
| 870 | * descriptor | ||
| 871 | */ | ||
| 872 | if (test_opt(sb, MBALLOC)) { | ||
| 873 | err = ext4_mb_add_more_groupinfo(sb, input->group, gdp); | ||
| 874 | if (err) | ||
| 875 | goto exit_journal; | ||
| 876 | } | ||
| 877 | /* | ||
| 868 | * Make the new blocks and inodes valid next. We do this before | 878 | * Make the new blocks and inodes valid next. We do this before |
| 869 | * increasing the group count so that once the group is enabled, | 879 | * increasing the group count so that once the group is enabled, |
| 870 | * all of its blocks and inodes are already valid. | 880 | * all of its blocks and inodes are already valid. |
| @@ -956,6 +966,8 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
| 956 | handle_t *handle; | 966 | handle_t *handle; |
| 957 | int err; | 967 | int err; |
| 958 | unsigned long freed_blocks; | 968 | unsigned long freed_blocks; |
| 969 | ext4_group_t group; | ||
| 970 | struct ext4_group_info *grp; | ||
| 959 | 971 | ||
| 960 | /* We don't need to worry about locking wrt other resizers just | 972 | /* We don't need to worry about locking wrt other resizers just |
| 961 | * yet: we're going to revalidate es->s_blocks_count after | 973 | * yet: we're going to revalidate es->s_blocks_count after |
| @@ -987,7 +999,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
| 987 | } | 999 | } |
| 988 | 1000 | ||
| 989 | /* Handle the remaining blocks in the last group only. */ | 1001 | /* Handle the remaining blocks in the last group only. */ |
| 990 | ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last); | 1002 | ext4_get_group_no_and_offset(sb, o_blocks_count, &group, &last); |
| 991 | 1003 | ||
| 992 | if (last == 0) { | 1004 | if (last == 0) { |
| 993 | ext4_warning(sb, __func__, | 1005 | ext4_warning(sb, __func__, |
| @@ -1059,6 +1071,45 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
| 1059 | o_blocks_count + add); | 1071 | o_blocks_count + add); |
| 1060 | if ((err = ext4_journal_stop(handle))) | 1072 | if ((err = ext4_journal_stop(handle))) |
| 1061 | goto exit_put; | 1073 | goto exit_put; |
| 1074 | |||
| 1075 | /* | ||
| 1076 | * Mark mballoc pages as not up to date so that they will be updated | ||
| 1077 | * next time they are loaded by ext4_mb_load_buddy. | ||
| 1078 | */ | ||
| 1079 | if (test_opt(sb, MBALLOC)) { | ||
| 1080 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 1081 | struct inode *inode = sbi->s_buddy_cache; | ||
| 1082 | int blocks_per_page; | ||
| 1083 | int block; | ||
| 1084 | int pnum; | ||
| 1085 | struct page *page; | ||
| 1086 | |||
| 1087 | /* Set buddy page as not up to date */ | ||
| 1088 | blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; | ||
| 1089 | block = group * 2; | ||
| 1090 | pnum = block / blocks_per_page; | ||
| 1091 | page = find_get_page(inode->i_mapping, pnum); | ||
| 1092 | if (page != NULL) { | ||
| 1093 | ClearPageUptodate(page); | ||
| 1094 | page_cache_release(page); | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | /* Set bitmap page as not up to date */ | ||
| 1098 | block++; | ||
| 1099 | pnum = block / blocks_per_page; | ||
| 1100 | page = find_get_page(inode->i_mapping, pnum); | ||
| 1101 | if (page != NULL) { | ||
| 1102 | ClearPageUptodate(page); | ||
| 1103 | page_cache_release(page); | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | /* Get the info on the last group */ | ||
| 1107 | grp = ext4_get_group_info(sb, group); | ||
| 1108 | |||
| 1109 | /* Update free blocks in group info */ | ||
| 1110 | ext4_mb_update_group_info(grp, add); | ||
| 1111 | } | ||
| 1112 | |||
| 1062 | if (test_opt(sb, DEBUG)) | 1113 | if (test_opt(sb, DEBUG)) |
| 1063 | printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", | 1114 | printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", |
| 1064 | ext4_blocks_count(es)); | 1115 | ext4_blocks_count(es)); |
