ext4: Remove old legacy block allocator
authorTheodore Ts'o <tytso@mit.edu>
Fri, 10 Oct 2008 13:40:52 +0000 (09:40 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 10 Oct 2008 13:40:52 +0000 (09:40 -0400)
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
12 files changed:
fs/ext4/balloc.c
fs/ext4/ext4.h
fs/ext4/ext4_i.h
fs/ext4/ext4_sb.h
fs/ext4/extents.c
fs/ext4/file.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/ext4/resize.c
fs/ext4/super.c

index cca7fd5..59566c0 100644 (file)
@@ -83,6 +83,7 @@ static int ext4_group_used_meta_blocks(struct super_block *sb,
        }
        return used_blocks;
 }
+
 /* Initializes an uninitialized block bitmap if given, and returns the
  * number of blocks free in the group. */
 unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
@@ -345,303 +346,6 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
         */
        return bh;
 }
-/*
- * The reservation window structure operations
- * --------------------------------------------
- * Operations include:
- * dump, find, add, remove, is_empty, find_next_reservable_window, etc.
- *
- * We use a red-black tree to represent per-filesystem reservation
- * windows.
- *
- */
-
-/**
- * __rsv_window_dump() -- Dump the filesystem block allocation reservation map
- * @rb_root:           root of per-filesystem reservation rb tree
- * @verbose:           verbose mode
- * @fn:                        function which wishes to dump the reservation map
- *
- * If verbose is turned on, it will print the whole block reservation
- * windows(start, end).        Otherwise, it will only print out the "bad" windows,
- * those windows that overlap with their immediate neighbors.
- */
-#if 1
-static void __rsv_window_dump(struct rb_root *root, int verbose,
-                             const char *fn)
-{
-       struct rb_node *n;
-       struct ext4_reserve_window_node *rsv, *prev;
-       int bad;
-
-restart:
-       n = rb_first(root);
-       bad = 0;
-       prev = NULL;
-
-       printk(KERN_DEBUG "Block Allocation Reservation "
-              "Windows Map (%s):\n", fn);
-       while (n) {
-               rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node);
-               if (verbose)
-                       printk(KERN_DEBUG "reservation window 0x%p "
-                              "start:  %llu, end:  %llu\n",
-                              rsv, rsv->rsv_start, rsv->rsv_end);
-               if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) {
-                       printk(KERN_DEBUG "Bad reservation %p (start >= end)\n",
-                              rsv);
-                       bad = 1;
-               }
-               if (prev && prev->rsv_end >= rsv->rsv_start) {
-                       printk(KERN_DEBUG "Bad reservation %p "
-                              "(prev->end >= start)\n", rsv);
-                       bad = 1;
-               }
-               if (bad) {
-                       if (!verbose) {
-                               printk(KERN_DEBUG "Restarting reservation "
-                                      "walk in verbose mode\n");
-                               verbose = 1;
-                               goto restart;
-                       }
-               }
-               n = rb_next(n);
-               prev = rsv;
-       }
-       printk(KERN_DEBUG "Window map complete.\n");
-       BUG_ON(bad);
-}
-#define rsv_window_dump(root, verbose) \
-       __rsv_window_dump((root), (verbose), __func__)
-#else
-#define rsv_window_dump(root, verbose) do {} while (0)
-#endif
-
-/**
- * goal_in_my_reservation()
- * @rsv:               inode's reservation window
- * @grp_goal:          given goal block relative to the allocation block group
- * @group:             the current allocation block group
- * @sb:                        filesystem super block
- *
- * Test if the given goal block (group relative) is within the file's
- * own block reservation window range.
- *
- * If the reservation window is outside the goal allocation group, return 0;
- * grp_goal (given goal block) could be -1, which means no specific
- * goal block. In this case, always return 1.
- * If the goal block is within the reservation window, return 1;
- * otherwise, return 0;
- */
-static int
-goal_in_my_reservation(struct ext4_reserve_window *rsv, ext4_grpblk_t grp_goal,
-                       ext4_group_t group, struct super_block *sb)
-{
-       ext4_fsblk_t group_first_block, group_last_block;
-
-       group_first_block = ext4_group_first_block_no(sb, group);
-       group_last_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1);
-
-       if ((rsv->_rsv_start > group_last_block) ||
-           (rsv->_rsv_end < group_first_block))
-               return 0;
-       if ((grp_goal >= 0) && ((grp_goal + group_first_block < rsv->_rsv_start)
-               || (grp_goal + group_first_block > rsv->_rsv_end)))
-               return 0;
-       return 1;
-}
-
-/**
- * search_reserve_window()
- * @rb_root:           root of reservation tree
- * @goal:              target allocation block
- *
- * Find the reserved window which includes the goal, or the previous one
- * if the goal is not in any window.
- * Returns NULL if there are no windows or if all windows start after the goal.
- */
-static struct ext4_reserve_window_node *
-search_reserve_window(struct rb_root *root, ext4_fsblk_t goal)
-{
-       struct rb_node *n = root->rb_node;
-       struct ext4_reserve_window_node *rsv;
-
-       if (!n)
-               return NULL;
-
-       do {
-               rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node);
-
-               if (goal < rsv->rsv_start)
-                       n = n->rb_left;
-               else if (goal > rsv->rsv_end)
-                       n = n->rb_right;
-               else
-                       return rsv;
-       } while (n);
-       /*
-        * We've fallen off the end of the tree: the goal wasn't inside
-        * any particular node.  OK, the previous node must be to one
-        * side of the interval containing the goal.  If it's the RHS,
-        * we need to back up one.
-        */
-       if (rsv->rsv_start > goal) {
-               n = rb_prev(&rsv->rsv_node);
-               rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node);
-       }
-       return rsv;
-}
-
-/**
- * ext4_rsv_window_add() -- Insert a window to the block reservation rb tree.
- * @sb:                        super block
- * @rsv:               reservation window to add
- *
- * Must be called with rsv_lock hold.
- */
-void ext4_rsv_window_add(struct super_block *sb,
-                   struct ext4_reserve_window_node *rsv)
-{
-       struct rb_root *root = &EXT4_SB(sb)->s_rsv_window_root;
-       struct rb_node *node = &rsv->rsv_node;
-       ext4_fsblk_t start = rsv->rsv_start;
-
-       struct rb_node **p = &root->rb_node;
-       struct rb_node *parent = NULL;
-       struct ext4_reserve_window_node *this;
-
-       while (*p)
-       {
-               parent = *p;
-               this = rb_entry(parent, struct ext4_reserve_window_node, rsv_node);
-
-               if (start < this->rsv_start)
-                       p = &(*p)->rb_left;
-               else if (start > this->rsv_end)
-                       p = &(*p)->rb_right;
-               else {
-                       rsv_window_dump(root, 1);
-                       BUG();
-               }
-       }
-
-       rb_link_node(node, parent, p);
-       rb_insert_color(node, root);
-}
-
-/**
- * ext4_rsv_window_remove() -- unlink a window from the reservation rb tree
- * @sb:                        super block
- * @rsv:               reservation window to remove
- *
- * Mark the block reservation window as not allocated, and unlink it
- * from the filesystem reservation window rb tree. Must be called with
- * rsv_lock hold.
- */
-static void rsv_window_remove(struct super_block *sb,
-                             struct ext4_reserve_window_node *rsv)
-{
-       rsv->rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
-       rsv->rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
-       rsv->rsv_alloc_hit = 0;
-       rb_erase(&rsv->rsv_node, &EXT4_SB(sb)->s_rsv_window_root);
-}
-
-/*
- * rsv_is_empty() -- Check if the reservation window is allocated.
- * @rsv:               given reservation window to check
- *
- * returns 1 if the end block is EXT4_RESERVE_WINDOW_NOT_ALLOCATED.
- */
-static inline int rsv_is_empty(struct ext4_reserve_window *rsv)
-{
-       /* a valid reservation end block could not be 0 */
-       return rsv->_rsv_end == EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
-}
-
-/**
- * ext4_init_block_alloc_info()
- * @inode:             file inode structure
- *
- * Allocate and initialize the reservation window structure, and
- * link the window to the ext4 inode structure at last
- *
- * The reservation window structure is only dynamically allocated
- * and linked to ext4 inode the first time the open file
- * needs a new block. So, before every ext4_new_block(s) call, for
- * regular files, we should check whether the reservation window
- * structure exists or not. In the latter case, this function is called.
- * Fail to do so will result in block reservation being turned off for that
- * open file.
- *
- * This function is called from ext4_get_blocks_handle(), also called
- * when setting the reservation window size through ioctl before the file
- * is open for write (needs block allocation).
- *
- * Needs down_write(i_data_sem) protection prior to call this function.
- */
-void ext4_init_block_alloc_info(struct inode *inode)
-{
-       struct ext4_inode_info *ei = EXT4_I(inode);
-       struct ext4_block_alloc_info *block_i = ei->i_block_alloc_info;
-       struct super_block *sb = inode->i_sb;
-
-       block_i = kmalloc(sizeof(*block_i), GFP_NOFS);
-       if (block_i) {
-               struct ext4_reserve_window_node *rsv = &block_i->rsv_window_node;
-
-               rsv->rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
-               rsv->rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
-
-               /*
-                * if filesystem is mounted with NORESERVATION, the goal
-                * reservation window size is set to zero to indicate
-                * block reservation is off
-                */
-               if (!test_opt(sb, RESERVATION))
-                       rsv->rsv_goal_size = 0;
-               else
-                       rsv->rsv_goal_size = EXT4_DEFAULT_RESERVE_BLOCKS;
-               rsv->rsv_alloc_hit = 0;
-               block_i->last_alloc_logical_block = 0;
-               block_i->last_alloc_physical_block = 0;
-       }
-       ei->i_block_alloc_info = block_i;
-}
-
-/**
- * ext4_discard_reservation()
- * @inode:             inode
- *
- * Discard(free) block reservation window on last file close, or truncate
- * or at last iput().
- *
- * It is being called in three cases:
- *     ext4_release_file(): last writer close the file
- *     ext4_clear_inode(): last iput(), when nobody link to this file.
- *     ext4_truncate(): when the block indirect map is about to change.
- *
- */
-void ext4_discard_reservation(struct inode *inode)
-{
-       struct ext4_inode_info *ei = EXT4_I(inode);
-       struct ext4_block_alloc_info *block_i = ei->i_block_alloc_info;
-       struct ext4_reserve_window_node *rsv;
-       spinlock_t *rsv_lock = &EXT4_SB(inode->i_sb)->s_rsv_window_lock;
-
-       ext4_mb_discard_inode_preallocations(inode);
-
-       if (!block_i)
-               return;
-
-       rsv = &block_i->rsv_window_node;
-       if (!rsv_is_empty(&rsv->rsv_window)) {
-               spin_lock(rsv_lock);
-               if (!rsv_is_empty(&rsv->rsv_window))
-                       rsv_window_remove(inode->i_sb, rsv);
-               spin_unlock(rsv_lock);
-       }
-}
 
 /**
  * ext4_free_blocks_sb() -- Free given blocks and update quota
@@ -650,6 +354,13 @@ void ext4_discard_reservation(struct inode *inode)
  * @block:                     start physcial block to free
  * @count:                     number of blocks to free
  * @pdquot_freed_blocks:       pointer to quota
+ *
+ * XXX This function is only used by the on-line resizing code, which
+ * should probably be fixed up to call the mballoc variant.  There
+ * this needs to be cleaned up later; in fact, I'm not convinced this
+ * is 100% correct in the face of the mballoc code.  The online resizing
+ * code needs to be fixed up to more tightly (and correctly) interlock
+ * with the mballoc code.
  */
 void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
                         ext4_fsblk_t block, unsigned long count,
