/*
 * 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 "output_file.h"
#include "backed_block.h"
#include "allocate.h"
#include "ext4fixup.h"

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

#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;
    unsigned int i;

    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(int fd, 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(fd, 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(fd, (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;
}
