]> err.no Git - linux-2.6/blobdiff - fs/ext4/resize.c
Merge branches 'x86/numa-fixes', 'x86/apic', 'x86/apm', 'x86/bitops', 'x86/build...
[linux-2.6] / fs / ext4 / resize.c
index 0a7e914c495a861625cd01834544531b15e2748b..9ff7b1c04239d6581a12f0dd18a73538a0695abc 100644 (file)
 
 #define EXT4FS_DEBUG
 
-#include <linux/ext4_jbd2.h>
-
 #include <linux/errno.h>
 #include <linux/slab.h>
 
+#include "ext4_jbd2.h"
 #include "group.h"
 
 #define outside(b, first, last)        ((b) < (first) || (b) >= (last))
@@ -28,7 +27,7 @@ static int verify_group_input(struct super_block *sb,
        struct ext4_super_block *es = sbi->s_es;
        ext4_fsblk_t start = ext4_blocks_count(es);
        ext4_fsblk_t end = start + input->blocks_count;
-       unsigned group = input->group;
+       ext4_group_t group = input->group;
        ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
        unsigned overhead = ext4_bg_has_super(sb, group) ?
                (1 + ext4_bg_num_gdb(sb, group) +
@@ -50,63 +49,63 @@ static int verify_group_input(struct super_block *sb,
 
        ext4_get_group_no_and_offset(sb, start, NULL, &offset);
        if (group != sbi->s_groups_count)
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Cannot add at group %u (only %lu groups)",
                             input->group, sbi->s_groups_count);
        else if (offset != 0)
-                       ext4_warning(sb, __FUNCTION__, "Last group not full");
+                       ext4_warning(sb, __func__, "Last group not full");
        else if (input->reserved_blocks > input->blocks_count / 5)
-               ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)",
+               ext4_warning(sb, __func__, "Reserved blocks too high (%u)",
                             input->reserved_blocks);
        else if (free_blocks_count < 0)
-               ext4_warning(sb, __FUNCTION__, "Bad blocks count %u",
+               ext4_warning(sb, __func__, "Bad blocks count %u",
                             input->blocks_count);
        else if (!(bh = sb_bread(sb, end - 1)))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Cannot read last block (%llu)",
                             end - 1);
        else if (outside(input->block_bitmap, start, end))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Block bitmap not in group (block %llu)",
                             (unsigned long long)input->block_bitmap);
        else if (outside(input->inode_bitmap, start, end))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Inode bitmap not in group (block %llu)",
                             (unsigned long long)input->inode_bitmap);
        else if (outside(input->inode_table, start, end) ||
                 outside(itend - 1, start, end))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Inode table not in group (blocks %llu-%llu)",
                             (unsigned long long)input->inode_table, itend - 1);
        else if (input->inode_bitmap == input->block_bitmap)
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Block bitmap same as inode bitmap (%llu)",
                             (unsigned long long)input->block_bitmap);
        else if (inside(input->block_bitmap, input->inode_table, itend))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Block bitmap (%llu) in inode table (%llu-%llu)",
                             (unsigned long long)input->block_bitmap,
                             (unsigned long long)input->inode_table, itend - 1);
        else if (inside(input->inode_bitmap, input->inode_table, itend))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Inode bitmap (%llu) in inode table (%llu-%llu)",
                             (unsigned long long)input->inode_bitmap,
                             (unsigned long long)input->inode_table, itend - 1);
        else if (inside(input->block_bitmap, start, metaend))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Block bitmap (%llu) in GDT table"
                             " (%llu-%llu)",
                             (unsigned long long)input->block_bitmap,
                             start, metaend - 1);
        else if (inside(input->inode_bitmap, start, metaend))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Inode bitmap (%llu) in GDT table"
                             " (%llu-%llu)",
                             (unsigned long long)input->inode_bitmap,
                             start, metaend - 1);
        else if (inside(input->inode_table, start, metaend) ||
                 inside(itend - 1, start, metaend))
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Inode table (%llu-%llu) overlaps"
                             "GDT table (%llu-%llu)",
                             (unsigned long long)input->inode_table,
@@ -140,6 +139,32 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
        return bh;
 }
 