@@ -861,747 +572,13 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
 
        sb = inode->i_sb;
 
-       if (!test_opt(sb, MBALLOC) || !EXT4_SB(sb)->s_group_info)
-               ext4_free_blocks_sb(handle, sb, block, count,
-                                               &dquot_freed_blocks);
-       else
-               ext4_mb_free_blocks(handle, inode, block, count,
-                                               metadata, &dquot_freed_blocks);
+       ext4_mb_free_blocks(handle, inode, block, count,
+                           metadata, &dquot_freed_blocks);
        if (dquot_freed_blocks)
                DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
        return;
 }
 
-/**
- * ext4_test_allocatable()
- * @nr:                        given allocation block group
- * @bh:                        bufferhead contains the bitmap of the given block group
- *
- * For ext4 allocations, we must not reuse any blocks which are
- * allocated in the bitmap buffer's "last committed data" copy.  This
- * prevents deletes from freeing up the page for reuse until we have
- * committed the delete transaction.
- *
- * If we didn't do this, then deleting something and reallocating it as
- * data would allow the old block to be overwritten before the
- * transaction committed (because we force data to disk before commit).
- * This would lead to corruption if we crashed between overwriting the
- * data and committing the delete.
- *
- * @@@ We may want to make this allocation behaviour conditional on
- * data-writes at some point, and disable it for metadata allocations or
- * sync-data inodes.
- */
-static int ext4_test_allocatable(ext4_grpblk_t nr, struct buffer_head *bh)
-{
-       int ret;
-       struct journal_head *jh = bh2jh(bh);
-
-       if (ext4_test_bit(nr, bh->b_data))
-               return 0;
-
-       jbd_lock_bh_state(bh);
-       if (!jh->b_committed_data)
-               ret = 1;
-       else
-               ret = !ext4_test_bit(nr, jh->b_committed_data);
-       jbd_unlock_bh_state(bh);
-       return ret;
-}
-
-/**
- * bitmap_search_next_usable_block()
- * @start:             the starting block (group relative) of the search
- * @bh:                        bufferhead contains the block group bitmap
- * @maxblocks:         the ending block (group relative) of the reservation
- *
- * The bitmap search --- search forward alternately through the actual
- * bitmap on disk and the last-committed copy in journal, until we find a
- * bit free in both bitmaps.
- */
-static ext4_grpblk_t
-bitmap_search_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh,
-                                       ext4_grpblk_t maxblocks)
-{
-       ext4_grpblk_t next;
-       struct journal_head *jh = bh2jh(bh);
-
-       while (start < maxblocks) {
-               next = ext4_find_next_zero_bit(bh->b_data, maxblocks, start);
-               if (next >= maxblocks)
-                       return -1;
-               if (ext4_test_allocatable(next, bh))
-                       return next;
-               jbd_lock_bh_state(bh);
-               if (jh->b_committed_data)
-                       start = ext4_find_next_zero_bit(jh->b_committed_data,
-                                                       maxblocks, next);
-               jbd_unlock_bh_state(bh);
-       }
-       return -1;
-}
-
-/**
- * find_next_usable_block()
- * @start:             the starting block (group relative) to find next
- *                     allocatable block in bitmap.
- * @bh:                        bufferhead contains the block group bitmap
- * @maxblocks:         the ending block (group relative) for the search
- *
- * Find an allocatable block in a bitmap.  We honor both the bitmap and
- * its last-committed copy (if that exists), and perform the "most
- * appropriate allocation" algorithm of looking for a free block near
- * the initial goal; then for a free byte somewhere in the bitmap; then
- * for any free bit in the bitmap.
- */
-static ext4_grpblk_t
-find_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh,
-                       ext4_grpblk_t maxblocks)
-{
-       ext4_grpblk_t here, next;
-       char *p, *r;
-
-       if (start > 0) {
-               /*
-                * The goal was occupied; search forward for a free
-                * block within the next XX blocks.
-                *
-                * end_goal is more or less random, but it has to be
-                * less than EXT4_BLOCKS_PER_GROUP. Aligning up to the
-                * next 64-bit boundary is simple..
-                */
-               ext4_grpblk_t end_goal = (start + 63) & ~63;
-               if (end_goal > maxblocks)
-                       end_goal = maxblocks;
-               here = ext4_find_next_zero_bit(bh->b_data, end_goal, start);
-               if (here < end_goal && ext4_test_allocatable(here, bh))
-                       return here;
-               ext4_debug("Bit not found near goal\n");
-       }
-
-       here = start;
-       if (here < 0)
-               here = 0;
-
-       p = ((char *)bh->b_data) + (here >> 3);
-       r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3));
-       next = (r - ((char *)bh->b_data)) << 3;
-
-       if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh))
-               return next;
-
-       /*
-        * The bitmap search --- search forward alternately through the actual
-        * bitmap and the last-committed copy until we find a bit free in
-        * both
-        */
-       here = bitmap_search_next_usable_block(here, bh, maxblocks);
-       return here;
-}
-
-/**
- * claim_block()
- * @block:             the free block (group relative) to allocate
- * @bh:                        the bufferhead containts the block group bitmap
- *
- * We think we can allocate this block in this bitmap.  Try to set the bit.
- * If that succeeds then check that nobody has allocated and then freed the
- * block since we saw that is was not marked in b_committed_data.  If it _was_
- * allocated and freed then clear the bit in the bitmap again and return
- * zero (failure).
- */
-static inline int
-claim_block(spinlock_t *lock, ext4_grpblk_t block, struct buffer_head *bh)
-{
-       struct journal_head *jh = bh2jh(bh);
-       int ret;
-
-       if (ext4_set_bit_atomic(lock, block, bh->b_data))
-               return 0;
-       jbd_lock_bh_state(bh);
-       if (jh->b_committed_data && ext4_test_bit(block, jh->b_committed_data)) {
-               ext4_clear_bit_atomic(lock, block, bh->b_data);
-               ret = 0;
-       } else {
-               ret = 1;
-       }
-       jbd_unlock_bh_state(bh);
-       return ret;
-}
-
-/**
- * ext4_try_to_allocate()
- * @sb:                        superblock
- * @handle:            handle to this transaction
- * @group:             given allocation block group
- * @bitmap_bh:         bufferhead holds the block bitmap
- * @grp_goal:          given target block within the group
- * @count:             target number of blocks to allocate
- * @my_rsv:            reservation window
- *
- * Attempt to allocate blocks within a give range. Set the range of allocation
- * first, then find the first free bit(s) from the bitmap (within the range),
- * and at last, allocate the blocks by claiming the found free bit as allocated.
- *
- * To set the range of this allocation:
- *     if there is a reservation window, only try to allocate block(s) from the
- *     file's own reservation window;
- *     Otherwise, the allocation range starts from the give goal block, ends at
- *     the block group's last block.
- *
- * If we failed to allocate the desired block then we may end up crossing to a
- * new bitmap.  In that case we must release write access to the old one via
- * ext4_journal_release_buffer(), else we'll run out of credits.
- */
-static ext4_grpblk_t
-ext4_try_to_allocate(struct super_block *sb, handle_t *handle,
-                       ext4_group_t group, struct buffer_head *bitmap_bh,
-                       ext4_grpblk_t grp_goal, unsigned long *count,
-                       struct ext4_reserve_window *my_rsv)
-{
-       ext4_fsblk_t group_first_block;
-       ext4_grpblk_t start, end;
-       unsigned long num = 0;
-
-       /* we do allocation within the reservation window if we have a window */
-       if (my_rsv) {
-               group_first_block = ext4_group_first_block_no(sb, group);
-               if (my_rsv->_rsv_start >= group_first_block)
-                       start = my_rsv->_rsv_start - group_first_block;
-               else
-                       /* reservation window cross group boundary */
-                       start = 0;
-               end = my_rsv->_rsv_end - group_first_block + 1;
-               if (end > EXT4_BLOCKS_PER_GROUP(sb))
-                       /* reservation window crosses group boundary */
-                       end = EXT4_BLOCKS_PER_GROUP(sb);
-               if ((start <= grp_goal) && (grp_goal < end))
-                       start = grp_goal;
-               else
-                       grp_goal = -1;
-       } else {
-               if (grp_goal > 0)
-                       start = grp_goal;
-               else
-                       start = 0;
-               end = EXT4_BLOCKS_PER_GROUP(sb);
-       }
-
-       BUG_ON(start > EXT4_BLOCKS_PER_GROUP(sb));
-
-repeat:
-       if (grp_goal < 0 || !ext4_test_allocatable(grp_goal, bitmap_bh)) {
-               grp_goal = find_next_usable_block(start, bitmap_bh, end);
-               if (grp_goal < 0)
-                       goto fail_access;
-               if (!my_rsv) {
-                       int i;
-
-                       for (i = 0; i < 7 && grp_goal > start &&
-                                       ext4_test_allocatable(grp_goal - 1,
-                                                               bitmap_bh);
-                                       i++, grp_goal--)
-                               ;
-               }
-       }
-       start = grp_goal;
-
-       if (!claim_block(sb_bgl_lock(EXT4_SB(sb), group),
-               grp_goal, bitmap_bh)) {
-               /*
-                * The block was allocated by another thread, or it was
-                * allocated and then freed by another thread
-                */
-               start++;
-               grp_goal++;
-               if (start >= end)
-                       goto fail_access;
-               goto repeat;
-       }
-       num++;
-       grp_goal++;
-       while (num < *count && grp_goal < end
-               && ext4_test_allocatable(grp_goal, bitmap_bh)
-               && claim_block(sb_bgl_lock(EXT4_SB(sb), group),
-                               grp_goal, bitmap_bh)) {
-               num++;
-               grp_goal++;
-       }
-       *count = num;
-       return grp_goal - num;
-fail_access:
-       *count = num;
-       return -1;
-}
-
-/**
- *     find_next_reservable_window():
- *             find a reservable space within the given range.
- *             It does not allocate the reservation window for now:
- *             alloc_new_reservation() will do the work later.
- *
- *     @search_head: the head of the searching list;
- *             This is not necessarily the list head of the whole filesystem
- *
- *             We have both head and start_block to assist the search
- *             for the reservable space. The list starts from head,
- *             but we will shift to the place where start_block is,
- *             then start from there, when looking for a reservable space.
- *
- *     @size: the target new reservation window size
- *
- *     @group_first_block: the first block we consider to start
- *                     the real search from
- *
- *     @last_block:
- *             the maximum block number that our goal reservable space
- *             could start from. This is normally the last block in this
- *             group. The search will end when we found the start of next
- *             possible reservable space is out of this boundary.
- *             This could handle the cross boundary reservation window
- *             request.
- *
- *     basically we search from the given range, rather than the whole
- *     reservation double linked list, (start_block, last_block)
- *     to find a free region that is of my size and has not
- *     been reserved.
- *
- */
-static int find_next_reservable_window(
-                               struct ext4_reserve_window_node *search_head,
-                               struct ext4_reserve_window_node *my_rsv,
-                               struct super_block *sb,
-                               ext4_fsblk_t start_block,
-                               ext4_fsblk_t last_block)
-{
-       struct rb_node *next;
-       struct ext4_reserve_window_node *rsv, *prev;
-       ext4_fsblk_t cur;
-       int size = my_rsv->rsv_goal_size;
-
-       /* TODO: make the start of the reservation window byte-aligned */
-       /* cur = *start_block & ~7;*/
-       cur = start_block;
-       rsv = search_head;
-       if (!rsv)
-               return -1;
-
-       while (1) {
-               if (cur <= rsv->rsv_end)
-                       cur = rsv->rsv_end + 1;
-
-               /* TODO?
-                * in the case we could not find a reservable space
-                * that is what is expected, during the re-search, we could
-                * remember what's the largest reservable space we could have
-                * and return that one.
-                *
-                * For now it will fail if we could not find the reservable
-                * space with expected-size (or more)...
-                */
-               if (cur > last_block)
-                       return -1;              /* fail */
-
-               prev = rsv;
-               next = rb_next(&rsv->rsv_node);
-               rsv = rb_entry(next, struct ext4_reserve_window_node, rsv_node);
-
-               /*
-                * Reached the last reservation, we can just append to the
-                * previous one.
-                */
-               if (!next)
-                       break;
-
-               if (cur + size <= rsv->rsv_start) {
-                       /*
-                        * Found a reserveable space big enough.  We could
-                        * have a reservation across the group boundary here
-                        */
-                       break;
-               }
-       }
-       /*
-        * we come here either :
-        * when we reach the end of the whole list,
-        * and there is empty reservable space after last entry in the list.
-        * append it to the end of the list.
-        *
-        * or we found one reservable space in the middle of the list,
-        * return the reservation window that we could append to.
-        * succeed.
-        */
-
-       if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window)))
-               rsv_window_remove(sb, my_rsv);
-
-       /*
-        * Let's book the whole avaliable window for now.  We will check the
-        * disk bitmap later and then, if there are free blocks then we adjust
-        * the window size if it's larger than requested.
-        * Otherwise, we will remove this node from the tree next time
-        * call find_next_reservable_window.
-        */
-       my_rsv->rsv_start = cur;
-       my_rsv->rsv_end = cur + size - 1;
-       my_rsv->rsv_alloc_hit = 0;
-
-       if (prev != my_rsv)
-               ext4_rsv_window_add(sb, my_rsv);
-
-       return 0;
-}
-
-/**
- *     alloc_new_reservation()--allocate a new reservation window
- *
- *             To make a new reservation, we search part of the filesystem
- *             reservation list (the list that inside the group). We try to
- *             allocate a new reservation window near the allocation goal,
- *             or the beginning of the group, if there is no goal.
- *
- *             We first find a reservable space after the goal, then from
- *             there, we check the bitmap for the first free block after
- *             it. If there is no free block until the end of group, then the
- *             whole group is full, we failed. Otherwise, check if the free
- *             block is inside the expected reservable space, if so, we
- *             succeed.
- *             If the first free block is outside the reservable space, then
- *             start from the first free block, we search for next available
- *             space, and go on.
- *
- *     on succeed, a new reservation will be found and inserted into the list
- *     It contains at least one free block, and it does not overlap with other
- *     reservation windows.
- *
- *     failed: we failed to find a reservation window in this group
- *
- *     @rsv: the reservation
- *
- *     @grp_goal: The goal (group-relative).  It is where the search for a
- *             free reservable space should start from.
- *             if we have a grp_goal(grp_goal >0 ), then start from there,
- *             no grp_goal(grp_goal = -1), we start from the first block
- *             of the group.
- *
- *     @sb: the super block
- *     @group: the group we are trying to allocate in
- *     @bitmap_bh: the block group block bitmap
- *
- */
-static int alloc_new_reservation(struct ext4_reserve_window_node *my_rsv,
-               ext4_grpblk_t grp_goal, struct super_block *sb,
-               ext4_group_t group, struct buffer_head *bitmap_bh)
-{
-       struct ext4_reserve_window_node *search_head;
-       ext4_fsblk_t group_first_block, group_end_block, start_block;
-       ext4_grpblk_t first_free_block;
-       struct rb_root *fs_rsv_root = &EXT4_SB(sb)->s_rsv_window_root;
-       unsigned long size;
-       int ret;
-       spinlock_t *rsv_lock = &EXT4_SB(sb)->s_rsv_window_lock;
-
-       group_first_block = ext4_group_first_block_no(sb, group);
-       group_end_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1);
-
-       if (grp_goal < 0)
-               start_block = group_first_block;
-       else
-               start_block = grp_goal + group_first_block;
-
-       size = my_rsv->rsv_goal_size;
-
-       if (!rsv_is_empty(&my_rsv->rsv_window)) {
-               /*
-                * if the old reservation is cross group boundary
-                * and if the goal is inside the old reservation window,
-                * we will come here when we just failed to allocate from
-                * the first part of the window. We still have another part
-                * that belongs to the next group. In this case, there is no
-                * point to discard our window and try to allocate a new one
-                * in this group(which will fail). we should
-                * keep the reservation window, just simply move on.
-                *
-                * Maybe we could shift the start block of the reservation
-                * window to the first block of next group.
-                */
-
-               if ((my_rsv->rsv_start <= group_end_block) &&
-                               (my_rsv->rsv_end > group_end_block) &&
-                               (start_block >= my_rsv->rsv_start))
-                       return -1;
-
-               if ((my_rsv->rsv_alloc_hit >
-                    (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) {
-                       /*
-                        * if the previously allocation hit ratio is
-                        * greater than 1/2, then we double the size of
-                        * the reservation window the next time,
-                        * otherwise we keep the same size window
-                        */
-                       size = size * 2;
-                       if (size > EXT4_MAX_RESERVE_BLOCKS)
-                               size = EXT4_MAX_RESERVE_BLOCKS;
-                       my_rsv->rsv_goal_size = size;
-               }
-       }
-
-       spin_lock(rsv_lock);
-       /*
-        * shift the search start to the window near the goal block
-        */
-       search_head = search_reserve_window(fs_rsv_root, start_block);
-
-       /*
-        * find_next_reservable_window() simply finds a reservable window
-        * inside the given range(start_block, group_end_block).
-        *
-        * To make sure the reservation window has a free bit inside it, we
-        * need to check the bitmap after we found a reservable window.
-        */
-retry:
-       ret = find_next_reservable_window(search_head, my_rsv, sb,
-                                               start_block, group_end_block);
-
-       if (ret == -1) {
-               if (!rsv_is_empty(&my_rsv->rsv_window))
-                       rsv_window_remove(sb, my_rsv);
-               spin_unlock(rsv_lock);
-               return -1;
-       }
-
-       /*
-        * On success, find_next_reservable_window() returns the
-        * reservation window where there is a reservable space after it.
-        * Before we reserve this reservable space, we need
-        * to make sure there is at least a free block inside this region.
-        *
-        * searching the first free bit on the block bitmap and copy of
-        * last committed bitmap alternatively, until we found a allocatable
-        * block. Search start from the start block of the reservable space
-        * we just found.
-        */
-       spin_unlock(rsv_lock);
-       first_free_block = bitmap_search_next_usable_block(
-                       my_rsv->rsv_start - group_first_block,
-                       bitmap_bh, group_end_block - group_first_block + 1);
-
-       if (first_free_block < 0) {
-               /*
-                * no free block left on the bitmap, no point
-                * to reserve the space. return failed.
-                */
-               spin_lock(rsv_lock);
-               if (!rsv_is_empty(&my_rsv->rsv_window))
-                       rsv_window_remove(sb, my_rsv);
-               spin_unlock(rsv_lock);
-               return -1;              /* failed */
-       }
-
-       start_block = first_free_block + group_first_block;
-       /*
-        * check if the first free block is within the
-        * free space we just reserved
-        */
-       if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end)
-               return 0;               /* success */
-       /*
-        * if the first free bit we found is out of the reservable space
-        * continue search for next reservable space,
-        * start from where the free block is,
-        * we also shift the list head to where we stopped last time
-        */
-       search_head = my_rsv;
-       spin_lock(rsv_lock);
-       goto retry;
-}
-
-/**
- * try_to_extend_reservation()
- * @my_rsv:            given reservation window
- * @sb:                        super block
- * @size:              the delta to extend
- *
- * Attempt to expand the reservation window large enough to have
- * required number of free blocks
- *
- * Since ext4_try_to_allocate() will always allocate blocks within
- * the reservation window range, if the window size is too small,
- * multiple blocks allocation has to stop at the end of the reservation
- * window. To make this more efficient, given the total number of
- * blocks needed and the current size of the window, we try to
- * expand the reservation window size if necessary on a best-effort
- * basis before ext4_new_blocks() tries to allocate blocks,
- */
-static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv,
-                       struct super_block *sb, int size)
-{
-       struct ext4_reserve_window_node *next_rsv;
-       struct rb_node *next;
-       spinlock_t *rsv_lock = &EXT4_SB(sb)->s_rsv_window_lock;
-
-       if (!spin_trylock(rsv_lock))
-               return;
-
-       next = rb_next(&my_rsv->rsv_node);
-
-       if (!next)
-               my_rsv->rsv_end += size;
-       else {
-               next_rsv = rb_entry(next, struct ext4_reserve_window_node, rsv_node);
-
-               if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size)
-                       my_rsv->rsv_end += size;
-               else
-                       my_rsv->rsv_end = next_rsv->rsv_start - 1;
-       }
-       spin_unlock(rsv_lock);
-}
-
-/**
- * ext4_try_to_allocate_with_rsv()
- * @sb:                        superblock
- * @handle:            handle to this transaction
- * @group:             given allocation block group
- * @bitmap_bh:         bufferhead holds the block bitmap
- * @grp_goal:          given target block within the group
- * @count:             target number of blocks to allocate
- * @my_rsv:            reservation window
- * @errp:              pointer to store the error code
- *
- * This is the main function used to allocate a new block and its reservation
- * window.
- *
- * Each time when a new block allocation is need, first try to allocate from
- * its own reservation.  If it does not have a reservation window, instead of
- * looking for a free bit on bitmap first, then look up the reservation list to
- * see if it is inside somebody else's reservation window, we try to allocate a
- * reservation window for it starting from the goal first. Then do the block
- * allocation within the reservation window.
- *
- * This will avoid keeping on searching the reservation list again and
- * again when somebody is looking for a free block (without
- * reservation), and there are lots of free blocks, but they are all
- * being reserved.
- *
- * We use a red-black tree for the per-filesystem reservation list.
- *
- */
-static ext4_grpblk_t
-ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
-                       ext4_group_t group, struct buffer_head *bitmap_bh,
-                       ext4_grpblk_t grp_goal,
-                       struct ext4_reserve_window_node *my_rsv,
-                       unsigned long *count, int *errp)
-{
-       ext4_fsblk_t group_first_block, group_last_block;
-       ext4_grpblk_t ret = 0;
-       int fatal;
-       unsigned long num = *count;
-
-       *errp = 0;
-
-       /*
-        * Make sure we use undo access for the bitmap, because it is critical
-        * that we do the frozen_data COW on bitmap buffers in all cases even
-        * if the buffer is in BJ_Forget state in the committing transaction.
-        */
-       BUFFER_TRACE(bitmap_bh, "get undo access for new block");
-       fatal = ext4_journal_get_undo_access(handle, bitmap_bh);
-       if (fatal) {
-               *errp = fatal;
-               return -1;
-       }
-
-       /*
-        * we don't deal with reservation when
-        * filesystem is mounted without reservation
-        * or the file is not a regular file
-        * or last attempt to allocate a block with reservation turned on failed
-        */
-       if (my_rsv == NULL) {
-               ret = ext4_try_to_allocate(sb, handle, group, bitmap_bh,
-                                               grp_goal, count, NULL);
-               goto out;
-       }
-       /*
-        * grp_goal is a group relative block number (if there is a goal)
-        * 0 <= grp_goal < EXT4_BLOCKS_PER_GROUP(sb)
-        * first block is a filesystem wide block number
-        * first block is the block number of the first block in this group
-        */
-       group_first_block = ext4_group_first_block_no(sb, group);
-       group_last_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1);
-
-       /*
-        * Basically we will allocate a new block from inode's reservation
-        * window.
-        *
-        * We need to allocate a new reservation window, if:
-        * a) inode does not have a reservation window; or
-        * b) last attempt to allocate a block from existing reservation
-        *    failed; or
-        * c) we come here with a goal and with a reservation window
-        *
-        * We do not need to allocate a new reservation window if we come here
-        * at the beginning with a goal and the goal is inside the window, or
-        * we don't have a goal but already have a reservation window.
-        * then we could go to allocate from the reservation window directly.
-        */
-       while (1) {
-               if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
-                       !goal_in_my_reservation(&my_rsv->rsv_window,
-                                               grp_goal, group, sb)) {
-                       if (my_rsv->rsv_goal_size < *count)
-                               my_rsv->rsv_goal_size = *count;
-                       ret = alloc_new_reservation(my_rsv, grp_goal, sb,
-                                                       group, bitmap_bh);
-                       if (ret < 0)
-                               break;                  /* failed */
-
-                       if (!goal_in_my_reservation(&my_rsv->rsv_window,
-                                                       grp_goal, group, sb))
-                               grp_goal = -1;
-               } else if (grp_goal >= 0) {
-                       int curr = my_rsv->rsv_end -
-                                       (grp_goal + group_first_block) + 1;
-
-                       if (curr < *count)
-                               try_to_extend_reservation(my_rsv, sb,
-                                                       *count - curr);
-               }
-
-               if ((my_rsv->rsv_start > group_last_block) ||
-                               (my_rsv->rsv_end < group_first_block)) {
-                       rsv_window_dump(&EXT4_SB(sb)->s_rsv_window_root, 1);
-                       BUG();
-               }
-               ret = ext4_try_to_allocate(sb, handle, group, bitmap_bh,
-                                          grp_goal, &num, &my_rsv->rsv_window);
-               if (ret >= 0) {
-                       my_rsv->rsv_alloc_hit += num;
-                       *count = num;
-                       break;                          /* succeed */
-               }
-               num = *count;
-       }
-out:
-       if (ret >= 0) {
-               BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for "
-                                       "bitmap block");
-               fatal = ext4_journal_dirty_metadata(handle, bitmap_bh);
-               if (fatal) {
-                       *errp = fatal;
-                       return -1;
-               }
-               return ret;
-       }
-
-       BUFFER_TRACE(bitmap_bh, "journal_release_buffer");
-       ext4_journal_release_buffer(handle, bitmap_bh);
-       return ret;
-}
-
 int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
                                                s64 nblocks)
 {
@@ -1702,313 +679,6 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
        return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal);
 }
 
