static int
nffs_restore_should_sweep_inode_entry(struct nffs_inode_entry *inode_entry,
                                      int *out_should_sweep)
{
    struct nffs_inode inode;
    int rc;

    /* Determine if the inode is a dummy.  Dummy inodes have a reference count
     * of 0.  If it is a dummy, increment its reference count back to 1 so that
     * it can be properly deleted.  The presence of a dummy inode during the
     * final sweep step indicates file system corruption.  If the inode is a
     * directory, all its children should have been migrated to the /lost+found
     * directory prior to this.
     */
    if (inode_entry->nie_refcnt == 0) {
        *out_should_sweep = 1;
        inode_entry->nie_refcnt++;
        return 0;
    }

    /* Determine if the inode has been deleted.  If an inode has no parent (and
     * it isn't the root directory), it has been deleted from the disk and
     * should be swept from the RAM representation.
     */
    if (inode_entry->nie_hash_entry.nhe_id != NFFS_ID_ROOT_DIR) {
        rc = nffs_inode_from_entry(&inode, inode_entry);
        if (rc != 0) {
            *out_should_sweep = 0;
            return rc;
        }

        if (inode.ni_parent == NULL) {
            *out_should_sweep = 1;
            return 0;
        }
    }

    /* If this is a file inode, verify that all of its constituent blocks are
     * present.
     */
    if (nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id)) {
        rc = nffs_restore_validate_block_chain(
                inode_entry->nie_last_block_entry);
        if (rc == FS_ECORRUPT) {
            *out_should_sweep = 1;
            return 0;
        } else if (rc != 0) {
            *out_should_sweep = 0;
            return rc;
        }
    }

    /* This is a valid inode; don't sweep it. */
    *out_should_sweep = 0;
    return 0;
}
static int
nffs_restore_should_sweep_inode_entry(struct nffs_inode_entry *inode_entry,
                                      int *out_should_sweep)
{
    struct nffs_inode inode;
    int rc;


    /*
     * if this inode was tagged to have a dummy block entry and the
     * flag is still set, that means we didn't find the block and so
     * should remove this inode and all associated blocks.
     */
    if (nffs_inode_getflags(inode_entry, NFFS_INODE_FLAG_DUMMYLSTBLK)) {
        *out_should_sweep = 1;
        /*nffs_inode_inc_refcnt(inode_entry);*/
        inode_entry->nie_refcnt = 1;
        assert(inode_entry->nie_refcnt >= 1);
        return 0;
    }

    /*
     * This inode was originally created to hold a block that was restored
     * before the owning inode. If the flag is still set, it means we never
     * restored the inode from disk and so this entry should be deleted.
     */
    if (nffs_inode_getflags(inode_entry, NFFS_INODE_FLAG_DUMMYINOBLK)) {
        *out_should_sweep = 2;
        inode_entry->nie_refcnt = 1;
        assert(inode_entry->nie_refcnt >= 1);
        return 0;
    }

    /*
     * Determine if the inode is a dummy. Dummy inodes have a flash
     * location set to LOC_NONE and should have a flag set for the reason.
     * The presence of a dummy inode during the final sweep step indicates
     * file system corruption.  It's assumed that directories have
     * previously migrated all children to /lost+found.
     */
    if (nffs_inode_is_dummy(inode_entry)) {
        *out_should_sweep = 3;
        nffs_inode_inc_refcnt(inode_entry);
        assert(inode_entry->nie_refcnt >= 1);
        return 0;
    }

    /* Determine if the inode has been deleted.  If an inode has no parent (and
     * it isn't the root directory), it has been deleted from the disk and
     * should be swept from the RAM representation.
     */
    if (inode_entry->nie_hash_entry.nhe_id != NFFS_ID_ROOT_DIR) {
        rc = nffs_inode_from_entry(&inode, inode_entry);
        if (rc != 0 && rc != FS_ENOENT) {
            *out_should_sweep = 0;
            return rc;
        }
        if (inode.ni_parent == NULL) {
            *out_should_sweep = 4;
            return 0;
        }
    }

    /*
     * If this inode has been marked as deleted, we can unlink it here.
     *
     * XXX Note that the record of a deletion could be lost if garbage
     * collection erases the delete but leaves inode updates on other
     * partitions which can then be restored.
     */
    if (nffs_inode_getflags(inode_entry, NFFS_INODE_FLAG_DELETED)) {
        rc = nffs_inode_from_entry(&inode, inode_entry);
        if (rc != 0) {
            *out_should_sweep = 0;
            return rc;
        }
        *out_should_sweep = 5;
    }

    /* If this is a file inode, verify that all of its constituent blocks are
     * present.
     */
    if (nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id)) {
        rc = nffs_restore_validate_block_chain(
                inode_entry->nie_last_block_entry);
        if (rc == FS_ECORRUPT) {
            *out_should_sweep = 6;
            return 0;
        } else if (rc == FS_ENOENT) {
            *out_should_sweep = 7;
            return 0;
        } else if (rc != 0) {
            *out_should_sweep = 0;
            return rc;
        }
    }

    /* This is a valid inode; don't sweep it. */
    *out_should_sweep = 0;
    return 0;
}