-Index: linux-stage/fs/ext4/ext4_jbd2.h
+commit 18aadd47f88464928b5ce57791c2e8f9f2aaece0 (v3.3-rc2-7-g18aadd4)
+Author: Bobi Jam <bobijam@whamcloud.com>
+Date: Mon Feb 20 17:53:02 2012 -0500
+
+ext4: expand commit callback and use it for mballoc
+
+The per-commit callback was used by mballoc code to manage free space
+bitmaps after deleted blocks have been released. This patch expands
+it to support multiple different callbacks, to allow other things to
+be done after the commit has been completed.
+
+Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
+Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+
+Index: linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/ext4_jbd2.h
===================================================================
---- linux-stage.orig/fs/ext4/ext4_jbd2.h
-+++ linux-stage/fs/ext4/ext4_jbd2.h
-@@ -106,6 +106,80 @@
+--- linux-2.6.32-504.3.3.el6.x86_64.orig/fs/ext4/ext4_jbd2.h
++++ linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/ext4_jbd2.h
+@@ -104,6 +104,80 @@
#define EXT4_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_INIT_BLOCKS(sb))
#define EXT4_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_DEL_BLOCKS(sb))
int
ext4_mark_iloc_dirty(handle_t *handle,
struct inode *inode,
-Index: linux-stage/fs/ext4/mballoc.h
+Index: linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/mballoc.h
===================================================================
---- linux-stage.orig/fs/ext4/mballoc.h
-+++ linux-stage/fs/ext4/mballoc.h
+--- linux-2.6.32-504.3.3.el6.x86_64.orig/fs/ext4/mballoc.h
++++ linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/mballoc.h
@@ -96,23 +96,24 @@ extern u8 mb_enable_debug;
*/
#define MB_DEFAULT_GROUP_PREALLOC 512
};
struct ext4_prealloc_space {
-Index: linux-stage/fs/ext4/mballoc.c
+Index: linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/mballoc.c
===================================================================
---- linux-stage.orig/fs/ext4/mballoc.c
-+++ linux-stage/fs/ext4/mballoc.c
+--- linux-2.6.32-504.3.3.el6.x86_64.orig/fs/ext4/mballoc.c
++++ linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/mballoc.c
@@ -21,6 +21,7 @@
* mballoc.c contains the multiblocks allocation routines
*/
static inline void *mb_correct_addr_and_bit(int *bit, void *addr)
{
-@@ -2592,8 +2593,6 @@ int ext4_mb_init(struct super_block *sb,
+@@ -2581,8 +2582,6 @@ int ext4_mb_init(struct super_block *sb,
}
}
return 0;
}
-@@ -2693,58 +2692,54 @@ static inline int ext4_issue_discard(str
+@@ -2684,58 +2683,54 @@ static inline int ext4_issue_discard(str
* This function is called by the jbd2 layer once the commit has finished,
* so we know we can free the blocks that were released with that commit.
*/
int err, count = 0, count2 = 0;
- struct ext4_free_data *entry;
- struct list_head *l, *ltmp;
--
+
- list_for_each_safe(l, ltmp, &txn->t_private_list) {
- entry = list_entry(l, struct ext4_free_data, list);
-
-- mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
-- entry->count, entry->group, entry);
+ mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
+ entry->efd_count, entry->efd_group, entry);
-- if (test_opt(sb, DISCARD))
-- ext4_issue_discard(sb, entry->group,
-- entry->start_blk, entry->count);
+- mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
+- entry->count, entry->group, entry);
+ if (test_opt(sb, DISCARD))
+ ext4_issue_discard(sb, entry->efd_group,
+ entry->efd_start_blk, entry->efd_count);
++
++ err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b);
++ /* we expect to find existing buddy because it's pinned */
++ BUG_ON(err != 0);
++
++ db = e4b.bd_info;
++ /* there are blocks to put in buddy to make them really free */
++ count += entry->efd_count;
++ count2++;
++ ext4_lock_group(sb, entry->efd_group);
++ /* Take it out of per group rb tree */
++ rb_erase(&entry->efd_node, &(db->bb_free_root));
++ mb_free_blocks(NULL, &e4b, entry->efd_start_blk, entry->efd_count);
+- if (test_opt(sb, DISCARD))
+- ext4_issue_discard(sb, entry->group,
+- entry->start_blk, entry->count);
+-
- err = ext4_mb_load_buddy(sb, entry->group, &e4b);
- /* we expect to find existing buddy because it's pinned */
- BUG_ON(err != 0);
- /* Take it out of per group rb tree */
- rb_erase(&entry->node, &(db->bb_free_root));
- mb_free_blocks(NULL, &e4b, entry->start_blk, entry->count);
--
++ /*
++ * Clear the trimmed flag for the group so that the next
++ * ext4_trim_fs can trim it.
++ * If the volume is mounted with -o discard, online discard
++ * is supported and the free blocks will be trimmed online.
++ */
++ if (!test_opt(sb, DISCARD))
++ EXT4_MB_GRP_CLEAR_TRIMMED(db);
+
- /*
- * Clear the trimmed flag for the group so that the next
- * ext4_trim_fs can trim it.
- * If the volume is mounted with -o discard, online discard
- * is supported and the free blocks will be trimmed online.
-- */
++ if (!db->bb_free_root.rb_node) {
++ /* No more items in the per group rb tree
++ * balance refcounts from ext4_mb_free_metadata()
+ */
- if (!test_opt(sb, DISCARD))
- EXT4_MB_GRP_CLEAR_TRIMMED(db);
-
- ext4_unlock_group(sb, entry->group);
- kmem_cache_free(ext4_free_ext_cachep, entry);
- ext4_mb_release_desc(&e4b);
-+ err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b);
-+ /* we expect to find existing buddy because it's pinned */
-+ BUG_ON(err != 0);
-+
-+ db = e4b.bd_info;
-+ /* there are blocks to put in buddy to make them really free */
-+ count += entry->efd_count;
-+ count2++;
-+ ext4_lock_group(sb, entry->efd_group);
-+ /* Take it out of per group rb tree */
-+ rb_erase(&entry->efd_node, &(db->bb_free_root));
-+ mb_free_blocks(NULL, &e4b, entry->efd_start_blk, entry->efd_count);
-+
-+ /*
-+ * Clear the trimmed flag for the group so that the next
-+ * ext4_trim_fs can trim it.
-+ * If the volume is mounted with -o discard, online discard
-+ * is supported and the free blocks will be trimmed online.
-+ */
-+ if (!test_opt(sb, DISCARD))
-+ EXT4_MB_GRP_CLEAR_TRIMMED(db);
-+
-+ if (!db->bb_free_root.rb_node) {
-+ /* No more items in the per group rb tree
-+ * balance refcounts from ext4_mb_free_metadata()
-+ */
+ page_cache_release(e4b.bd_buddy_page);
+ page_cache_release(e4b.bd_bitmap_page);
}
mb_debug(1, "freed %u blocks in %u structures\n", count, count2);
}
-@@ -2794,22 +2789,22 @@ int __init init_ext4_mballoc(void)
+@@ -2787,22 +2782,22 @@ int __init init_ext4_mballoc(void)
kmem_cache_create("ext4_alloc_context",
sizeof(struct ext4_allocation_context),
0, SLAB_RECLAIM_ACCOUNT, NULL);
}
void exit_ext4_mballoc(void)
-@@ -2821,7 +2816,7 @@ void exit_ext4_mballoc(void)
+@@ -2814,7 +2809,7 @@ void exit_ext4_mballoc(void)
rcu_barrier();
kmem_cache_destroy(ext4_pspace_cachep);
kmem_cache_destroy(ext4_ac_cachep);
ext4_remove_debugfs_entry();
}
-@@ -3362,8 +3357,8 @@ static void ext4_mb_generate_from_freeli
+@@ -3355,8 +3350,8 @@ static void ext4_mb_generate_from_freeli
n = rb_first(&(grp->bb_free_root));
while (n) {
n = rb_next(n);
}
return;
-@@ -4623,11 +4618,11 @@ out3:
+@@ -4606,11 +4601,11 @@ out:
* AND the blocks are associated with the same group.
*/
static int can_merge(struct ext4_free_data *entry1,
return 1;
return 0;
}
-@@ -4640,7 +4635,6 @@ ext4_mb_free_metadata(handle_t *handle,
+@@ -4623,7 +4618,6 @@ ext4_mb_free_metadata(handle_t *handle,
struct ext4_free_data *entry;
struct ext4_group_info *db = e4b->bd_info;
struct super_block *sb = e4b->bd_sb;
struct rb_node **n = &db->bb_free_root.rb_node, *node;
struct rb_node *parent = NULL, *new_node;
-@@ -4648,8 +4642,8 @@ ext4_mb_free_metadata(handle_t *handle,
+@@ -4631,8 +4625,8 @@ ext4_mb_free_metadata(handle_t *handle,
BUG_ON(e4b->bd_bitmap_page == NULL);
BUG_ON(e4b->bd_buddy_page == NULL);
if (!*n) {
/* first free block exent. We need to
-@@ -4662,15 +4656,15 @@ ext4_mb_free_metadata(handle_t *handle,
+@@ -4645,15 +4639,15 @@ ext4_mb_free_metadata(handle_t *handle,
}
while (*n) {
parent = *n;
return 0;
}
}
-@@ -4681,34 +4675,29 @@ ext4_mb_free_metadata(handle_t *handle,
+@@ -4664,34 +4658,29 @@ ext4_mb_free_metadata(handle_t *handle,
/* Now try to see the extent can be merged to left and right */
node = rb_prev(new_node);
if (node) {
return 0;
}
-@@ -4836,11 +4825,11 @@ do_more:
+@@ -4825,11 +4814,11 @@ do_more:
* blocks being freed are metadata. these blocks shouldn't
* be used until this transaction is committed
*/
ext4_lock_group(sb, block_group);
mb_clear_bits(bitmap_bh->b_data, bit, count);
-Index: linux-stage/fs/ext4/super.c
+Index: linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/super.c
===================================================================
---- linux-stage.orig/fs/ext4/super.c
-+++ linux-stage/fs/ext4/super.c
-@@ -301,6 +301,23 @@ void ext4_journal_abort_handle(const cha
+--- linux-2.6.32-504.3.3.el6.x86_64.orig/fs/ext4/super.c
++++ linux-2.6.32-504.3.3.el6.x86_64/fs/ext4/super.c
+@@ -338,6 +338,23 @@ void ext4_journal_abort_handle(const cha
EXPORT_SYMBOL(ext4_journal_abort_handle);
/* Deal with the reporting of failure conditions on a filesystem such as
* inconsistencies detected or read IO failures.
*
-@@ -3040,6 +3057,8 @@ static int ext4_fill_super(struct super_
- }
- set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
+@@ -3500,6 +3517,8 @@ static int ext4_fill_super(struct super_
+ ext4_count_dirs(sb));
+ percpu_counter_set(&sbi->s_dirtyblocks_counter, 0);
+ sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
+
no_journal:
-
if (test_opt(sb, NOBH)) {
+ if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) {