-/**
- * ext4_old_new_blocks() -- core block bitmap based block allocation function
- *
- * @handle:            handle to this transaction
- * @inode:             file inode
- * @goal:              given target block(filesystem wide)
- * @count:             target number of blocks to allocate
- * @errp:              error code
- *
- * ext4_old_new_blocks uses a goal block to assist allocation and look up
- * the block bitmap directly to do block allocation.  It tries to
- * allocate block(s) from the block group contains the goal block first. If
- * that fails, it will try to allocate block(s) from other block groups
- * without any specific goal block.
- *
- * This function is called when -o nomballoc mount option is enabled
- *
- */
-ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
-                       ext4_fsblk_t goal, unsigned long *count, int *errp)
-{
-       struct buffer_head *bitmap_bh = NULL;
-       struct buffer_head *gdp_bh;
-       ext4_group_t group_no;
-       ext4_group_t goal_group;
-       ext4_grpblk_t grp_target_blk;   /* blockgroup relative goal block */
-       ext4_grpblk_t grp_alloc_blk;    /* blockgroup-relative allocated block*/
-       ext4_fsblk_t ret_block;         /* filesyetem-wide allocated block */
-       ext4_group_t bgi;                       /* blockgroup iteration index */
-       int fatal = 0, err;
-       int performed_allocation = 0;
-       ext4_grpblk_t free_blocks;      /* number of free blocks in a group */
-       struct super_block *sb;
-       struct ext4_group_desc *gdp;
-       struct ext4_super_block *es;
-       struct ext4_sb_info *sbi;
-       struct ext4_reserve_window_node *my_rsv = NULL;
-       struct ext4_block_alloc_info *block_i;
-       unsigned short windowsz = 0;
-       ext4_group_t ngroups;
-       unsigned long num = *count;
-
-       sb = inode->i_sb;
-       if (!sb) {
-               *errp = -ENODEV;
-               printk(KERN_ERR "ext4_new_block: nonexistent superblock");
-               return 0;
-       }
-
-       sbi = EXT4_SB(sb);
-       if (!EXT4_I(inode)->i_delalloc_reserved_flag) {
-               /*
-                * With delalloc we already reserved the blocks
-                */
-               while (*count && ext4_claim_free_blocks(sbi, *count)) {
-                       /* let others to free the space */
-                       yield();
-                       *count = *count >> 1;
-               }
-               if (!*count) {
-                       *errp = -ENOSPC;
-                       return 0;       /*return with ENOSPC error */
-               }
-               num = *count;
-       }
-       /*
-        * Check quota for allocation of this block.
-        */
-       if (DQUOT_ALLOC_BLOCK(inode, num)) {
-               *errp = -EDQUOT;
-               return 0;
-       }
-
-       sbi = EXT4_SB(sb);
-       es = EXT4_SB(sb)->s_es;
-       ext4_debug("goal=%llu.\n", goal);
-       /*
-        * Allocate a block from reservation only when
-        * filesystem is mounted with reservation(default,-o reservation), and
-        * it's a regular file, and
-        * the desired window size is greater than 0 (One could use ioctl
-        * command EXT4_IOC_SETRSVSZ to set the window size to 0 to turn off
-        * reservation on that particular file)
-        */
-       block_i = EXT4_I(inode)->i_block_alloc_info;
-       if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
-               my_rsv = &block_i->rsv_window_node;
-
-       /*
-        * First, test whether the goal block is free.
-        */
-       if (goal < le32_to_cpu(es->s_first_data_block) ||
-           goal >= ext4_blocks_count(es))
-               goal = le32_to_cpu(es->s_first_data_block);
-       ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
-       goal_group = group_no;
-retry_alloc:
-       gdp = ext4_get_group_desc(sb, group_no, &gdp_bh);
-       if (!gdp)
-               goto io_error;
-
-       free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
-
-       if (free_blocks > 0) {
-               /*
-                * try to allocate with group target block
-                * in the goal group. If we have low free_blocks
-                * count turn off reservation
-                */
-               if (my_rsv && (free_blocks < windowsz)
-                       && (rsv_is_empty(&my_rsv->rsv_window)))
-                       my_rsv = NULL;
-
-               bitmap_bh = ext4_read_block_bitmap(sb, group_no);
-               if (!bitmap_bh)
-                       goto io_error;
-               grp_alloc_blk = ext4_try_to_allocate_with_rsv(sb, handle,
-                                       group_no, bitmap_bh, grp_target_blk,
-                                       my_rsv, &num, &fatal);
-               if (fatal)
-                       goto out;
-               if (grp_alloc_blk >= 0)
-                       goto allocated;
-       }
-
-       ngroups = EXT4_SB(sb)->s_groups_count;
-       smp_rmb();
-
-       /*
-        * Now search the rest of the groups.  We assume that
-        * group_no and gdp correctly point to the last group visited.
-        */
-       for (bgi = 0; bgi < ngroups; bgi++) {
-               group_no++;
-               if (group_no >= ngroups)
-                       group_no = 0;
-               gdp = ext4_get_group_desc(sb, group_no, &gdp_bh);
-               if (!gdp)
-                       goto io_error;
-               free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
-               /*
-                * skip this group if the number of
-                * free blocks is less than half of the reservation
-                * window size.
-                */
-               if (my_rsv && (free_blocks <= (windowsz/2)))
-                       continue;
-
-               brelse(bitmap_bh);
-               bitmap_bh = ext4_read_block_bitmap(sb, group_no);
-               if (!bitmap_bh)
-                       goto io_error;
-               /*
-                * try to allocate block(s) from this group, without a goal(-1).
-                */
-               grp_alloc_blk = ext4_try_to_allocate_with_rsv(sb, handle,
-                                       group_no, bitmap_bh, -1, my_rsv,
-                                       &num, &fatal);
-               if (fatal)
-                       goto out;
-               if (grp_alloc_blk >= 0)
-                       goto allocated;
-       }
-       /*
-        * We may end up a bogus ealier ENOSPC error due to
-        * filesystem is "full" of reservations, but
-        * there maybe indeed free blocks avaliable on disk
-        * In this case, we just forget about the reservations
-        * just do block allocation as without reservations.
-        */
-       if (my_rsv) {
-               my_rsv = NULL;
-               windowsz = 0;
-               group_no = goal_group;
-               goto retry_alloc;
-       }
-       /* No space left on the device */
-       *errp = -ENOSPC;
-       goto out;
-
-allocated:
-
-       ext4_debug("using block group %lu(%d)\n",
-                       group_no, gdp->bg_free_blocks_count);
-
-       BUFFER_TRACE(gdp_bh, "get_write_access");
-       fatal = ext4_journal_get_write_access(handle, gdp_bh);
-       if (fatal)
-               goto out;
-
-       ret_block = grp_alloc_blk + ext4_group_first_block_no(sb, group_no);
-
-       if (in_range(ext4_block_bitmap(sb, gdp), ret_block, num) ||
-           in_range(ext4_inode_bitmap(sb, gdp), ret_block, num) ||
-           in_range(ret_block, ext4_inode_table(sb, gdp),
-                    EXT4_SB(sb)->s_itb_per_group) ||
-           in_range(ret_block + num - 1, ext4_inode_table(sb, gdp),
-                    EXT4_SB(sb)->s_itb_per_group)) {
-               ext4_error(sb, "ext4_new_block",
-                           "Allocating block in system zone - "
-                           "blocks from %llu, length %lu",
-                            ret_block, num);
-               /*
-                * claim_block marked the blocks we allocated
-                * as in use. So we may want to selectively
-                * mark some of the blocks as free
-                */
-               goto retry_alloc;
-       }
-
-       performed_allocation = 1;
-
-#ifdef CONFIG_JBD2_DEBUG
-       {
-               struct buffer_head *debug_bh;
-
-               /* Record bitmap buffer state in the newly allocated block */
-               debug_bh = sb_find_get_block(sb, ret_block);
-               if (debug_bh) {
-                       BUFFER_TRACE(debug_bh, "state when allocated");
-                       BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap state");
-                       brelse(debug_bh);
-               }
-       }
-       jbd_lock_bh_state(bitmap_bh);
-       spin_lock(sb_bgl_lock(sbi, group_no));
-       if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) {
-               int i;
-
-               for (i = 0; i < num; i++) {
-                       if (ext4_test_bit(grp_alloc_blk+i,
-                                       bh2jh(bitmap_bh)->b_committed_data)) {
-                               printk(KERN_ERR "%s: block was unexpectedly "
-                                      "set in b_committed_data\n", __func__);
-                       }
-               }
-       }
-       ext4_debug("found bit %d\n", grp_alloc_blk);
-       spin_unlock(sb_bgl_lock(sbi, group_no));
-       jbd_unlock_bh_state(bitmap_bh);
-#endif
-
-       if (ret_block + num - 1 >= ext4_blocks_count(es)) {
-               ext4_error(sb, "ext4_new_block",
-                           "block(%llu) >= blocks count(%llu) - "
-                           "block_group = %lu, es == %p ", ret_block,
-                       ext4_blocks_count(es), group_no, es);
-               goto out;
-       }
-
-       /*
-        * It is up to the caller to add the new buffer to a journal
-        * list of some description.  We don't know in advance whether
-        * the caller wants to use it as metadata or data.
-        */
-       spin_lock(sb_bgl_lock(sbi, group_no));
-       if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
-               gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
-       le16_add_cpu(&gdp->bg_free_blocks_count, -num);
-       gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
-       spin_unlock(sb_bgl_lock(sbi, group_no));
-       percpu_counter_sub(&sbi->s_freeblocks_counter, num);
-       /*
-        * Now reduce the dirty block count also. Should not go negative
-        */
-       if (!EXT4_I(inode)->i_delalloc_reserved_flag)
-               percpu_counter_sub(&sbi->s_dirtyblocks_counter, *count);
-       else
-               percpu_counter_sub(&sbi->s_dirtyblocks_counter, num);
-       if (sbi->s_log_groups_per_flex) {
-               ext4_group_t flex_group = ext4_flex_group(sbi, group_no);
-               spin_lock(sb_bgl_lock(sbi, flex_group));
-               sbi->s_flex_groups[flex_group].free_blocks -= num;
-               spin_unlock(sb_bgl_lock(sbi, flex_group));
-       }
-
-       BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor");
-       err = ext4_journal_dirty_metadata(handle, gdp_bh);
-       if (!fatal)
-               fatal = err;
-
-       sb->s_dirt = 1;
-       if (fatal)
-               goto out;
-
-       *errp = 0;
-       brelse(bitmap_bh);
-       DQUOT_FREE_BLOCK(inode, *count-num);
-       *count = num;
-       return ret_block;
-
-io_error:
-       *errp = -EIO;
-out:
-       if (fatal) {
-               *errp = fatal;
-               ext4_std_error(sb, fatal);
-       }
-       /*
-        * Undo the block allocation
-        */
-       if (!performed_allocation)
-               DQUOT_FREE_BLOCK(inode, *count);
-       brelse(bitmap_bh);
-       return 0;
-}
-
 #define EXT4_META_BLOCK 0x1
 
 static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode,
