Example #1
0
static int __fatfs_control_load_fat_cache(struct fatfs_control *ctrl,
					   u32 sect_num)
{
	int rc;
	u32 index;
	u64 fat_base, len;

	if (-1 < __fatfs_control_find_fat_cache(ctrl, sect_num)) {
		return VMM_OK;
	}

	index = ctrl->fat_cache_victim;
	ctrl->fat_cache_victim++;
	if (ctrl->fat_cache_victim == FAT_TABLE_CACHE_SIZE) {
		ctrl->fat_cache_victim = 0;
	}

	rc = __fatfs_control_flush_fat_cache(ctrl, index);
	if (rc) {
		return rc;
	}

	fat_base = (u64)ctrl->first_fat_sector * ctrl->bytes_per_sector;
	len = vmm_blockdev_read(ctrl->bdev, 
			&ctrl->fat_cache_buf[index * ctrl->bytes_per_sector], 
			fat_base + sect_num * ctrl->bytes_per_sector, 
			ctrl->bytes_per_sector);
	if (len != ctrl->bytes_per_sector) {
		return VMM_EIO;
	}
	ctrl->fat_cache_num[index] = sect_num;

	return VMM_OK;
}
Example #2
0
static struct dir_entry *path_to_dentry(struct vmm_blockdev *mdev,
					const char *path,
					struct dir_entry *pdentry)
{
	char dirname[VFS_MAX_NAME] = { 0 };
	struct dir_entry *dentry, *d_root;
	int i = 0, rd;
	int len = 0;
	char rpath[VFS_MAX_NAME];

	len = strlen(path);

	if (!len) return NULL;

	vmm_snprintf(rpath, len, "%s", path);
	if (rpath[len - 1] != '/') {
		rpath[len] = '/';
		rpath[len+1] = 0;
	}

	path = rpath;

	if (*path == '/') {
		path++;
		if (!*path) return pdentry;
	}

	while (*path && *path != '/') {
		dirname[i] = *path;
		path++;
		i++;
	}

	dentry = lookup_dentry(dirname, pdentry);
	if (dentry) {
		d_root = vmm_zalloc(dentry->dlen.lsb);
		rd = vmm_blockdev_read(mdev, (u8 *)d_root,
				       (dentry->start_lba.lsb * 2048),
				       dentry->dlen.lsb);
		if (rd != dentry->dlen.lsb) {
			vmm_free(d_root);
			return NULL;
		}
		dentry = path_to_dentry(mdev, path, d_root);
	}

	return dentry;
}
Example #3
0
/* vnode operations */
static size_t iso9660fs_read(struct vnode *v, loff_t off, void *buf, size_t len)
{
	u64 toff;
	size_t sz = 0;

	if (v->v_type != VREG) {
		return 0;
	}

	if (off >= v->v_size) {
		return 0;
	}

	sz = len;
	if ((v->v_size - off) < sz) {
		sz = v->v_size - off;
	}

	toff = (u64)(v->v_data);
	sz = vmm_blockdev_read(v->v_mount->m_dev, (u8 *)buf, (toff + off), sz);

	return sz;
}
Example #4
0
/* Mount operation */
static int iso9660fs_mount(struct mount *m, const char *dev, u32 flags)
{
	u64 read_count;
	int retval = VMM_OK, rd;
	struct iso9660_mount_data *mdata;

	if (dev == NULL) {
		return VMM_EINVALID;
	}

	if (vmm_blockdev_total_size(m->m_dev) <=
				sizeof(struct primary_vol_desc)) {
		return VMM_EFAIL;
	}

	mdata = vmm_zalloc(sizeof(struct iso9660_mount_data));

	if (!mdata)
		return VMM_ENOMEM;

	mdata->mdev = m->m_dev;

	read_count = vmm_blockdev_read(m->m_dev, (u8 *)(&mdata->vol_desc),
				       VOL_DESC_START_OFFS,
				       sizeof(struct primary_vol_desc));
	if (read_count != sizeof(struct primary_vol_desc)) {
		retval = VMM_EIO;
		goto _fail;
	}

	if (mdata->vol_desc.type != VOL_DESC_PRIMARY) {
		retval = VMM_EINVALID;
		goto _fail;
	}

	if (strncmp((const char *)&mdata->vol_desc.ident[0], "CD001", 5) != 0) {
		retval = VMM_EINVALID;
		goto _fail;
	}

	mdata->root_dir_entry = (struct dir_entry *)
		(&mdata->vol_desc.root_dir_entry[0]);
	mdata->root_dir_offset = mdata->root_dir_entry->start_lba.lsb * 2048;
	mdata->root_dir_len = mdata->root_dir_entry->dlen.lsb;

	mdata->root_dir = vmm_zalloc(mdata->root_dir_len);
	if (!mdata->root_dir) {
		retval = VMM_ENOMEM;
		goto _fail;
	}

	rd = vmm_blockdev_read(m->m_dev, (u8 *)mdata->root_dir,
			       mdata->root_dir_offset,
			       mdata->root_dir_len);
	if (!rd || rd != mdata->root_dir_len) {
		retval = VMM_EIO;
		goto _fail;
	}

	/* We don't support writing to ISO9660 fs */
	m->m_flags = MOUNT_RDONLY;
	m->m_root->v_data = NULL;
	m->m_data = mdata;

	return VMM_OK;

 _fail:
	if (mdata) {
		if (mdata->root_dir) vmm_free(mdata->root_dir);
		vmm_free(mdata);
	}

	return retval;
}