コード例 #1
0
ファイル: fsw_lib.c プロジェクト: jeppeter/vbox
fsw_status_t fsw_memdup(void **dest_out, void *src, int len)
{
    fsw_status_t status;

    status = fsw_alloc(len, dest_out);
    if (status)
        return status;
    fsw_memcpy(*dest_out, src, len);
    return FSW_SUCCESS;
}
コード例 #2
0
ファイル: fsw_lib.c プロジェクト: jeppeter/vbox
fsw_status_t fsw_alloc_zero(int len, void **ptr_out)
{
    fsw_status_t status;

    status = fsw_alloc(len, ptr_out);
    if (status)
        return status;
    fsw_memzero(*ptr_out, len);
    return FSW_SUCCESS;
}
コード例 #3
0
ファイル: fsw_posix.c プロジェクト: JackieXie168/rEFIt
struct fsw_posix_dir * fsw_posix_opendir(struct fsw_posix_volume *pvol, const char *path)
{
    fsw_status_t        status;
    struct fsw_posix_dir *dir;
    
    // allocate file structure
    status = fsw_alloc(sizeof(struct fsw_posix_dir), &dir);
    if (status)
        return NULL;
    dir->pvol = pvol;
    
    // open the directory
    status = fsw_posix_open_dno(pvol, path, FSW_DNODE_TYPE_DIR, &dir->shand);
    if (status) {
        fprintf(stderr, "fsw_posix_opendir: open_dno returned %d\n", status);
        fsw_free(dir);
        return NULL;
    }
    