@@ -2018,10 +688,6 @@ static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode,
        struct ext4_allocation_request ar;
        ext4_fsblk_t ret;
 
-       if (!test_opt(inode->i_sb, MBALLOC)) {
-               return ext4_old_new_blocks(handle, inode, goal, count, errp);
-       }
-
        memset(&ar, 0, sizeof(ar));
        /* Fill with neighbour allocated blocks */
 
@@ -2242,3 +908,4 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
        return ext4_bg_num_gdb_meta(sb,group);
 
 }
+
index 922d187..c50c04c 100644 (file)
@@ -539,7 +539,6 @@ do {                                                                               \
 #define EXT4_MOUNT_JOURNAL_CHECKSUM    0x800000 /* Journal checksums */
 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT        0x1000000 /* Journal Async Commit */
 #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
-#define EXT4_MOUNT_MBALLOC             0x4000000 /* Buddy allocation support */
 #define EXT4_MOUNT_DELALLOC            0x8000000 /* Delalloc support */
 /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
 #ifndef _LINUX_EXT2_FS_H
@@ -1002,8 +1001,6 @@ extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
 extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
                                        ext4_lblk_t iblock, ext4_fsblk_t goal,
                                        unsigned long *count, int *errp);
-extern ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
-                       ext4_fsblk_t goal, unsigned long *count, int *errp);
 extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks);
 extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
                                         s64 nblocks);
