예제 #1
0
int
flashcache_read_compute_checksum(struct cache_c *dmc, int index, void *block)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
	struct io_region where;
#else
	struct dm_io_region where;
#endif
	int error;
	u_int64_t sum = 0, *idx;
	int cnt;

	where.bdev = dmc->cache_dev->bdev;
	where.sector = INDEX_TO_CACHE_ADDR(dmc, index);
	where.count = dmc->block_size;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
	error = flashcache_dm_io_sync_vm(dmc, &where, READ, block);
#else
	error = flashcache_dm_io_sync_vm(dmc, &where, READ, block);
#endif
	if (error)
		return error;
	cnt = dmc->block_size * 512;
	idx = (u_int64_t *)block;
	while (cnt > 0) {
		sum += *idx++;
		cnt -= sizeof(u_int64_t);		
	}
	dmc->cache[index].checksum = sum;
	return 0;
}
예제 #2
0
struct flashcache_copy_job *
new_flashcache_copy_job(struct cache_c *dmc, 
			int nr_writes, 
			struct dbn_index_pair *writes_list)
{
	struct flashcache_copy_job *job;
	int i, j;
	
	job = alloc_flashcache_copy_job(dmc);
	if (unlikely(job == NULL))
		return NULL;
	job->dmc = dmc;
	job->nr_writes = nr_writes;
	job->reads_completed = 0;
	job->write_kickoff = 0;
	job->error = 0;
	job->pl_list_head = NULL;
	for (i = 0 ; i < nr_writes ; i++) {
		job->page_base[i] = alloc_page(GFP_NOIO);
		if (unlikely(job->page_base[i] == NULL)) {
			for (j = 0 ; j < i ; j++)
				__free_page(job->page_base[j]);
			goto nomem;
		}
		job->job_base[i] = new_kcached_job(dmc, NULL, writes_list[i].index);
		atomic_inc(&dmc->nr_jobs);
		if (unlikely(job->job_base[i] == NULL)) {
			for (j = 0 ; j <= i ; j++)
				__free_page(job->page_base[j]);
			for (j = 0 ; j < i ; j++) {
				flashcache_free_cache_job(job->job_base[i]);
				if (atomic_dec_and_test(&dmc->nr_jobs))
					wake_up(&dmc->destroyq);
			}
			goto nomem;			
		}
	}
	/* 
	 * Stuff the pages into the page_list structures.
	 * Null terminate each page_list entry, because we want to do 
	 * the individial reads first.
	 */
	for (i = 0 ; i < nr_writes ; i++) {
		job->pl_base[i].next = NULL;
		job->pl_base[i].page = job->page_base[i];
	}
	spin_lock_init(&job->copy_job_spinlock);
	for (i = 0 ; i < nr_writes ; i++) {
		job->job_io_regions.cache[i].bdev = dmc->cache_dev->bdev;
		job->job_io_regions.cache[i].sector = INDEX_TO_CACHE_ADDR(dmc, writes_list[i].index);
		job->job_io_regions.cache[i].count = dmc->block_size;
	}	
	job->job_io_regions.disk.bdev = dmc->disk_dev->bdev;
	job->job_io_regions.disk.sector = writes_list[0].dbn;
	job->job_io_regions.disk.count = dmc->block_size * nr_writes;
	return job;
nomem:
	free_flashcache_copy_job(dmc, job);
	return NULL;
}