+/*
+ * If we have fewer than thresh credits, extend by EXT4_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
+ */
+static int extend_or_restart_transaction(handle_t *handle, int thresh,
+                                        struct buffer_head *bh)
+{
+       int err;
+
+       if (handle->h_buffer_credits >= thresh)
+               return 0;
+
+       err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA);
+       if (err < 0)
+               return err;
+       if (err) {
+               if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
+                       return err;
+               if ((err = ext4_journal_get_write_access(handle, bh)))
+                       return err;
+        }
+
+       return 0;
+}
+
 /*
  * Set up the block and inode bitmaps, and the inode table for the new group.
  * This doesn't need to be part of the main transaction, since we are only
@@ -162,8 +187,9 @@ static int setup_new_group_blocks(struct super_block *sb,
        int i;
        int err = 0, err2;
 
-       handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks +
-                                      2 + sbi->s_itb_per_group);
+       /* This transaction may be extended/restarted along the way */
+       handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
+
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
@@ -179,7 +205,7 @@ static int setup_new_group_blocks(struct super_block *sb,
        }
 
        if (ext4_bg_has_super(sb, input->group)) {
-               ext4_debug("mark backup superblock %#04lx (+0)\n", start);
+               ext4_debug("mark backup superblock %#04llx (+0)\n", start);
                ext4_set_bit(0, bh->b_data);
        }
 