@@ -1018,8 +1015,6 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
                                                    ext4_group_t block_group,
                                                    struct buffer_head ** bh);
 extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
-extern void ext4_init_block_alloc_info(struct inode *);
-extern void ext4_rsv_window_add(struct super_block *sb, struct ext4_reserve_window_node *rsv);
 
 /* dir.c */
 extern int ext4_check_dir_entry(const char *, struct inode *,
@@ -1054,7 +1049,7 @@ extern int ext4_mb_release(struct super_block *);
 extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *,
                                struct ext4_allocation_request *, int *);
 extern int ext4_mb_reserve_blocks(struct super_block *, int);
-extern void ext4_mb_discard_inode_preallocations(struct inode *);
+extern void ext4_discard_preallocations(struct inode *);
 extern int __init init_ext4_mballoc(void);
 extern void exit_ext4_mballoc(void);
 extern void ext4_mb_free_blocks(handle_t *, struct inode *,
@@ -1084,7 +1079,6 @@ extern int  ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
                                struct kstat *stat);
 extern void ext4_delete_inode(struct inode *);
 extern int  ext4_sync_inode(handle_t *, struct inode *);
-extern void ext4_discard_reservation(struct inode *);
 extern void ext4_dirty_inode(struct inode *);
 extern int ext4_change_inode_journal_flag(struct inode *, int);
 extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *);
