Exemple #1
0
/******************************************************************************
 *
 * axfs_do_fill_data_ptrs
 *
 * Description:
 *      Fills the incore region descriptor with data from the onmedia version.
 *    Processes the region to populate virt_addr by mapping to the physical
 *    address or copying the data to RAM or if the data can be fetched later,
 *    it is set to NULL.
 *
 * Parameters:
 *    (IN) sb - pointer to the super block on media
 *
 *    (IN) region_desc_offset - offset to the region descriptor from the
 *                                beginning of filesystem
 *
 *    (OUT) iregion - pointer to the in RAM copy of the region descriptor
 *
 *    (IN) force_va - if true the region must have a valid virt_addr
 *
 * Returns:
 *    0 or error number
 *
 *****************************************************************************/
static int axfs_do_fill_data_ptrs(struct super_block *sb, u64 region_desc_offset, struct axfs_region_desc_incore *iregion, int force_va) {
	struct axfs_super_incore *sbi;
	struct axfs_region_desc_onmedia *oregion;
	unsigned long addr;
	void *mapped = NULL;
	int err;
	u64 size;
	u64 end;
	u64 struct_len = sizeof(*oregion);

	sbi = AXFS_SB(sb);

	oregion = (struct axfs_region_desc_onmedia *) axfs_fetch_data(sb,region_desc_offset,struct_len);

	iregion->fsoffset = be64_to_cpu(oregion->fsoffset);
	iregion->size = be64_to_cpu(oregion->size);
	iregion->compressed_size = be64_to_cpu(oregion->compressed_size);
	iregion->max_index = be64_to_cpu(oregion->max_index);
	iregion->table_byte_depth = oregion->table_byte_depth;
	iregion->incore = oregion->incore;
	vfree(oregion);

    if (iregion->size == 0)
		return 0;

	end = iregion->fsoffset + iregion->size;
	if( (AXFS_IS_REGION_XIP(sbi,iregion)) && !(force_va && (sbi->mmap_size < end)) ) {
		if(AXFS_PHYSADDR_IS_VALID(sbi) ) {
			addr = sbi->phys_start_addr;
			addr += (unsigned long)iregion->fsoffset;
			size = (sbi->mmap_size > (iregion->fsoffset + iregion->size)) ? iregion->size : (sbi->mmap_size - iregion->fsoffset);
			iregion->virt_addr = AXFS_REMAP(addr,size);
		} else {
			addr = sbi->virt_start_addr;
			addr += (unsigned long)iregion->fsoffset;
			iregion->virt_addr = (void *)addr;
		}
	} else if(AXFS_IS_REGION_INCORE(iregion) || AXFS_IS_REGION_COMPRESSED(iregion) || force_va) {
		iregion->virt_addr = vmalloc(iregion->size);
		if(!(iregion->virt_addr)) {
			err = -ENOMEM;
			goto out;
		}
		if(AXFS_IS_REGION_COMPRESSED(iregion)) {
			mapped = axfs_fetch_data(sb,iregion->fsoffset,iregion->compressed_size);
			err = axfs_uncompress_block(iregion->virt_addr,iregion->size,mapped,iregion->compressed_size);
			if (err)
				goto out;
		} else {
			mapped = axfs_fetch_data(sb,iregion->fsoffset,iregion->size);
			memcpy(iregion->virt_addr,mapped,iregion->size);
		}
	} else {
		iregion->virt_addr = NULL;
	}

	if(mapped)
		vfree(mapped);
	return 0;

out:
	if(mapped)
		vfree(mapped);
	if(iregion->virt_addr)
		vfree(iregion->virt_addr);
	return err;
}
Exemple #2
0
static int axfs_fill_region_data(struct super_block *sb,
                                 struct axfs_region_desc *region, int force)
{
    struct axfs_super *sbi = AXFS_SB(sb);
    unsigned long addr;
    void *buff = NULL;
    void *vaddr;
    int err = -ENOMEM;
    u64 size = region->size;
    u64 fsoffset = region->fsoffset;
    u64 end = fsoffset + size;
    u64 c_size = region->compressed_size;

    if (size == 0)
        return 0;

    if (axfs_is_region_incore(region))
        goto incore;

    if (axfs_is_region_compressed(region))
        goto incore;

    if (axfs_is_region_xip(sbi, region)) {
        if ((end > sbi->mmap_size) && (force))
            goto incore;
        addr = sbi->virt_start_addr;
        addr += (unsigned long)fsoffset;
        region->virt_addr = (void *)addr;
        return 0;
    }

    if (force)
        goto incore;

    region->virt_addr = NULL;
    return 0;

incore:
    region->virt_addr = vmalloc(size);
    if (!region->virt_addr)
        goto out;
    vaddr = region->virt_addr;

    if (axfs_is_region_compressed(region)) {
        buff = vmalloc(c_size);
        if (!buff)
            goto out;
        axfs_copy_metadata(sb, buff, fsoffset, c_size);
        err = axfs_uncompress_block(vaddr, size, buff, c_size);
        if (!err)
            goto out;
        vfree(buff);
    } else {
        axfs_copy_metadata(sb, vaddr, fsoffset, size);
    }

    return 0;

out:
    vfree(buff);
    vfree(region->virt_addr);
    return err;
}