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; }
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; }