index ef7409f..2875eec 100644 (file)
@@ -33,38 +33,6 @@ typedef __u32 ext4_lblk_t;
 /* data type for block group number */
 typedef unsigned long ext4_group_t;
 
-struct ext4_reserve_window {
-       ext4_fsblk_t    _rsv_start;     /* First byte reserved */
-       ext4_fsblk_t    _rsv_end;       /* Last byte reserved or 0 */
-};
-
-struct ext4_reserve_window_node {
-       struct rb_node          rsv_node;
-       __u32                   rsv_goal_size;
-       __u32                   rsv_alloc_hit;
-       struct ext4_reserve_window      rsv_window;
-};
-
-struct ext4_block_alloc_info {
-       /* information about reservation window */
-       struct ext4_reserve_window_node rsv_window_node;
-       /*
-        * was i_next_alloc_block in ext4_inode_info
-        * is the logical (file-relative) number of the
-        * most-recently-allocated block in this file.
-        * We use this for detecting linearly ascending allocation requests.
-        */
-       ext4_lblk_t last_alloc_logical_block;
-       /*
-        * Was i_next_alloc_goal in ext4_inode_info
-        * is the *physical* companion to i_next_alloc_block.
-        * it the physical block number of the block which was most-recentl
-        * allocated to this file.  This give us the goal (target) for the next
-        * allocation when we detect linearly ascending requests.
-        */
-       ext4_fsblk_t last_alloc_physical_block;
-};
-
 #define rsv_start rsv_window._rsv_start
 #define rsv_end rsv_window._rsv_end
 