@@ -188,7 +214,10 @@ static int setup_new_group_blocks(struct super_block *sb,
             i < gdblocks; i++, block++, bit++) {
                struct buffer_head *gdb;
 
-               ext4_debug("update backup group %#04lx (+%d)\n", block, bit);
+               ext4_debug("update backup group %#04llx (+%d)\n", block, bit);
+
+               if ((err = extend_or_restart_transaction(handle, 1, bh)))
+                       goto exit_bh;
 
                gdb = sb_getblk(sb, block);
                if (!gdb) {
@@ -199,10 +228,10 @@ static int setup_new_group_blocks(struct super_block *sb,
                        brelse(gdb);
                        goto exit_bh;
                }
-               lock_buffer(bh);
-               memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+               lock_buffer(gdb);
+               memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
                set_buffer_uptodate(gdb);
-               unlock_buffer(bh);
+               unlock_buffer(gdb);
                ext4_journal_dirty_metadata(handle, gdb);
                ext4_set_bit(bit, bh->b_data);
                brelse(gdb);
@@ -213,7 +242,10 @@ static int setup_new_group_blocks(struct super_block *sb,
             i < reserved_gdb; i++, block++, bit++) {
                struct buffer_head *gdb;
 
-               ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit);
+               ext4_debug("clear reserved block %#04llx (+%d)\n", block, bit);
+
+               if ((err = extend_or_restart_transaction(handle, 1, bh)))
+                       goto exit_bh;
 
                if (IS_ERR(gdb = bclean(handle, sb, block))) {
                        err = PTR_ERR(bh);
@@ -223,10 +255,10 @@ static int setup_new_group_blocks(struct super_block *sb,
                ext4_set_bit(bit, bh->b_data);
                brelse(gdb);
        }
-       ext4_debug("mark block bitmap %#04x (+%ld)\n", input->block_bitmap,
+       ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap,
                   input->block_bitmap - start);
        ext4_set_bit(input->block_bitmap - start, bh->b_data);
-       ext4_debug("mark inode bitmap %#04x (+%ld)\n", input->inode_bitmap,
+       ext4_debug("mark inode bitmap %#04llx (+%llu)\n", input->inode_bitmap,
                   input->inode_bitmap - start);
        ext4_set_bit(input->inode_bitmap - start, bh->b_data);
 
@@ -235,7 +267,11 @@ static int setup_new_group_blocks(struct super_block *sb,
             i < sbi->s_itb_per_group; i++, bit++, block++) {
                struct buffer_head *it;
 
-               ext4_debug("clear inode block %#04lx (+%d)\n", block, bit);
+               ext4_debug("clear inode block %#04llx (+%d)\n", block, bit);
+
+               if ((err = extend_or_restart_transaction(handle, 1, bh)))
+                       goto exit_bh;
+
                if (IS_ERR(it = bclean(handle, sb, block))) {
                        err = PTR_ERR(it);
                        goto exit_bh;
@@ -244,13 +280,17 @@ static int setup_new_group_blocks(struct super_block *sb,
                brelse(it);
                ext4_set_bit(bit, bh->b_data);
        }
+
+       if ((err = extend_or_restart_transaction(handle, 2, bh)))
+               goto exit_bh;
+
        mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
                        bh->b_data);
        ext4_journal_dirty_metadata(handle, bh);
        brelse(bh);
 
        /* Mark unused entries in inode bitmap used */
-       ext4_debug("clear inode bitmap %#04x (+%ld)\n",
+       ext4_debug("clear inode bitmap %#04llx (+%llu)\n",
                   input->inode_bitmap, input->inode_bitmap - start);
        if (IS_ERR(bh = bclean(handle, sb, input->inode_bitmap))) {
                err = PTR_ERR(bh);
@@ -271,7 +311,6 @@ exit_journal:
        return err;
 }
 
-
 /*
  * Iterate through the groups which hold BACKUP superblock/GDT copies in an
  * ext4 filesystem.  The counters should be initialized to 1, 5, and 7 before
@@ -317,7 +356,7 @@ static int verify_reserved_gdb(struct super_block *sb,
                               struct buffer_head *primary)
 {
        const ext4_fsblk_t blk = primary->b_blocknr;
-       const unsigned long end = EXT4_SB(sb)->s_groups_count;
+       const ext4_group_t end = EXT4_SB(sb)->s_groups_count;
        unsigned three = 1;
        unsigned five = 5;
        unsigned seven = 7;
@@ -328,7 +367,7 @@ static int verify_reserved_gdb(struct super_block *sb,
        while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) {
                if (le32_to_cpu(*p++) !=
                    grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){
-                       ext4_warning(sb, __FUNCTION__,
+                       ext4_warning(sb, __func__,
                                     "reserved GDT %llu"
                                     " missing grp %d (%llu)",
                                     blk, grp,
@@ -384,7 +423,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
         */
        if (EXT4_SB(sb)->s_sbh->b_blocknr !=
            le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                        "won't resize using backup superblock at %llu",
                        (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
                return -EPERM;
@@ -408,7 +447,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
 
        data = (__le32 *)dind->b_data;
        if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "new group %u GDT block %llu not reserved",
                             input->group, gdblock);
                err = -EINVAL;
@@ -429,10 +468,10 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
                goto exit_dindj;
 
        n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *),
-                       GFP_KERNEL);
+                       GFP_NOFS);
        if (!n_group_desc) {
                err = -ENOMEM;
-               ext4_warning (sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                              "not enough memory for %lu groups", gdb_num + 1);
                goto exit_inode;
        }
@@ -462,8 +501,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
        EXT4_SB(sb)->s_gdb_count++;
        kfree(o_group_desc);
 
-       es->s_reserved_gdt_blocks =
-               cpu_to_le16(le16_to_cpu(es->s_reserved_gdt_blocks) - 1);
+       le16_add_cpu(&es->s_reserved_gdt_blocks, -1);
        ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
 
        return 0;
@@ -513,7 +551,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
        int res, i;
        int err;
 
-       primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_KERNEL);
+       primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_NOFS);
        if (!primary)
                return -ENOMEM;
 
@@ -525,13 +563,14 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
        }
 
        blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count;
-       data = (__le32 *)dind->b_data + EXT4_SB(sb)->s_gdb_count;
+       data = (__le32 *)dind->b_data + (EXT4_SB(sb)->s_gdb_count %
+                                        EXT4_ADDR_PER_BLOCK(sb));
        end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb);
 
        /* Get each reserved primary GDT block and verify it holds backups */
        for (res = 0; res < reserved_gdb; res++, blk++) {
                if (le32_to_cpu(*data) != blk) {
-                       ext4_warning(sb, __FUNCTION__,
+                       ext4_warning(sb, __func__,
                                     "reserved block %llu"
                                     " not at offset %ld",
                                     blk,
@@ -616,12 +655,12 @@ static void update_backups(struct super_block *sb,
                           int blk_off, char *data, int size)
 {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
-       const unsigned long last = sbi->s_groups_count;
+       const ext4_group_t last = sbi->s_groups_count;
        const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
        unsigned three = 1;
        unsigned five = 5;
        unsigned seven = 7;
-       unsigned group;
+       ext4_group_t group;
        int rest = sb->s_blocksize - size;
        handle_t *handle;
        int err = 0, err2;
@@ -675,8 +714,8 @@ static void update_backups(struct super_block *sb,
         */
 exit_err:
        if (err) {
-               ext4_warning(sb, __FUNCTION__,
-                            "can't update backup for group %d (err %d), "
+               ext4_warning(sb, __func__,
+                            "can't update backup for group %lu (err %d), "
                             "forcing fsck on next reboot", group, err);
                sbi->s_mount_state &= ~EXT4_VALID_FS;
                sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
@@ -715,36 +754,35 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 
        if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb,
                                        EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "Can't resize non-sparse filesystem further");
                return -EPERM;
        }
 
        if (ext4_blocks_count(es) + input->blocks_count <
            ext4_blocks_count(es)) {
-               ext4_warning(sb, __FUNCTION__, "blocks_count overflow\n");
+               ext4_warning(sb, __func__, "blocks_count overflow\n");
                return -EINVAL;
        }
 
        if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) <
            le32_to_cpu(es->s_inodes_count)) {
-               ext4_warning(sb, __FUNCTION__, "inodes_count overflow\n");
+               ext4_warning(sb, __func__, "inodes_count overflow\n");
                return -EINVAL;
        }
 
        if (reserved_gdb || gdb_off == 0) {
                if (!EXT4_HAS_COMPAT_FEATURE(sb,
                                             EXT4_FEATURE_COMPAT_RESIZE_INODE)){
-                       ext4_warning(sb, __FUNCTION__,
+                       ext4_warning(sb, __func__,
                                     "No reserved GDT blocks, can't resize");
                        return -EPERM;
                }
-               inode = iget(sb, EXT4_RESIZE_INO);
-               if (!inode || is_bad_inode(inode)) {
-                       ext4_warning(sb, __FUNCTION__,
+               inode = ext4_iget(sb, EXT4_RESIZE_INO);
+               if (IS_ERR(inode)) {
+                       ext4_warning(sb, __func__,
                                     "Error opening resize inode");
-                       iput(inode);
-                       return -ENOENT;
+                       return PTR_ERR(inode);
                }
        }
 
@@ -771,7 +809,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 
        lock_super(sb);
        if (input->group != sbi->s_groups_count) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "multiple resizers run on filesystem!");
                err = -EBUSY;
                goto exit_journal;
@@ -817,7 +855,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
         */
 
        /* Update group descriptor block for new group */
-       gdp = (struct ext4_group_desc *)primary->b_data + gdb_off;
+       gdp = (struct ext4_group_desc *)((char *)primary->b_data +
+                                        gdb_off * EXT4_DESC_SIZE(sb));
 
        ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
        ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
@@ -838,8 +877,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
         */
        ext4_blocks_count_set(es, ext4_blocks_count(es) +
                input->blocks_count);
-       es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) +
-               EXT4_INODES_PER_GROUP(sb));
+       le32_add_cpu(&es->s_inodes_count, EXT4_INODES_PER_GROUP(sb));
 
        /*
         * We need to protect s_groups_count against other CPUs seeing
@@ -912,7 +950,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
                      ext4_fsblk_t n_blocks_count)
 {
        ext4_fsblk_t o_blocks_count;
-       unsigned long o_groups_count;
+       ext4_group_t o_groups_count;
        ext4_grpblk_t last;
        ext4_grpblk_t add;
        struct buffer_head * bh;
@@ -938,13 +976,13 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
                        " too large to resize to %llu blocks safely\n",
                        sb->s_id, n_blocks_count);
                if (sizeof(sector_t) < 8)
-                       ext4_warning(sb, __FUNCTION__,
+                       ext4_warning(sb, __func__,
                        "CONFIG_LBD not enabled\n");
                return -EINVAL;
        }
 
        if (n_blocks_count < o_blocks_count) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "can't shrink FS - resize aborted");
                return -EBUSY;
        }
@@ -953,7 +991,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last);
 
        if (last == 0) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "need to use ext2online to resize further");
                return -EPERM;
        }
@@ -961,7 +999,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        add = EXT4_BLOCKS_PER_GROUP(sb) - last;
 
        if (o_blocks_count + add < o_blocks_count) {
-               ext4_warning(sb, __FUNCTION__, "blocks_count overflow");
+               ext4_warning(sb, __func__, "blocks_count overflow");
                return -EINVAL;
        }
 
@@ -969,7 +1007,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
                add = n_blocks_count - o_blocks_count;
 
        if (o_blocks_count + add < n_blocks_count)
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "will only finish group (%llu"
                             " blocks, %u new)",
                             o_blocks_count + add, add);
@@ -977,7 +1015,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        /* See if the device is actually as big as what was requested */
        bh = sb_bread(sb, o_blocks_count + add -1);
        if (!bh) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "can't read last block, resize aborted");
                return -ENOSPC;
        }
@@ -989,22 +1027,23 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        handle = ext4_journal_start_sb(sb, 3);
        if (IS_ERR(handle)) {
                err = PTR_ERR(handle);
-               ext4_warning(sb, __FUNCTION__, "error %d on journal start",err);
+               ext4_warning(sb, __func__, "error %d on journal start", err);
                goto exit_put;
        }
 
        lock_super(sb);
        if (o_blocks_count != ext4_blocks_count(es)) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "multiple resizers run on filesystem!");
                unlock_super(sb);
+               ext4_journal_stop(handle);
                err = -EBUSY;
                goto exit_put;
        }
 
        if ((err = ext4_journal_get_write_access(handle,
                                                 EXT4_SB(sb)->s_sbh))) {
-               ext4_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __func__,
                             "error %d on journal write access", err);
                unlock_super(sb);
                ext4_journal_stop(handle);
@@ -1014,7 +1053,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
        sb->s_dirt = 1;
        unlock_super(sb);
-       ext4_debug("freeing blocks %lu through %llu\n", o_blocks_count,
+       ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
                   o_blocks_count + add);
        ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks);
        ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,