|
@@ -134,6 +134,61 @@ static int verify_group_input(struct super_block *sb,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * ext4_new_flex_group_data is used by 64bit-resize interface to add a flex
|
|
|
+ * group each time.
|
|
|
+ */
|
|
|
+struct ext4_new_flex_group_data {
|
|
|
+ struct ext4_new_group_data *groups; /* new_group_data for groups
|
|
|
+ in the flex group */
|
|
|
+ __u16 *bg_flags; /* block group flags of groups
|
|
|
+ in @groups */
|
|
|
+ ext4_group_t count; /* number of groups in @groups
|
|
|
+ */
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * alloc_flex_gd() allocates a ext4_new_flex_group_data with size of
|
|
|
+ * @flexbg_size.
|
|
|
+ *
|
|
|
+ * Returns NULL on failure otherwise address of the allocated structure.
|
|
|
+ */
|
|
|
+static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size)
|
|
|
+{
|
|
|
+ struct ext4_new_flex_group_data *flex_gd;
|
|
|
+
|
|
|
+ flex_gd = kmalloc(sizeof(*flex_gd), GFP_NOFS);
|
|
|
+ if (flex_gd == NULL)
|
|
|
+ goto out3;
|
|
|
+
|
|
|
+ flex_gd->count = flexbg_size;
|
|
|
+
|
|
|
+ flex_gd->groups = kmalloc(sizeof(struct ext4_new_group_data) *
|
|
|
+ flexbg_size, GFP_NOFS);
|
|
|
+ if (flex_gd->groups == NULL)
|
|
|
+ goto out2;
|
|
|
+
|
|
|
+ flex_gd->bg_flags = kmalloc(flexbg_size * sizeof(__u16), GFP_NOFS);
|
|
|
+ if (flex_gd->bg_flags == NULL)
|
|
|
+ goto out1;
|
|
|
+
|
|
|
+ return flex_gd;
|
|
|
+
|
|
|
+out1:
|
|
|
+ kfree(flex_gd->groups);
|
|
|
+out2:
|
|
|
+ kfree(flex_gd);
|
|
|
+out3:
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static void free_flex_gd(struct ext4_new_flex_group_data *flex_gd)
|
|
|
+{
|
|
|
+ kfree(flex_gd->bg_flags);
|
|
|
+ kfree(flex_gd->groups);
|
|
|
+ kfree(flex_gd);
|
|
|
+}
|
|
|
+
|
|
|
static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
|
|
|
ext4_fsblk_t blk)
|
|
|
{
|