@@ -97,9 +65,6 @@ struct ext4_inode_info {
        ext4_group_t    i_block_group;
        __u32   i_state;                /* Dynamic state flags for ext4 */
 
-       /* block reservation info */
-       struct ext4_block_alloc_info *i_block_alloc_info;
-
        ext4_lblk_t             i_dir_start_lookup;
 #ifdef CONFIG_EXT4DEV_FS_XATTR
        /*
index 94e0757..6a0b40d 100644 (file)
@@ -67,7 +67,6 @@ struct ext4_sb_info {
        /* root of the per fs reservation window tree */
        spinlock_t s_rsv_window_lock;
        struct rb_root s_rsv_window_root;
-       struct ext4_reserve_window_node s_rsv_window_head;
 
        /* Journaling */
        struct inode *s_journal_inode;
index e8758df..c8f81f2 100644 (file)
@@ -2697,11 +2697,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                goto out2;
        }
        /*
-        * Okay, we need to do block allocation.  Lazily initialize the block
-        * allocation info here if necessary.
+        * Okay, we need to do block allocation.
         */
-       if (S_ISREG(inode->i_mode) && (!EXT4_I(inode)->i_block_alloc_info))
-               ext4_init_block_alloc_info(inode);
 
        /* find neighbour allocated blocks */
        ar.lleft = iblock;
@@ -2761,7 +2758,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                /* free data blocks we just allocated */
                /* not a good idea to call discard here directly,
                 * but otherwise we'd need to call it every free() */
-               ext4_mb_discard_inode_preallocations(inode);
+               ext4_discard_preallocations(inode);
                ext4_free_blocks(handle, inode, ext_pblock(&newex),
                                        ext4_ext_get_actual_len(&newex), 0);
                goto out2;
@@ -2825,7 +2822,7 @@ void ext4_ext_truncate(struct inode *inode)
        down_write(&EXT4_I(inode)->i_data_sem);
        ext4_ext_invalidate_cache(inode);
 
-       ext4_discard_reservation(inode);
+       ext4_discard_preallocations(inode);
 
        /*
         * TODO: optimization is possible here.
index 11b289f..62796b7 100644 (file)
@@ -38,7 +38,7 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
                        (atomic_read(&inode->i_writecount) == 1))
        {
                down_write(&EXT4_I(inode)->i_data_sem);
-               ext4_discard_reservation(inode);
+               ext4_discard_preallocations(inode);
                up_write(&EXT4_I(inode)->i_data_sem);
        }
        if (is_dx(inode) && filp->private_data)
index 5e66a2f..1343bf1 100644 (file)
@@ -817,7 +817,6 @@ got:
                ei->i_flags &= ~EXT4_DIRSYNC_FL;
        ei->i_file_acl = 0;
        ei->i_dtime = 0;
-       ei->i_block_alloc_info = NULL;
        ei->i_block_group = group;
 
        ext4_set_inode_flags(inode);
index ef4ca3d..bd770c3 100644 (file)
@@ -486,18 +486,9 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
 static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block,
                Indirect *partial)
 {
-       struct ext4_block_alloc_info *block_i;
-
-       block_i =  EXT4_I(inode)->i_block_alloc_info;
-
        /*
-        * try the heuristic for sequential allocation,
-        * failing that at least try to get decent locality.
+        * XXX need to get goal block from mballoc's data structures
         */
-       if (block_i && (block == block_i->last_alloc_logical_block + 1)
-               && (block_i->last_alloc_physical_block != 0)) {
-               return block_i->last_alloc_physical_block + 1;
-       }
 
        return ext4_find_near(inode, partial);
 }
@@ -757,10 +748,8 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
 {
        int i;
        int err = 0;
-       struct ext4_block_alloc_info *block_i;
        ext4_fsblk_t current_block;
 
-       block_i = EXT4_I(inode)->i_block_alloc_info;
        /*
         * If we're splicing into a [td]indirect block (as opposed to the
         * inode) then we need to get write access to the [td]indirect block
@@ -786,17 +775,6 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
                        *(where->p + i) = cpu_to_le32(current_block++);
        }
 
-       /*
-        * update the most recently allocated logical & physical block
-        * in i_block_alloc_info, to assist find the proper goal block for next
-        * allocation
-        */
-       if (block_i) {
-               block_i->last_alloc_logical_block = block + blks - 1;
-               block_i->last_alloc_physical_block =
-                               le32_to_cpu(where[num].key) + blks - 1;
-       }
-
        /* We are done with atomic stuff, now do the rest of housekeeping */
 
        inode->i_ctime = ext4_current_time(inode);
@@ -914,12 +892,8 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
                goto cleanup;
 
        /*
-        * Okay, we need to do block allocation.  Lazily initialize the block
-        * allocation info here if necessary
+        * Okay, we need to do block allocation.
        */
-       if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info))
-               ext4_init_block_alloc_info(inode);
-
        goal = ext4_find_goal(inode, iblock, partial);
 
        /* the number of blocks need to allocate for [d,t]indirect blocks */
@@ -3738,7 +3712,7 @@ void ext4_truncate(struct inode *inode)
         */
        down_write(&ei->i_data_sem);
 
-       ext4_discard_reservation(inode);
+       ext4_discard_preallocations(inode);
 
        /*
         * The orphan list entry will now protect us from any crash which
@@ -4071,7 +4045,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
        ei->i_acl = EXT4_ACL_NOT_CACHED;
        ei->i_default_acl = EXT4_ACL_NOT_CACHED;
 #endif
-       ei->i_block_alloc_info = NULL;
 
        ret = __ext4_get_inode_loc(inode, &iloc, 0);
        if (ret < 0)
index 3e14060..ea27eaa 100644 (file)
@@ -23,7 +23,6 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        struct inode *inode = filp->f_dentry->d_inode;
        struct ext4_inode_info *ei = EXT4_I(inode);
        unsigned int flags;
-       unsigned short rsv_window_size;
 
        ext4_debug("cmd = %u, arg = %lu\n", cmd, arg);
 
@@ -190,49 +189,6 @@ setversion_out:
                        return ret;
                }
 #endif
-       case EXT4_IOC_GETRSVSZ:
-               if (test_opt(inode->i_sb, RESERVATION)
-                       && S_ISREG(inode->i_mode)
-                       && ei->i_block_alloc_info) {
-                       rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
-                       return put_user(rsv_window_size, (int __user *)arg);
-               }
-               return -ENOTTY;
-       case EXT4_IOC_SETRSVSZ: {
-               int err;
-
-               if (!test_opt(inode->i_sb, RESERVATION) || !S_ISREG(inode->i_mode))
-                       return -ENOTTY;
-
-               if (!is_owner_or_cap(inode))
-                       return -EACCES;
-
-               if (get_user(rsv_window_size, (int __user *)arg))
-                       return -EFAULT;
-
-               err = mnt_want_write(filp->f_path.mnt);
-               if (err)
-                       return err;
-
-               if (rsv_window_size > EXT4_MAX_RESERVE_BLOCKS)
-                       rsv_window_size = EXT4_MAX_RESERVE_BLOCKS;
-
-               /*
-                * need to allocate reservation structure for this inode
-                * before set the window size
-                */
-               down_write(&ei->i_data_sem);
-               if (!ei->i_block_alloc_info)
-                       ext4_init_block_alloc_info(inode);
-
-               if (ei->i_block_alloc_info){
-                       struct ext4_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
-                       rsv->rsv_goal_size = rsv_window_size;
-               }
-               up_write(&ei->i_data_sem);
-               mnt_drop_write(filp->f_path.mnt);
-               return 0;
-       }
        case EXT4_IOC_GROUP_EXTEND: {
                ext4_fsblk_t n_blocks_count;
                struct super_block *sb = inode->i_sb;
index b9118bb..335faee 100644 (file)
@@ -534,9 +534,6 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,
        void *buddy;
        void *buddy2;
 
-       if (!test_opt(sb, MBALLOC))
-               return 0;
-
        {
                static int mb_check_counter;
                if (mb_check_counter++ % 100 != 0)
@@ -2487,19 +2484,14 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
        unsigned max;
        int ret;
 
-       if (!test_opt(sb, MBALLOC))
-               return 0;
-
        i = (sb->s_blocksize_bits + 2) * sizeof(unsigned short);
 
        sbi->s_mb_offsets = kmalloc(i, GFP_KERNEL);
        if (sbi->s_mb_offsets == NULL) {
-               clear_opt(sbi->s_mount_opt, MBALLOC);
                return -ENOMEM;
        }
        sbi->s_mb_maxs = kmalloc(i, GFP_KERNEL);
        if (sbi->s_mb_maxs == NULL) {
-               clear_opt(sbi->s_mount_opt, MBALLOC);
                kfree(sbi->s_mb_maxs);
                return -ENOMEM;
        }
@@ -2522,7 +2514,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
        /* init file for buddy data */
        ret = ext4_mb_init_backend(sb);
        if (ret != 0) {
-               clear_opt(sbi->s_mount_opt, MBALLOC);
                kfree(sbi->s_mb_offsets);
                kfree(sbi->s_mb_maxs);
                return ret;
@@ -2544,7 +2535,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
 
        sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group);
        if (sbi->s_locality_groups == NULL) {
-               clear_opt(sbi->s_mount_opt, MBALLOC);
                kfree(sbi->s_mb_offsets);
                kfree(sbi->s_mb_maxs);
                return -ENOMEM;
@@ -2590,9 +2580,6 @@ int ext4_mb_release(struct super_block *sb)
        struct ext4_group_info *grinfo;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
 
-       if (!test_opt(sb, MBALLOC))
-               return 0;
-
        /* release freed, non-committed blocks */
        spin_lock(&sbi->s_md_lock);
        list_splice_init(&sbi->s_closed_transaction,
@@ -3805,7 +3792,7 @@ out:
  *
  * FIXME!! Make sure it is valid at all the call sites
  */
-void ext4_mb_discard_inode_preallocations(struct inode *inode)
+void ext4_discard_preallocations(struct inode *inode)
 {
        struct ext4_inode_info *ei = EXT4_I(inode);
        struct super_block *sb = inode->i_sb;
@@ -3817,7 +3804,7 @@ void ext4_mb_discard_inode_preallocations(struct inode *inode)
        struct ext4_buddy e4b;
        int err;
 
-       if (!test_opt(sb, MBALLOC) || !S_ISREG(inode->i_mode)) {
+       if (!S_ISREG(inode->i_mode)) {
                /*BUG_ON(!list_empty(&ei->i_prealloc_list));*/
                return;
        }
@@ -4300,11 +4287,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
        sb = ar->inode->i_sb;
        sbi = EXT4_SB(sb);
 
-       if (!test_opt(sb, MBALLOC)) {
-               block = ext4_old_new_blocks(handle, ar->inode, ar->goal,
-                                           &(ar->len), errp);
-               return block;
-       }
        if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) {
                /*
                 * With delalloc we already reserved the blocks
index b60afbc..b6ec184 100644 (file)
@@ -870,11 +870,10 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
         * We can allocate memory for mb_alloc based on the new group
         * descriptor
         */
-       if (test_opt(sb, MBALLOC)) {
-               err = ext4_mb_add_more_groupinfo(sb, input->group, gdp);
-               if (err)
-                       goto exit_journal;
-       }
+       err = ext4_mb_add_more_groupinfo(sb, input->group, gdp);
+       if (err)
+               goto exit_journal;
+
        /*
         * Make the new blocks and inodes valid next.  We do this before
         * increasing the group count so that once the group is enabled,
@@ -1086,8 +1085,15 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        /*
         * Mark mballoc pages as not up to date so that they will be updated
         * next time they are loaded by ext4_mb_load_buddy.
+        *
+        * XXX Bad, Bad, BAD!!!  We should not be overloading the
+        * Uptodate flag, particularly on thte bitmap bh, as way of
+        * hinting to ext4_mb_load_buddy() that it needs to be
+        * overloaded.  A user could take a LVM snapshot, then do an
+        * on-line fsck, and clear the uptodate flag, and this would
+        * not be a bug in userspace, but a bug in the kernel.  FIXME!!!
         */
-       if (test_opt(sb, MBALLOC)) {
+       {
                struct ext4_sb_info *sbi = EXT4_SB(sb);
                struct inode *inode = sbi->s_buddy_cache;
                int blocks_per_page;
index 6583aee..dfcd41f 100644 (file)
@@ -574,7 +574,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        ei->i_acl = EXT4_ACL_NOT_CACHED;
        ei->i_default_acl = EXT4_ACL_NOT_CACHED;
 #endif
-       ei->i_block_alloc_info = NULL;
        ei->vfs_inode.i_version = 1;
        ei->vfs_inode.i_data.writeback_index = 0;
        memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
@@ -633,7 +632,6 @@ static void destroy_inodecache(void)
 
 static void ext4_clear_inode(struct inode *inode)
 {
-       struct ext4_block_alloc_info *rsv = EXT4_I(inode)->i_block_alloc_info;
 #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
        if (EXT4_I(inode)->i_acl &&
                        EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) {
@@ -646,10 +644,7 @@ static void ext4_clear_inode(struct inode *inode)
                EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED;
        }
 #endif
-       ext4_discard_reservation(inode);
-       EXT4_I(inode)->i_block_alloc_info = NULL;
-       if (unlikely(rsv))
-               kfree(rsv);
+       ext4_discard_preallocations(inode);
        jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal,
                                       &EXT4_I(inode)->jinode);
 }
@@ -760,8 +755,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
                seq_puts(seq, ",nobh");
        if (!test_opt(sb, EXTENTS))
                seq_puts(seq, ",noextents");
-       if (!test_opt(sb, MBALLOC))
-               seq_puts(seq, ",nomballoc");
        if (test_opt(sb, I_VERSION))
                seq_puts(seq, ",i_version");
        if (!test_opt(sb, DELALLOC))
@@ -1373,12 +1366,6 @@ set_qf_format:
                case Opt_nodelalloc:
                        clear_opt(sbi->s_mount_opt, DELALLOC);
                        break;
-               case Opt_mballoc:
-                       set_opt(sbi->s_mount_opt, MBALLOC);
-                       break;
-               case Opt_nomballoc:
-                       clear_opt(sbi->s_mount_opt, MBALLOC);
-                       break;
                case Opt_stripe:
                        if (match_int(&args[0], &option))
                                return 0;
@@ -2040,11 +2027,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                ext4_warning(sb, __func__,
                        "extents feature not enabled on this filesystem, "
                        "use tune2fs.\n");
-       /*
-        * turn on mballoc code by default in ext4 filesystem
-        * Use -o nomballoc to turn it off
-        */
-       set_opt(sbi->s_mount_opt, MBALLOC);
 
        /*
         * enable delayed allocation by default
@@ -2301,19 +2283,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                goto failed_mount3;
        }
 
-       /* per fileystem reservation list head & lock */
-       spin_lock_init(&sbi->s_rsv_window_lock);
-       sbi->s_rsv_window_root = RB_ROOT;
-       /* Add a single, static dummy reservation to the start of the
-        * reservation window list --- it gives us a placeholder for
-        * append-at-start-of-list which makes the allocation logic
-        * _much_ simpler. */
-       sbi->s_rsv_window_head.rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
-       sbi->s_rsv_window_head.rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
-       sbi->s_rsv_window_head.rsv_alloc_hit = 0;
-       sbi->s_rsv_window_head.rsv_goal_size = 0;
-       ext4_rsv_window_add(sb, &sbi->s_rsv_window_head);
-
        sbi->s_stripe = ext4_get_stripe_size(sbi);
 
        /*
@@ -2510,7 +2479,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n");
 
        ext4_ext_init(sb);
-       ext4_mb_init(sb, needs_recovery);
+       err = ext4_mb_init(sb, needs_recovery);
+       if (err) {
+               printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n",
+                      err);
+               goto failed_mount4;
+       }
 
        lock_kernel();
        return 0;