aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Qi <joseph.qi@huawei.com>2015-12-29 17:54:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-12-29 20:45:49 -0500
commit5c9ee4cbf2a945271f25b89b137f2c03bbc3be33 (patch)
tree19ba4dcdb5ec895f8f0a45d24481910376068d4c
parent8513342170278468bac126640a5d2d12ffbff106 (diff)
ocfs2: fix BUG when calculate new backup super
When resizing, it firstly extends the last gd. Once it should backup super in the gd, it calculates new backup super and update the corresponding value. But it currently doesn't consider the situation that the backup super is already done. And in this case, it still sets the bit in gd bitmap and then decrease from bg_free_bits_count, which leads to a corrupted gd and trigger the BUG in ocfs2_block_group_set_bits: BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits); So check whether the backup super is done and then do the updates. Signed-off-by: Joseph Qi <joseph.qi@huawei.com> Reviewed-by: Jiufei Xue <xuejiufei@huawei.com> Reviewed-by: Yiwen Jiang <jiangyiwen@huawei.com> Cc: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ocfs2/resize.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c
index d5da6f624142..79b8021302b3 100644
--- a/fs/ocfs2/resize.c
+++ b/fs/ocfs2/resize.c
@@ -54,11 +54,12 @@
54static u16 ocfs2_calc_new_backup_super(struct inode *inode, 54static u16 ocfs2_calc_new_backup_super(struct inode *inode,
55 struct ocfs2_group_desc *gd, 55 struct ocfs2_group_desc *gd,
56 u16 cl_cpg, 56 u16 cl_cpg,
57 u16 old_bg_clusters,
57 int set) 58 int set)
58{ 59{
59 int i; 60 int i;
60 u16 backups = 0; 61 u16 backups = 0;
61 u32 cluster; 62 u32 cluster, lgd_cluster;
62 u64 blkno, gd_blkno, lgd_blkno = le64_to_cpu(gd->bg_blkno); 63 u64 blkno, gd_blkno, lgd_blkno = le64_to_cpu(gd->bg_blkno);
63 64
64 for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) { 65 for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) {
@@ -71,6 +72,12 @@ static u16 ocfs2_calc_new_backup_super(struct inode *inode,
71 else if (gd_blkno > lgd_blkno) 72 else if (gd_blkno > lgd_blkno)
72 break; 73 break;
73 74
75 /* check if already done backup super */
76 lgd_cluster = ocfs2_blocks_to_clusters(inode->i_sb, lgd_blkno);
77 lgd_cluster += old_bg_clusters;
78 if (lgd_cluster >= cluster)
79 continue;
80
74 if (set) 81 if (set)
75 ocfs2_set_bit(cluster % cl_cpg, 82 ocfs2_set_bit(cluster % cl_cpg,
76 (unsigned long *)gd->bg_bitmap); 83 (unsigned long *)gd->bg_bitmap);
@@ -99,6 +106,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle,
99 u16 chain, num_bits, backups = 0; 106 u16 chain, num_bits, backups = 0;
100 u16 cl_bpc = le16_to_cpu(cl->cl_bpc); 107 u16 cl_bpc = le16_to_cpu(cl->cl_bpc);
101 u16 cl_cpg = le16_to_cpu(cl->cl_cpg); 108 u16 cl_cpg = le16_to_cpu(cl->cl_cpg);
109 u16 old_bg_clusters;
102 110
103 trace_ocfs2_update_last_group_and_inode(new_clusters, 111 trace_ocfs2_update_last_group_and_inode(new_clusters,
104 first_new_cluster); 112 first_new_cluster);
@@ -112,6 +120,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle,
112 120
113 group = (struct ocfs2_group_desc *)group_bh->b_data; 121 group = (struct ocfs2_group_desc *)group_bh->b_data;
114 122
123 old_bg_clusters = le16_to_cpu(group->bg_bits) / cl_bpc;
115 /* update the group first. */ 124 /* update the group first. */
116 num_bits = new_clusters * cl_bpc; 125 num_bits = new_clusters * cl_bpc;
117 le16_add_cpu(&group->bg_bits, num_bits); 126 le16_add_cpu(&group->bg_bits, num_bits);
@@ -125,7 +134,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle,
125 OCFS2_FEATURE_COMPAT_BACKUP_SB)) { 134 OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
126 backups = ocfs2_calc_new_backup_super(bm_inode, 135 backups = ocfs2_calc_new_backup_super(bm_inode,
127 group, 136 group,
128 cl_cpg, 1); 137 cl_cpg, old_bg_clusters, 1);
129 le16_add_cpu(&group->bg_free_bits_count, -1 * backups); 138 le16_add_cpu(&group->bg_free_bits_count, -1 * backups);
130 } 139 }
131 140
@@ -163,7 +172,7 @@ out_rollback:
163 if (ret < 0) { 172 if (ret < 0) {
164 ocfs2_calc_new_backup_super(bm_inode, 173 ocfs2_calc_new_backup_super(bm_inode,
165 group, 174 group,
166 cl_cpg, 0); 175 cl_cpg, old_bg_clusters, 0);
167 le16_add_cpu(&group->bg_free_bits_count, backups); 176 le16_add_cpu(&group->bg_free_bits_count, backups);
168 le16_add_cpu(&group->bg_bits, -1 * num_bits); 177 le16_add_cpu(&group->bg_bits, -1 * num_bits);
169 le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits); 178 le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits);