/*
 * 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 <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;
    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;
}
