diff options
author | Frederic Bohe <frederic.bohe@bull.net> | 2008-07-11 19:27:31 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-07-11 19:27:31 -0400 |
commit | 5f21b0e642d7bf6fe4434c9ba12bc9cb96b17cf7 (patch) | |
tree | 0f391fac5cc7fa93129bf8dd853598c6d2d65bb5 /fs/ext4/resize.c | |
parent | 953e622b601f58b7cc0f29fe644457fa40a18456 (diff) |
ext4: fix online resize with mballoc
Update group infos when updating a group's descriptor.
Add group infos when adding a group's descriptor.
Refresh cache pages used by mb_alloc when changes occur.
This will probably need modifications when META_BG resizing will be allowed.
Signed-off-by: Frederic Bohe <frederic.bohe@bull.net>
Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Diffstat (limited to 'fs/ext4/resize.c')
-rw-r--r-- | fs/ext4/resize.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9ff7b1c04239..f000fbe2cd93 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -866,6 +866,15 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
866 | gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); | 866 | gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); |
867 | 867 | ||
868 | /* | 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 | /* | ||
869 | * 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 |
870 | * increasing the group count so that once the group is enabled, | 879 | * increasing the group count so that once the group is enabled, |
871 | * all of its blocks and inodes are already valid. | 880 | * all of its blocks and inodes are already valid. |
@@ -957,6 +966,8 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
957 | handle_t *handle; | 966 | handle_t *handle; |
958 | int err; | 967 | int err; |
959 | unsigned long freed_blocks; | 968 | unsigned long freed_blocks; |
969 | ext4_group_t group; | ||
970 | struct ext4_group_info *grp; | ||
960 | 971 | ||
961 | /* 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 |
962 | * yet: we're going to revalidate es->s_blocks_count after | 973 | * yet: we're going to revalidate es->s_blocks_count after |
@@ -988,7 +999,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
988 | } | 999 | } |
989 | 1000 | ||
990 | /* Handle the remaining blocks in the last group only. */ | 1001 | /* Handle the remaining blocks in the last group only. */ |
991 | 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); |
992 | 1003 | ||
993 | if (last == 0) { | 1004 | if (last == 0) { |
994 | ext4_warning(sb, __func__, | 1005 | ext4_warning(sb, __func__, |
@@ -1060,6 +1071,45 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1060 | o_blocks_count + add); | 1071 | o_blocks_count + add); |
1061 | if ((err = ext4_journal_stop(handle))) | 1072 | if ((err = ext4_journal_stop(handle))) |
1062 | 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 | |||
1063 | if (test_opt(sb, DEBUG)) | 1113 | if (test_opt(sb, DEBUG)) |
1064 | printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", | 1114 | printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", |
1065 | ext4_blocks_count(es)); | 1115 | ext4_blocks_count(es)); |