    return dir;
}
コード例 #4
0
ファイル: fsw_lib.c プロジェクト: jeppeter/vbox
fsw_status_t fsw_strdup_coerce(struct fsw_string *dest, int type, struct fsw_string *src)
{
    fsw_status_t    status;

    if (src->type == FSW_STRING_TYPE_EMPTY || src->len == 0) {
        dest->type = type;
        dest->size = dest->len = 0;
        dest->data = NULL;
        return FSW_SUCCESS;
    }

    if (src->type == type) {
        dest->type = type;
        dest->len  = src->len;
        dest->size = src->size;
        status = fsw_alloc(dest->size, &dest->data);
        if (status)
            return status;

        fsw_memcpy(dest->data, src->data, dest->size);
        return FSW_SUCCESS;
    }

    // dispatch to type-specific functions
    #define STRCOERCE_DISPATCH(type1, type2) \
      if (src->type == FSW_STRING_TYPE_##type1 && type == FSW_STRING_TYPE_##type2) \
        return fsw_strcoerce_##type1##_##type2(src->data, src->len, dest);
    STRCOERCE_DISPATCH(UTF8, ISO88591);
    STRCOERCE_DISPATCH(UTF16, ISO88591);
    STRCOERCE_DISPATCH(UTF16_SWAPPED, ISO88591);
    STRCOERCE_DISPATCH(ISO88591, UTF8);
    STRCOERCE_DISPATCH(UTF16, UTF8);
    STRCOERCE_DISPATCH(UTF16_SWAPPED, UTF8);
    STRCOERCE_DISPATCH(ISO88591, UTF16);
    STRCOERCE_DISPATCH(UTF8, UTF16);
    STRCOERCE_DISPATCH(UTF16_SWAPPED, UTF16);

    return FSW_UNSUPPORTED;
}
コード例 #5
0
ファイル: fsw_posix.c プロジェクト: JackieXie168/rEFIt
struct fsw_posix_file * fsw_posix_open(struct fsw_posix_volume *pvol, const char *path, int flags, mode_t mode)
{
    fsw_status_t        status;
    struct fsw_posix_file *file;
    
    // TODO: check flags for unwanted values
    
    // allocate file structure
    status = fsw_alloc(sizeof(struct fsw_posix_file), &file);
    if (status)
        return NULL;
    file->pvol = pvol;
    
    // open the file
    status = fsw_posix_open_dno(pvol, path, FSW_DNODE_TYPE_FILE, &file->shand);
    if (status) {
        fprintf(stderr, "fsw_posix_open: open_dno returned %d\n", status);
        fsw_free(file);
        return NULL;
    }
    
    return file;
}
コード例 #6
0
fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32 cache_level, void **buffer_out)
{
    fsw_status_t    status;
    fsw_u32         i, discard_level, new_bcache_size;
    struct fsw_blockcache *new_bcache;

    /// @todo allow the host driver to do its own caching; just call through if
    //  the appropriate function pointers are set

    if (cache_level > MAX_CACHE_LEVEL)
        cache_level = MAX_CACHE_LEVEL;

    // check block cache
    for (i = 0; i < vol->bcache_size; i++) {
        if (vol->bcache[i].phys_bno == phys_bno) {
            // cache hit!
            if (vol->bcache[i].cache_level < cache_level)
                vol->bcache[i].cache_level = cache_level;  // promote the entry
            vol->bcache[i].refcount++;
            *buffer_out = vol->bcache[i].data;
            return FSW_SUCCESS;
        }
    }

    // find a free entry in the cache table
    for (i = 0; i < vol->bcache_size; i++) {
        if (vol->bcache[i].phys_bno == FSW_INVALID_BNO)
            break;
    }
    if (i >= vol->bcache_size) {
        for (discard_level = 0; discard_level <= MAX_CACHE_LEVEL; discard_level++) {
            for (i = 0; i < vol->bcache_size; i++) {
                if (vol->bcache[i].refcount == 0 && vol->bcache[i].cache_level <= discard_level)
                    break;
            }
            if (i < vol->bcache_size)
                break;
        }
    }
    if (i >= vol->bcache_size) {
        // enlarge / create the cache
        if (vol->bcache_size < 16)
            new_bcache_size = 16;
        else
            new_bcache_size = vol->bcache_size << 1;
        status = fsw_alloc(new_bcache_size * sizeof(struct fsw_blockcache), &new_bcache);
        if (status)
            return status;
        if (vol->bcache_size > 0)
            fsw_memcpy(new_bcache, vol->bcache, vol->bcache_size * sizeof(struct fsw_blockcache));
        for (i = vol->bcache_size; i < new_bcache_size; i++) {
            new_bcache[i].refcount = 0;
            new_bcache[i].cache_level = 0;
            new_bcache[i].phys_bno = FSW_INVALID_BNO;
            new_bcache[i].data = NULL;
        }
        i = vol->bcache_size;

        // switch caches
        if (vol->bcache != NULL)
            fsw_free(vol->bcache);
        vol->bcache = new_bcache;
        vol->bcache_size = new_bcache_size;
    }
    vol->bcache[i].phys_bno = FSW_INVALID_BNO;

    // read the data
    if (vol->bcache[i].data == NULL) {
        status = fsw_alloc(vol->phys_blocksize, &vol->bcache[i].data);
        if (status)
            return status;
    }
    status = vol->host_table->read_block(vol, phys_bno, vol->bcache[i].data);
    if (status)
        return status;

    vol->bcache[i].phys_bno = phys_bno;
    vol->bcache[i].cache_level = cache_level;
    vol->bcache[i].refcount = 1;
    *buffer_out = vol->bcache[i].data;
    return FSW_SUCCESS;
}
コード例 #7
0
ファイル: fsw_ext2.c プロジェクト: Zokormazo/refind
static fsw_status_t fsw_ext2_volume_mount(struct fsw_ext2_volume *vol)
{
    fsw_status_t    status;
    void            *buffer;
    fsw_u32         blocksize;
    fsw_u32         groupcnt, groupno, gdesc_per_block, gdesc_bno, gdesc_index;
    struct ext2_group_desc *gdesc;
    int             i;
    struct fsw_string s;

    // allocate memory to keep the superblock around
    status = fsw_alloc(sizeof(struct ext2_super_block), &vol->sb);
    if (status)
        return status;

    // read the superblock into its buffer
    fsw_set_blocksize(vol, EXT2_SUPERBLOCK_BLOCKSIZE, EXT2_SUPERBLOCK_BLOCKSIZE);
    status = fsw_block_get(vol, EXT2_SUPERBLOCK_BLOCKNO, 0, &buffer);
    if (status)
        return status;
    fsw_memcpy(vol->sb, buffer, sizeof(struct ext2_super_block));
    fsw_block_release(vol, EXT2_SUPERBLOCK_BLOCKNO, buffer);

    // check the superblock
    if (vol->sb->s_magic != EXT2_SUPER_MAGIC)
        return FSW_UNSUPPORTED;
    if (vol->sb->s_rev_level != EXT2_GOOD_OLD_REV &&
        vol->sb->s_rev_level != EXT2_DYNAMIC_REV)
        return FSW_UNSUPPORTED;
    if (vol->sb->s_rev_level == EXT2_DYNAMIC_REV &&
        (vol->sb->s_feature_incompat & ~(EXT2_FEATURE_INCOMPAT_FILETYPE | EXT3_FEATURE_INCOMPAT_RECOVER)))
        return FSW_UNSUPPORTED;

    /*
     if (vol->sb->s_rev_level == EXT2_DYNAMIC_REV &&
         (vol->sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER))
     Print(L"Ext2 WARNING: This ext3 file system needs recovery, trying to use it anyway.\n");
     */

    // set real blocksize
    blocksize = EXT2_BLOCK_SIZE(vol->sb);
    fsw_set_blocksize(vol, blocksize, blocksize);

    // get other info from superblock
    vol->ind_bcnt = EXT2_ADDR_PER_BLOCK(vol->sb);
    vol->dind_bcnt = vol->ind_bcnt * vol->ind_bcnt;
    vol->inode_size = EXT2_INODE_SIZE(vol->sb);

    for (i = 0; i < 16; i++)
        if (vol->sb->s_volume_name[i] == 0)
            break;
    s.type = FSW_STRING_TYPE_ISO88591;
    s.size = s.len = i;
    s.data = vol->sb->s_volume_name;
    status = fsw_strdup_coerce(&vol->g.label, vol->g.host_string_type, &s);
    if (status)
        return status;

    // read the group descriptors to get inode table offsets
    groupcnt = ((vol->sb->s_inodes_count - 2) / vol->sb->s_inodes_per_group) + 1;
    gdesc_per_block = (vol->g.phys_blocksize / sizeof(struct ext2_group_desc));

    status = fsw_alloc(sizeof(fsw_u32) * groupcnt, &vol->inotab_bno);
    if (status)
        return status;
    for (groupno = 0; groupno < groupcnt; groupno++) {
        // get the block group descriptor
        gdesc_bno = (vol->sb->s_first_data_block + 1) + groupno / gdesc_per_block;
        gdesc_index = groupno % gdesc_per_block;
        status = fsw_block_get(vol, gdesc_bno, 1, (void **)&buffer);
        if (status)
            return status;
        gdesc = ((struct ext2_group_desc *)(buffer)) + gdesc_index;
        vol->inotab_bno[groupno] = gdesc->bg_inode_table;
        fsw_block_release(vol, gdesc_bno, buffer);
    }

    // setup the root dnode
    status = fsw_dnode_create_root(vol, EXT2_ROOT_INO, &vol->g.root);
    if (status)
        return status;

    FSW_MSG_DEBUG((FSW_MSGSTR("fsw_ext2_volume_mount: success, blocksize %d\n"), blocksize));

    return FSW_SUCCESS;
}