parent
db3d323d27
commit
abdb25d31c
|
@ -29,13 +29,6 @@
|
|||
|
||||
#include <linux/dm-compress.h>
|
||||
|
||||
#define CPU_NONE (~0)
|
||||
|
||||
struct iostate {
|
||||
int cpu;
|
||||
byte hash[MD5_DIGEST_SIZE];
|
||||
};
|
||||
|
||||
struct pbat {
|
||||
u32 zone;
|
||||
struct mutex reflock;
|
||||
|
@ -46,50 +39,8 @@ struct pbat {
|
|||
struct cbd_params* params;
|
||||
struct page* pages;
|
||||
u8* buf;
|
||||
|
||||
struct iostate lrs; /* last read state */
|
||||
struct iostate lws; /* last written state */
|
||||
};
|
||||
|
||||
static void
|
||||
pbat_save_state(struct pbat* pbat)
|
||||
{
|
||||
struct md5 ctx;
|
||||
|
||||
md5_init(&ctx);
|
||||
md5_update(&ctx, pbat->buf, PBLK_SIZE);
|
||||
md5_final(&ctx, pbat->lws.hash);
|
||||
pbat->lws.cpu = smp_processor_id();
|
||||
}
|
||||
|
||||
static bool
|
||||
pbat_check_state(struct pbat* pbat)
|
||||
{
|
||||
struct md5 ctx;
|
||||
byte hash[MD5_DIGEST_SIZE];
|
||||
|
||||
if (pbat->lws.cpu == CPU_NONE) {
|
||||
pbat_save_state(pbat);
|
||||
memcpy(&pbat->lrs, &pbat->lws, sizeof(struct iostate));
|
||||
return true;
|
||||
}
|
||||
|
||||
md5_init(&ctx);
|
||||
md5_update(&ctx, pbat->buf, PBLK_SIZE);
|
||||
md5_final(&ctx, hash);
|
||||
if (!memcmp(hash, pbat->lws.hash, MD5_DIGEST_SIZE)) {
|
||||
return true;
|
||||
}
|
||||
if (!memcmp(hash, pbat->lrs.hash, MD5_DIGEST_SIZE)) {
|
||||
printk(KERN_ERR "%s: read stale data: wcpu=%d curcpu=%d\n", __func__,
|
||||
pbat->lws.cpu, smp_processor_id());
|
||||
return false;
|
||||
}
|
||||
printk(KERN_ERR "%s: read bogus data: wcpu=%d curcpu=%d\n", __func__,
|
||||
pbat->lws.cpu, smp_processor_id());
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
pbat_ctr(struct pbat* pbat,
|
||||
struct cbd_params* params)
|
||||
|
@ -107,8 +58,6 @@ pbat_ctr(struct pbat* pbat,
|
|||
return false;
|
||||
}
|
||||
pbat->buf = page_address(pbat->pages);
|
||||
pbat->lrs.cpu = CPU_NONE;
|
||||
pbat->lws.cpu = CPU_NONE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -158,7 +107,6 @@ pbat_flush(struct pbat* pbat)
|
|||
for (n = 0; n < count; ++n, p += PBLK_SIZE) {
|
||||
iopagev[n] = virt_to_page(p);
|
||||
}
|
||||
pbat_save_state(pbat);
|
||||
pblk_write(pbat->params, pblk, count, iopagev, pbat_flush_endio, pbat);
|
||||
pbat->state = CACHE_STATE_CLEAN;
|
||||
|
||||
|
@ -186,7 +134,6 @@ pbat_read(struct pbat* pbat)
|
|||
u64 pblk;
|
||||
u32 n;
|
||||
u8* p;
|
||||
bool retried = false;
|
||||
|
||||
mutex_lock(&pbat->lock);
|
||||
if (pbat->state != CACHE_STATE_UNCACHED) {
|
||||
|
@ -197,20 +144,10 @@ pbat_read(struct pbat* pbat)
|
|||
for (n = 0; n < count; ++n, p += PBLK_SIZE) {
|
||||
iopagev[n] = virt_to_page(p);
|
||||
}
|
||||
again:
|
||||
ret = pblk_read_wait(pbat->params, pblk, count, iopagev);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
if (!pbat_check_state(pbat)) {
|
||||
printk(KERN_ERR "%s: check state failed, retrying\n", __func__);
|
||||
yield();
|
||||
retried = true;
|
||||
goto again;
|
||||
}
|
||||
if (retried) {
|
||||
printk(KERN_ERR "%s: read good data after retry\n", __func__);
|
||||
}
|
||||
pbat->state = CACHE_STATE_CLEAN;
|
||||
|
||||
out:
|
||||
|
@ -275,8 +212,6 @@ struct pbatcache {
|
|||
struct cbd_params* params;
|
||||
unsigned int len;
|
||||
struct pbat** cache;
|
||||
struct iostate* lrsv;
|
||||
struct iostate* lwsv;
|
||||
};
|
||||
|
||||
size_t
|
||||
|
@ -322,17 +257,9 @@ bool
|
|||
pbatcache_ctr(struct pbatcache* pc,
|
||||
struct cbd_params* params)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
memset(pc, 0, sizeof(struct pbatcache));
|
||||
mutex_init(&pc->lock);
|
||||
pc->params = params;
|
||||
pc->lrsv = kzalloc(params->nr_zones * sizeof(struct iostate), GFP_KERNEL);
|
||||
pc->lwsv = kzalloc(params->nr_zones * sizeof(struct iostate), GFP_KERNEL);
|
||||
for (idx = 0; idx < params->nr_zones; ++idx) {
|
||||
pc->lrsv[idx].cpu = CPU_NONE;
|
||||
pc->lwsv[idx].cpu = CPU_NONE;
|
||||
}
|
||||
|
||||
return pbatcache_realloc(pc, 1);
|
||||
}
|
||||
|
@ -343,8 +270,6 @@ pbatcache_dtr(struct pbatcache* pc)
|
|||
unsigned int n;
|
||||
struct pbat* pbat;
|
||||
|
||||
kfree(pc->lwsv);
|
||||
kfree(pc->lrsv);
|
||||
for (n = 0; n < pc->len; ++n) {
|
||||
pbat = pc->cache[n];
|
||||
if (!pbat) {
|
||||
|
@ -411,8 +336,6 @@ pbatcache_get(struct pbatcache* pc, u32 zone)
|
|||
found:
|
||||
pbat_reset(pbat, zone);
|
||||
pbat->ref = 1;
|
||||
memcpy(&pbat->lrs, &pc->lrsv[zone], sizeof(struct iostate));
|
||||
memcpy(&pbat->lws, &pc->lwsv[zone], sizeof(struct iostate));
|
||||
mutex_unlock(&pbat->reflock);
|
||||
|
||||
out:
|
||||
|
@ -436,8 +359,6 @@ pbatcache_put(struct pbatcache* pc, struct pbat* pbat)
|
|||
if (ret) {
|
||||
printk(KERN_ERR "%s: pbat_flush failed\n", __func__);
|
||||
}
|
||||
memcpy(&pc->lrsv[pbat->zone], &pbat->lrs, sizeof(struct iostate));
|
||||
memcpy(&pc->lwsv[pbat->zone], &pbat->lws, sizeof(struct iostate));
|
||||
}
|
||||
mutex_unlock(&pbat->reflock);
|
||||
mutex_unlock(&pc->lock);
|
||||
|
|
Loading…
Reference in New Issue