Implement bi-directional page alloc scanning
This commit is contained in:
parent
c1ec406a00
commit
b80d80215b
|
@ -328,6 +328,25 @@ pblk_alloc_read(struct dm_compress* dc, struct zone_cache* zc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u64
|
||||
__pblk_alloc_get(struct dm_compress* dc, struct zone_cache* zc)
|
||||
{
|
||||
u32 pblk_count = pblk_alloc_len(&dc->params) * PBLK_SIZE_BITS;
|
||||
u32 idx;
|
||||
|
||||
if (pblk_alloc_read(dc, zc) != 0) {
|
||||
printk(KERN_ERR "%s: pblk_alloc_read failed\n", __func__);
|
||||
return PBLK_NONE;
|
||||
}
|
||||
idx = cbd_bitmap_alloc(zc->pblk_alloc, pblk_count);
|
||||
if (idx == pblk_count) {
|
||||
return PBLK_NONE;
|
||||
}
|
||||
zc->pblk_alloc_dirty = true;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get (allocate) one pblk from the currently cached zone pblk alloc bitmap.
|
||||
* XXX: get rid of this function and use pblk_alloc directly in lblk_write().
|
||||
|
@ -335,37 +354,45 @@ pblk_alloc_read(struct dm_compress* dc, struct zone_cache* zc)
|
|||
static u64
|
||||
pblk_alloc_get(struct dm_compress* dc, struct zone_cache* zc_hint)
|
||||
{
|
||||
u32 zone_pblk_count = pblk_alloc_len(&dc->params) * PBLK_SIZE_BITS;
|
||||
u64 pblk;
|
||||
u32 zone_off;
|
||||
struct zone_cache* zc;
|
||||
u32 zone;
|
||||
u32 idx;
|
||||
|
||||
zc = zc_hint;
|
||||
zone = zc->zone;
|
||||
/* XXX: check both forward and backward */
|
||||
do {
|
||||
if (pblk_alloc_read(dc, zc) != 0) {
|
||||
printk(KERN_ERR " pblk_alloc_read failed\n");
|
||||
return 0;
|
||||
}
|
||||
idx = cbd_bitmap_alloc(zc->pblk_alloc, zone_pblk_count);
|
||||
if (idx != zone_pblk_count) {
|
||||
zc->pblk_alloc_dirty = true;
|
||||
if (zc != zc_hint) {
|
||||
zone_cache_put(dc, zc);
|
||||
}
|
||||
return zone_data_off(&dc->params, zone) + idx;
|
||||
}
|
||||
++zone;
|
||||
if (zone == dc->params.nr_zones) {
|
||||
zone = 0;
|
||||
}
|
||||
zc = zone_cache_get(dc, zone);
|
||||
pblk = __pblk_alloc_get(dc, zc_hint);
|
||||
if (pblk != PBLK_NONE) {
|
||||
return zone_data_off(&dc->params, zc_hint->zone) + pblk;
|
||||
}
|
||||
for (zone_off = 1;
|
||||
zone_off <= zc_hint->zone || zc_hint->zone + zone_off < dc->params.nr_zones;
|
||||
++zone_off) {
|
||||
if (zone_off <= zc_hint->zone) {
|
||||
zc = zone_cache_get(dc, zc_hint->zone - zone_off);
|
||||
if (zc) {
|
||||
pblk = __pblk_alloc_get(dc, zc);
|
||||
if (zone_cache_put(dc, zc) != 0) {
|
||||
return PBLK_NONE;
|
||||
}
|
||||
if (pblk != PBLK_NONE) {
|
||||
return zone_data_off(&dc->params, zc->zone) + pblk;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (zc_hint->zone + zone_off < dc->params.nr_zones) {
|
||||
zc = zone_cache_get(dc, zc_hint->zone + zone_off);
|
||||
if (zc) {
|
||||
pblk = __pblk_alloc_get(dc, zc);
|
||||
if (zone_cache_put(dc, zc) != 0) {
|
||||
return PBLK_NONE;
|
||||
}
|
||||
if (pblk != PBLK_NONE) {
|
||||
return zone_data_off(&dc->params, zc->zone) + pblk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (zc != zc_hint);
|
||||
printk(KERN_ERR "%s: fail, all zones full\n", __func__);
|
||||
|
||||
return 0;
|
||||
return PBLK_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue