/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "ext4_utils.h"
#include "make_ext4fs.h"
#include "ext4_extents.h"
#include "allocate.h"
#include "ext4fixup.h"

#include <sparse/sparse.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>

#ifndef USE_MINGW
#include <sys/mman.h>
#endif

#if defined(__APPLE__) && defined(__MACH__)
#define lseek64 lseek
#define off64_t off_t
#endif

/* The inode block count for a file/directory is in units of 512 byte blocks,
 * _NOT_ the filesystem block size!
 */
#define INODE_BLOCK_SIZE 512

#define MAX_EXT4_BLOCK_SIZE 4096

/* The two modes the recurse_dir() can be in */
#define SANITY_CHECK_PASS 1
#define MARK_INODE_NUMS   2
#define UPDATE_INODE_NUMS 3

/* Magic numbers to indicate what state the update process is in */
#define MAGIC_STATE_MARKING_INUMS  0x7000151515565512ll
#define MAGIC_STATE_UPDATING_INUMS 0x6121131211735123ll
#define MAGIC_STATE_UPDATING_SB    0x15e1715151558477ll

/* Internal state variables corresponding to the magic numbers */
#define STATE_UNSET          0
#define STATE_MARKING_INUMS  1
#define STATE_UPDATING_INUMS 2
#define STATE_UPDATING_SB    3

/* Used for automated testing of this programs ability to stop and be restarted wthout error */
static int bail_phase = 0;
static int bail_loc = 0;
static int bail_count = 0;
static int count = 0;

/* global flags */
static int verbose = 0;
static int no_write = 0;

static int new_inodes_per_group = 0;

static int no_write_fixup_state = 0;

static int compute_new_inum(unsigned int old_inum)
{
    unsigned int group, offset;

    group = (old_inum - 1) / info.inodes_per_group;
    offset = (old_inum -1) % info.inodes_per_group;

    return (group * new_inodes_per_group) + offset + 1;
}

/* Function to read the primary superblock */
static void read_sb(int fd, struct ext4_super_block *sb)
{
    off64_t ret;

    ret = lseek64(fd, 1024, SEEK_SET);
    if (ret < 0)
        critical_error_errno("failed to seek to superblock");

    ret = read(fd, sb, sizeof(*sb));
    if (ret < 0)
        critical_error_errno("failed to read superblock");
    if (ret != sizeof(*sb))
        critical_error("failed to read all of superblock");
}

/* Function to write a primary or backup superblock at a given offset */
static void write_sb(int fd, unsigned long long offset, struct ext4_super_block *sb)
{
    off64_t ret;

    if (no_write) {
        return;
    }

    ret = lseek64(fd, offset, SEEK_SET);
    if (ret < 0)
        critical_error_errno("failed to seek to superblock");

    ret = write(fd, sb, sizeof(*sb));
    if (ret < 0)
        critical_error_errno("failed to write superblock");
    if (ret != sizeof(*sb))
        critical_error("failed to write all of superblock");
}

static int get_fs_fixup_state(int fd)
{
    unsigned long long magic;
    int ret, len;

    if (no_write) {
        return no_write_fixup_state;
    }

    lseek64(fd, 0, SEEK_SET);
    len = read(fd, &magic, sizeof(magic));
    if (len != sizeof(magic)) {
        critical_error("cannot read fixup_state\n");
    }

    switch (magic) {
        case MAGIC_STATE_MARKING_INUMS:
            ret = STATE_MARKING_INUMS;
            break;
        case MAGIC_STATE_UPDATING_INUMS:
            ret = STATE_UPDATING_INUMS;
            break;
        case MAGIC_STATE_UPDATING_SB:
            ret = STATE_UPDATING_SB;
            break;
        default:
            ret = STATE_UNSET;
    }
    return ret;
}

static int set_fs_fixup_state(int fd, int state)
{
    unsigned long long magic;
    struct ext4_super_block sb;
    int len;

    if (no_write) {
        no_write_fixup_state = state;
        return 0;
    }

    switch (state) {
        case STATE_MARKING_INUMS:
            magic = MAGIC_STATE_MARKING_INUMS;
            break;
        case STATE_UPDATING_INUMS:
            magic = MAGIC_STATE_UPDATING_INUMS;
            break;
        case STATE_UPDATING_SB:
            magic = MAGIC_STATE_UPDATING_SB;
            break;
        case STATE_UNSET:
        default:
            magic = 0ll;
            break;
    }

    lseek64(fd, 0, SEEK_SET);
    len = write(fd, &magic, sizeof(magic));
    if (len != sizeof(magic)) {
        critical_error("cannot write fixup_state\n");
    }

    read_sb(fd, &sb);
    if (magic) {
        /* If we are in the process of updating the filesystem, make it unmountable */
        sb.s_desc_size |= 1;
    } else {
        /* we are done, so make the filesystem mountable again */
        sb.s_desc_size &= ~1;
    }
    write_sb(fd, 1024, &sb);

    return 0;
}

static int read_ext(int fd)
{
    off64_t ret;
    struct ext4_super_block sb;

    read_sb(fd, &sb);

    ext4_parse_sb(&sb);

    if (info.feat_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) {
        critical_error("Filesystem needs recovery first, mount and unmount to do that\n");
    }

    /* Clear the low bit which is set while this tool is in progress.
     * If the tool crashes, it will still be set when we restart.
     * The low bit is set to make the filesystem unmountable while
     * it is being fixed up.  Also allow 0, which means the old ext2
     * size is in use.
     */
    if (((sb.s_desc_size & ~1) != sizeof(struct ext2_group_desc)) &&
        ((sb.s_desc_size & ~1) != 0))
        critical_error("error: bg_desc_size != sizeof(struct ext2_group_desc)\n");

    ret = lseek64(fd, info.len, SEEK_SET);
    if (ret < 0)
        critical_error_errno("failed to seek to end of input image");

    ret = lseek64(fd, info.block_size * (aux_info.first_data_block + 1), SEEK_SET);
    if (ret < 0)
        critical_error_errno("failed to seek to block group descriptors");

    ret = read(fd, aux_info.bg_desc, info.block_size * aux_info.bg_desc_blocks);
    if (ret < 0)
        critical_error_errno("failed to read block group descriptors");
    if (ret != (int)info.block_size * (int)aux_info.bg_desc_blocks)
        critical_error("failed to read all of block group descriptors");

    if (verbose) {
        printf("Found filesystem with parameters:\n");
        printf("    Size: %llu\n", info.len);
        printf("    Block size: %d\n", info.block_size);
        printf("    Blocks per group: %d\n", info.blocks_per_group);
        printf("    Inodes per group: %d\n", info.inodes_per_group);
        printf("    Inode size: %d\n", info.inode_size);
        printf("    Label: %s\n", info.label);
        printf("    Blocks: %llu\n", aux_info.len_blocks);
        printf("    Block groups: %d\n", aux_info.groups);
        printf("    Reserved block group size: %d\n", info.bg_desc_reserve_blocks);
        printf("    Used %d/%d inodes and %d/%d blocks\n",
                aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count,
                aux_info.sb->s_inodes_count,
                aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo,
                aux_info.sb->s_blocks_count_lo);
    }

    return 0;
}

static int read_inode(int fd, unsigned int inum, struct ext4_inode *inode)
{
    unsigned int bg_num, bg_offset;
    off64_t inode_offset;
    int len;

    bg_num = (inum-1) / info.inodes_per_group;
    bg_offset = (inum-1) % info.inodes_per_group;

    inode_offset = ((unsigned long long)aux_info.bg_desc[bg_num].bg_inode_table * info.block_size) +
                    (bg_offset * info.inode_size);

    if (lseek64(fd, inode_offset, SEEK_SET) < 0) {
        critical_error_errno("failed to seek to inode %d\n", inum);
    }

    len=read(fd, inode, sizeof(*inode));
    if (len != sizeof(*inode)) {
        critical_error_errno("failed to read inode %d\n", inum);
    }

    return 0;
}

static int read_block(int fd, unsigned long long block_num, void *block)
{
    off64_t off;
    unsigned int len;

    off = block_num * info.block_size;

    if (lseek64(fd, off, SEEK_SET) , 0) {
        critical_error_errno("failed to seek to block %lld\n", block_num);
    }

    len=read(fd, block, info.block_size);
    if (len != info.block_size) {
        critical_error_errno("failed to read block %lld\n", block_num);
    }

    return 0;
}

static int write_block(int fd, unsigned long long block_num, void *block)
{
    off64_t off;
    unsigned int len;

    if (no_write) {
        return 0;
    }

    off = block_num * info.block_size;

    if (lseek64(fd, off, SEEK_SET) < 0) {
        critical_error_errno("failed to seek to block %lld\n", block_num);
    }

    len=write(fd, block, info.block_size);
    if (len != info.block_size) {
        critical_error_errno("failed to write block %lld\n", block_num);
    }

    return 0;
}

static int bitmap_get_bit(u8 *bitmap, u32 bit)
{
        if (bitmap[bit / 8] & (1 << (bit % 8)))
                return 1;

        return 0;
}

static void bitmap_clear_bit(u8 *bitmap, u32 bit)
{
        bitmap[bit / 8] &= ~(1 << (bit % 8));

        return;
}

static void check_inode_bitmap(int fd, unsigned int bg_num)
{
    unsigned int inode_bitmap_block_num;
    unsigned char block[MAX_EXT4_BLOCK_SIZE];
    int i, bitmap_updated = 0;

    /* Using the bg_num, aux_info.bg_desc[], info.inodes_per_group and
     * new_inodes_per_group, retrieve the inode bitmap, and make sure
     * the bits between the old and new size are clear
     */
    inode_bitmap_block_num = aux_info.bg_desc[bg_num].bg_inode_bitmap;

    read_block(fd, inode_bitmap_block_num, block);

    for (i = info.inodes_per_group; i < new_inodes_per_group; i++) {
        if (bitmap_get_bit(block, i)) {
            bitmap_clear_bit(block, i);
            bitmap_updated = 1;
        }
    }

    if (bitmap_updated) {
        if (verbose) {
            printf("Warning: updated inode bitmap for block group %d\n", bg_num);
        }
        write_block(fd, inode_bitmap_block_num, block);
    }

    return;
}

/* Update the superblock and bgdesc of the specified block group */
static int update_superblocks_and_bg_desc(int fd, int state)
{
    off64_t ret;
    struct ext4_super_block sb;
    unsigned int num_block_groups, total_new_inodes;
    unsigned int i;


    read_sb(fd, &sb);

    /* Compute how many more inodes are now available */
    num_block_groups = DIV_ROUND_UP(aux_info.len_blocks, info.blocks_per_group);
    total_new_inodes = num_block_groups * (new_inodes_per_group - sb.s_inodes_per_group);

    if (verbose) {
        printf("created %d additional inodes\n", total_new_inodes);
    }

    /* Update the free inodes count in each block group descriptor */
    for (i = 0; i < num_block_groups; i++) {
       if (state == STATE_UPDATING_SB) {
           aux_info.bg_desc[i].bg_free_inodes_count += (new_inodes_per_group - sb.s_inodes_per_group);
       }
       check_inode_bitmap(fd, i);
    }

    /* First some sanity checks */
    if ((sb.s_inodes_count + total_new_inodes) != (new_inodes_per_group * num_block_groups)) {
        critical_error("Failed sanity check on new inode count\n");
    }
    if (new_inodes_per_group % (info.block_size/info.inode_size)) {
        critical_error("Failed sanity check on new inode per group alignment\n");
    }

    /* Update the free inodes count in the superblock */
    sb.s_inodes_count += total_new_inodes;
    sb.s_free_inodes_count += total_new_inodes;
    sb.s_inodes_per_group = new_inodes_per_group;

    for (i = 0; i < aux_info.groups; i++) {
        if (ext4_bg_has_super_block(i)) {
            unsigned int sb_offset;

            if (i == 0) {
              /* The first superblock is offset by 1K to leave room for boot sectors */
              sb_offset = 1024;
            } else {
              sb_offset = 0;
            }

            sb.s_block_group_nr = i;
            /* Don't write out the backup superblocks with the bit set in the s_desc_size
             * which prevents the filesystem from mounting.  The bit for the primary
             * superblock will be cleared on the final call to set_fs_fixup_state() */
            if (i != 0) {
                sb.s_desc_size &= ~1;
            }

            write_sb(fd, (unsigned long long)i * info.blocks_per_group * info.block_size + sb_offset, &sb);

            ret = lseek64(fd, ((unsigned long long)i * info.blocks_per_group * info.block_size) +
                              (info.block_size * (aux_info.first_data_block + 1)), SEEK_SET);
            if (ret < 0)
                critical_error_errno("failed to seek to block group descriptors");

            if (!no_write) {
                ret = write(fd, aux_info.bg_desc, info.block_size * aux_info.bg_desc_blocks);
                if (ret < 0)
                    critical_error_errno("failed to write block group descriptors");
                if (ret != (int)info.block_size * (int)aux_info.bg_desc_blocks)
                    critical_error("failed to write all of block group descriptors");
            }
        }
        if ((bail_phase == 4) && ((unsigned int)bail_count == i)) {
            critical_error("bailing at phase 4\n");
        }
    }

    return 0;
}


static int get_direct_blocks(struct ext4_inode *inode, unsigned long long *block_list,
                                                       unsigned int *count)
{
    unsigned int i = 0;
    unsigned int ret = 0;
    unsigned int sectors_per_block;

    sectors_per_block = info.block_size / INODE_BLOCK_SIZE;
    while ((i < (inode->i_blocks_lo / sectors_per_block)) && (i < EXT4_NDIR_BLOCKS)) {
        block_list[i] = inode->i_block[i];
        i++;
    }

    *count += i;

    if ((inode->i_blocks_lo / sectors_per_block) > EXT4_NDIR_BLOCKS) {
        ret = 1;
    }

    return ret;
}

static int get_indirect_blocks(int fd, struct ext4_inode *inode,
                               unsigned long long *block_list, unsigned int *count)
{
    unsigned int i;
    unsigned int *indirect_block;
    unsigned int sectors_per_block;

    sectors_per_block = info.block_size / INODE_BLOCK_SIZE;

    indirect_block = (unsigned int *)malloc(info.block_size);
    if (indirect_block == 0) {
        critical_error("failed to allocate memory for indirect_block\n");
    }

    read_block(fd, inode->i_block[EXT4_NDIR_BLOCKS], indirect_block);

    for(i = 0; i < (inode->i_blocks_lo / sectors_per_block - EXT4_NDIR_BLOCKS); i++) {
       block_list[EXT4_NDIR_BLOCKS+i] = indirect_block[i];
    }

    *count += i;

    free(indirect_block);

    return 0;
}

static int get_block_list_indirect(int fd, struct ext4_inode *inode, unsigned long long *block_list)
{
    unsigned int count=0;

    if (get_direct_blocks(inode, block_list, &count)) {
        get_indirect_blocks(fd, inode, block_list, &count);
    }

    return count;
}

static int get_extent_ents(struct ext4_extent_header *ext_hdr, unsigned long long *block_list)
{
    int i, j;
    struct ext4_extent *extent;
    off64_t fs_block_num;

    if (ext_hdr->eh_depth != 0) {
        critical_error("get_extent_ents called with eh_depth != 0\n");
    }

    /* The extent entries immediately follow the header, so add 1 to the pointer
     * and cast it to an extent pointer.
     */
    extent = (struct ext4_extent *)(ext_hdr + 1);

    for (i = 0; i < ext_hdr->eh_entries; i++) {
         fs_block_num = ((off64_t)extent->ee_start_hi << 32) | extent->ee_start_lo;
         for (j = 0; j < extent->ee_len; j++) {
             block_list[extent->ee_block+j] = fs_block_num+j;
         }
         extent++;
    }

    return 0;
}

static int get_extent_idx(int fd, struct ext4_extent_header *ext_hdr, unsigned long long *block_list)
{
    int i;
    struct ext4_extent_idx *extent_idx;
    struct ext4_extent_header *tmp_ext_hdr;
    off64_t fs_block_num;
    unsigned char block[MAX_EXT4_BLOCK_SIZE];

    /* Sanity check */
    if (ext_hdr->eh_depth == 0) {
        critical_error("get_extent_idx called with eh_depth == 0\n");
    }

    /* The extent entries immediately follow the header, so add 1 to the pointer
     * and cast it to an extent pointer.
     */
    extent_idx = (struct ext4_extent_idx *)(ext_hdr + 1);

    for (i = 0; i < ext_hdr->eh_entries; i++) {
         fs_block_num = ((off64_t)extent_idx->ei_leaf_hi << 32) | extent_idx->ei_leaf_lo;
         read_block(fd, fs_block_num, block);
         tmp_ext_hdr = (struct ext4_extent_header *)block;

         if (tmp_ext_hdr->eh_depth == 0) {
             get_extent_ents(tmp_ext_hdr, block_list); /* leaf node, fill in block_list */
         } else {
             get_extent_idx(fd, tmp_ext_hdr, block_list); /* recurse down the tree */
         }
    }

    return 0;
}

static int get_block_list_extents(int fd, struct ext4_inode *inode, unsigned long long *block_list)
{
    struct ext4_extent_header *extent_hdr;

    extent_hdr = (struct ext4_extent_header *)inode->i_block;

    if (extent_hdr->eh_magic != EXT4_EXT_MAGIC) {
        critical_error("extent header has unexpected magic value 0x%4.4x\n",
                       extent_hdr->eh_magic);
    }

    if (extent_hdr->eh_depth == 0) {
         get_extent_ents((struct ext4_extent_header *)inode->i_block, block_list);
         return 0;
    }

    get_extent_idx(fd, (struct ext4_extent_header *)inode->i_block, block_list);

    return 0;
}

static int is_entry_dir(int fd, struct ext4_dir_entry_2 *dirp, int pass)
{
    struct ext4_inode inode;
    int ret = 0;

    if (dirp->file_type == EXT4_FT_DIR) {
        ret = 1;
    } else if (dirp->file_type == EXT4_FT_UNKNOWN) {
        /* Somebody was too lazy to fill in the dir entry,
         * so we have to go fetch it from the inode. Grrr.
         */
        /* if UPDATE_INODE_NUMS pass and the inode high bit is not
         * set return false so we don't recurse down the tree that is
         * already updated.  Otherwise, fetch inode, and return answer.
         */
        if ((pass == UPDATE_INODE_NUMS) && !(dirp->inode & 0x80000000)) {
            ret = 0;
        } else {
            read_inode(fd, (dirp->inode & 0x7fffffff), &inode);
            if (S_ISDIR(inode.i_mode)) {
                ret = 1;
            }
        }
    }

    return ret;
}

static int recurse_dir(int fd, struct ext4_inode *inode, char *dirbuf, int dirsize, int mode)
{
    unsigned long long *block_list;
    unsigned int num_blocks;
    struct ext4_dir_entry_2 *dirp, *prev_dirp = 0;
    char name[256];
    unsigned int i, leftover_space, is_dir;
    struct ext4_inode tmp_inode;
    int tmp_dirsize;
    char *tmp_dirbuf;

    switch (mode) {
        case SANITY_CHECK_PASS:
        case MARK_INODE_NUMS:
        case UPDATE_INODE_NUMS:
            break;
        default:
            critical_error("recurse_dir() called witn unknown mode!\n");
    }

    if (dirsize % info.block_size) {
        critical_error("dirsize %d not a multiple of block_size %d.  This is unexpected!\n",
                dirsize, info.block_size);
    }

    num_blocks = dirsize / info.block_size;

    block_list = malloc((num_blocks + 1) * sizeof(*block_list));
    if (block_list == 0) {
        critical_error("failed to allocate memory for block_list\n");
    }

    if (inode->i_flags & EXT4_EXTENTS_FL) {
        get_block_list_extents(fd, inode, block_list);
    } else {
        /* A directory that requires doubly or triply indirect blocks in huge indeed,
         * and will almost certainly not exist, especially since make_ext4fs only creates
         * directories with extents, and the kernel will too, but check to make sure the
         * directory is not that big and give an error if so.  Our limit is 12 direct blocks,
         * plus block_size/4 singly indirect blocks, which for a filesystem with 4K blocks
         * is a directory 1036 blocks long, or 4,243,456 bytes long!  Assuming an average
         * filename length of 20 (which I think is generous) thats 20 + 8 bytes overhead
         * per entry, or 151,552 entries in the directory!
         */
        if (num_blocks > (info.block_size / 4 + EXT4_NDIR_BLOCKS)) {
            critical_error("Non-extent based directory is too big!\n");
        }
        get_block_list_indirect(fd, inode, block_list);
    }

    /* Read in all the blocks for this directory */
    for (i = 0; i < num_blocks; i++) {
        read_block(fd, block_list[i], dirbuf + (i * info.block_size));
    }

    dirp = (struct ext4_dir_entry_2 *)dirbuf;
    while (dirp < (struct ext4_dir_entry_2 *)(dirbuf + dirsize)) {
        count++;
        leftover_space = (char *)(dirbuf + dirsize) - (char *)dirp;
        if (((mode == SANITY_CHECK_PASS) || (mode == UPDATE_INODE_NUMS)) &&
            (leftover_space <= 8) && prev_dirp) {
            /* This is a bug in an older version of make_ext4fs, where it
             * didn't properly include the rest of the block in rec_len.
             * Update rec_len on the previous entry to include the rest of
             * the block and exit the loop.
             */
            if (verbose) {
                printf("fixing up short rec_len for diretory entry for %s\n", name);
            }
            prev_dirp->rec_len += leftover_space;
            break;
        }

        if (dirp->inode == 0) {
            /* This is the last entry in the directory */
            break;
        }

        strncpy(name, dirp->name, dirp->name_len);
        name[dirp->name_len]='\0';

        /* Only recurse on pass UPDATE_INODE_NUMS if the high bit is set.
         * Otherwise, this inode entry has already been updated
         * and we'll do the wrong thing.  Also don't recurse on . or ..,
         * and certainly not on non-directories!
         */
        /* Hrm, looks like filesystems made by fastboot on stingray set the file_type
         * flag, but the lost+found directory has the type set to Unknown, which
         * seems to imply I need to read the inode and get it.
         */
        is_dir = is_entry_dir(fd, dirp, mode);
        if ( is_dir && (strcmp(name, ".") && strcmp(name, "..")) &&
            ((mode == SANITY_CHECK_PASS) || (mode == MARK_INODE_NUMS) ||
              ((mode == UPDATE_INODE_NUMS) && (dirp->inode & 0x80000000))) ) {
            /* A directory!  Recurse! */
            read_inode(fd, dirp->inode & 0x7fffffff, &tmp_inode);

            if (!S_ISDIR(tmp_inode.i_mode)) {
                critical_error("inode %d for name %s does not point to a directory\n",
                        dirp->inode & 0x7fffffff, name);
            }
            if (verbose) {
                printf("inode %d %s use extents\n", dirp->inode & 0x7fffffff,
                       (tmp_inode.i_flags & EXT4_EXTENTS_FL) ? "does" : "does not");
            }

            tmp_dirsize = tmp_inode.i_blocks_lo * INODE_BLOCK_SIZE;
            if (verbose) {
                printf("dir size = %d bytes\n", tmp_dirsize);
            }

            tmp_dirbuf = malloc(tmp_dirsize);
            if (tmp_dirbuf == 0) {
                critical_error("failed to allocate memory for tmp_dirbuf\n");
            }

            recurse_dir(fd, &tmp_inode, tmp_dirbuf, tmp_dirsize, mode);

            free(tmp_dirbuf);
        }

        if (verbose) {
            if (is_dir) {
                printf("Directory %s\n", name);
            } else {
                printf("Non-directory %s\n", name);
            }
        }

        /* Process entry based on current mode.  Either set high bit or change inode number */
        if (mode == MARK_INODE_NUMS) {
            dirp->inode |= 0x80000000;
        } else if (mode == UPDATE_INODE_NUMS) {
            if (dirp->inode & 0x80000000) {
                dirp->inode = compute_new_inum(dirp->inode & 0x7fffffff);
            }
        }

        if ((bail_phase == mode) && (bail_loc == 1) && (bail_count == count)) {
            critical_error("Bailing at phase %d, loc 1 and count %d\n", mode, count);
        }

        /* Point dirp at the next entry */
        prev_dirp = dirp;
        dirp = (struct ext4_dir_entry_2*)((char *)dirp + dirp->rec_len);
    }

    /* Write out all the blocks for this directory */
    for (i = 0; i < num_blocks; i++) {
        write_block(fd, block_list[i], dirbuf + (i * info.block_size));
        if ((bail_phase == mode) && (bail_loc == 2) && (bail_count <= count)) {
            critical_error("Bailing at phase %d, loc 2 and count %d\n", mode, count);
        }
    }

    free(block_list);

    return 0;
}

int ext4fixup(char *fsdev)
{
    return ext4fixup_internal(fsdev, 0, 0, 0, 0, 0);
}

int ext4fixup_internal(char *fsdev, int v_flag, int n_flag,
                       int stop_phase, int stop_loc, int stop_count)
{
    int fd;
    struct ext4_inode root_inode;
    unsigned int dirsize;
    char *dirbuf;

    if (setjmp(setjmp_env))
        return EXIT_FAILURE; /* Handle a call to longjmp() */

    verbose = v_flag;
    no_write = n_flag;

    bail_phase = stop_phase;
    bail_loc = stop_loc;
    bail_count = stop_count;

    fd = open(fsdev, O_RDWR);

    if (fd < 0)
        critical_error_errno("failed to open filesystem image");

    read_ext(fd);

    if ((info.feat_incompat & EXT4_FEATURE_INCOMPAT_FILETYPE) == 0) {
        critical_error("Expected filesystem to have filetype flag set\n");
    }

#if 0 // If we have to fix the directory rec_len issue, we can't use this check
    /* Check to see if the inodes/group is copacetic */
    if (info.inodes_per_blockgroup % (info.block_size/info.inode_size) == 0) {
             /* This filesystem has either already been updated, or was
              * made correctly.
              */
             if (verbose) {
                 printf("%s: filesystem correct, no work to do\n", me);
             }
             exit(0);
    }
#endif

    /* Compute what the new value of inodes_per_blockgroup will be when we're done */
    new_inodes_per_group=ALIGN(info.inodes_per_group,(info.block_size/info.inode_size));

    read_inode(fd, EXT4_ROOT_INO, &root_inode);

    if (!S_ISDIR(root_inode.i_mode)) {
        critical_error("root inode %d does not point to a directory\n", EXT4_ROOT_INO);
    }
    if (verbose) {
        printf("inode %d %s use extents\n", EXT4_ROOT_INO,
               (root_inode.i_flags & EXT4_EXTENTS_FL) ? "does" : "does not");
    }

    dirsize = root_inode.i_blocks_lo * INODE_BLOCK_SIZE;
    if (verbose) {
        printf("root dir size = %d bytes\n", dirsize);
    }

    dirbuf = malloc(dirsize);
    if (dirbuf == 0) {
        critical_error("failed to allocate memory for dirbuf\n");
    }

    /* Perform a sanity check pass first, try to catch any errors that will occur
     * before we actually change anything, so we don't leave a filesystem in a
     * corrupted, unrecoverable state.  Set no_write, make it quiet, and do a recurse
     * pass and a update_superblock pass.  Set flags back to requested state when done.
     * Only perform sanity check if the state is unset.  If the state is _NOT_ unset,
     * then the tool has already been run and interrupted, and it presumably ran and
     * passed sanity checked before it got interrupted.  It is _NOT_ safe to run sanity
     * check if state is unset because it assumes inodes are to be computed using the
     * old inodes/group, but some inode numbers may be updated to the new number.
     */
    if (get_fs_fixup_state(fd) == STATE_UNSET) {
        verbose = 0;
        no_write = 1;
        recurse_dir(fd, &root_inode, dirbuf, dirsize, SANITY_CHECK_PASS);
        update_superblocks_and_bg_desc(fd, STATE_UNSET);
        verbose = v_flag;
        no_write = n_flag;

        set_fs_fixup_state(fd, STATE_MARKING_INUMS);
    }

    if (get_fs_fixup_state(fd) == STATE_MARKING_INUMS) {
        count = 0; /* Reset debugging counter */
        if (!recurse_dir(fd, &root_inode, dirbuf, dirsize, MARK_INODE_NUMS)) {
            set_fs_fixup_state(fd, STATE_UPDATING_INUMS);
        }
    }

    if (get_fs_fixup_state(fd) == STATE_UPDATING_INUMS) {
        count = 0; /* Reset debugging counter */
        if (!recurse_dir(fd, &root_inode, dirbuf, dirsize, UPDATE_INODE_NUMS)) {
            set_fs_fixup_state(fd, STATE_UPDATING_SB);
        }
    }

    if (get_fs_fixup_state(fd) == STATE_UPDATING_SB) {
        /* set the new inodes/blockgroup number,
         * and sets the state back to 0.
         */
        if (!update_superblocks_and_bg_desc(fd, STATE_UPDATING_SB)) {
            set_fs_fixup_state(fd, STATE_UNSET);
        }
    }

    close(fd);

    return 0;
}
