1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

bcache-utils: bcache_set_bytes()

This commit is contained in:
Joe Thornber 2018-05-09 11:05:29 +01:00
parent 2e1869b923
commit 1c5c99afce
3 changed files with 108 additions and 2 deletions

View File

@ -227,3 +227,46 @@ bool bcache_zero_bytes(struct bcache *cache, int fd, uint64_t start, size_t len)
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
static bool _set_partial(struct updater *u, int fd, block_address bb, uint64_t offset, size_t len)
{
struct block *b;
uint8_t val = *((uint8_t *) u->data);
if (!bcache_get(u->cache, fd, bb, GF_DIRTY, &b, NULL))
return false;
memset(((unsigned char *) b->data) + offset, val, len);
bcache_put(b);
return true;
}
static bool _set_whole(struct updater *u, int fd, block_address bb, block_address be)
{
struct block *b;
uint8_t val = *((uint8_t *) u->data);
uint64_t len = bcache_block_sectors(u->cache) * 512;
for (; bb != be; bb++) {
if (!bcache_get(u->cache, fd, bb, GF_ZERO, &b, NULL))
return false;
memset((unsigned char *) b->data, val, len);
bcache_put(b);
}
return true;
}
bool bcache_set_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, uint8_t val)
{
struct updater u;
u.cache = cache;
u.partial_fn = _set_partial;
u.whole_fn = _set_whole;
u.data = &val;
return _update_bytes(&u, fd, start, len);
}

View File

@ -162,6 +162,7 @@ void bcache_prefetch_bytes(struct bcache *cache, int fd, uint64_t start, size_t
bool bcache_read_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data); bool bcache_read_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data);
bool bcache_write_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data); bool bcache_write_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data);
bool bcache_zero_bytes(struct bcache *cache, int fd, uint64_t start, size_t len); bool bcache_zero_bytes(struct bcache *cache, int fd, uint64_t start, size_t len);
bool bcache_set_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, uint8_t val);
//---------------------------------------------------------------- //----------------------------------------------------------------

View File

@ -140,7 +140,7 @@ static void _verify(struct fixture *f, uint64_t byte_b, uint64_t byte_e, uint8_t
} }
} }
static void _verify_zeroes(struct fixture *f, uint64_t byte_b, uint64_t byte_e) static void _verify_set(struct fixture *f, uint64_t byte_b, uint64_t byte_e, uint8_t val)
{ {
int err; int err;
unsigned i; unsigned i;
@ -155,7 +155,7 @@ static void _verify_zeroes(struct fixture *f, uint64_t byte_b, uint64_t byte_e)
blen = _min(T_BLOCK_SIZE - offset, len); blen = _min(T_BLOCK_SIZE - offset, len);
for (i = 0; i < blen; i++) for (i = 0; i < blen; i++)
T_ASSERT(((uint8_t *) b->data)[offset + i] == 0); T_ASSERT(((uint8_t *) b->data)[offset + i] == val);
offset = 0; offset = 0;
len -= blen; len -= blen;
@ -164,6 +164,11 @@ static void _verify_zeroes(struct fixture *f, uint64_t byte_b, uint64_t byte_e)
} }
} }
static void _verify_zeroes(struct fixture *f, uint64_t byte_b, uint64_t byte_e)
{
_verify_set(f, byte_b, byte_e, 0);
}
static void _do_write(struct fixture *f, uint64_t byte_b, uint64_t byte_e, uint8_t pat) static void _do_write(struct fixture *f, uint64_t byte_b, uint64_t byte_e, uint8_t pat)
{ {
unsigned i; unsigned i;
@ -183,6 +188,11 @@ static void _do_zero(struct fixture *f, uint64_t byte_b, uint64_t byte_e)
T_ASSERT(bcache_zero_bytes(f->cache, f->fd, byte_b, byte_e - byte_b)); T_ASSERT(bcache_zero_bytes(f->cache, f->fd, byte_b, byte_e - byte_b));
} }
static void _do_set(struct fixture *f, uint64_t byte_b, uint64_t byte_e, uint8_t val)
{
T_ASSERT(bcache_set_bytes(f->cache, f->fd, byte_b, byte_e - byte_b, val));
}
static void _reopen(struct fixture *f) static void _reopen(struct fixture *f)
{ {
struct io_engine *engine; struct io_engine *engine;
@ -296,6 +306,51 @@ static void _test_zero_many_boundaries(void *fixture)
//---------------------------------------------------------------- //----------------------------------------------------------------
static void _set_cycle(struct fixture *f, uint64_t b, uint64_t e)
{
uint8_t val = random();
_verify(f, b, e, INIT_PATTERN);
_do_set(f, b, e, val);
_reopen(f);
_verify(f, b < 128 ? 0 : b - 128, b, INIT_PATTERN);
_verify_set(f, b, e, val);
_verify(f, e, _min(e + 128, _max_byte()), INIT_PATTERN);
}
static void _test_set_first_block(void *fixture)
{
_set_cycle(fixture, byte(0, 0), byte(0, T_BLOCK_SIZE));
}
static void _test_set_last_block(void *fixture)
{
uint64_t last_block = NR_BLOCKS - 1;
_set_cycle(fixture, byte(last_block, 0), byte(last_block, T_BLOCK_SIZE));
}
static void _test_set_several_whole_blocks(void *fixture)
{
_set_cycle(fixture, byte(5, 0), byte(10, 0));
}
static void _test_set_within_single_block(void *fixture)
{
_set_cycle(fixture, byte(7, 3), byte(7, T_BLOCK_SIZE / 2));
}
static void _test_set_cross_one_boundary(void *fixture)
{
_set_cycle(fixture, byte(13, 43), byte(14, 43));
}
static void _test_set_many_boundaries(void *fixture)
{
_set_cycle(fixture, byte(13, 13), byte(23, 13));
}
//----------------------------------------------------------------
#define T(path, desc, fn) register_test(ts, "/base/device/bcache/utils/" path, desc, fn) #define T(path, desc, fn) register_test(ts, "/base/device/bcache/utils/" path, desc, fn)
static struct test_suite *_tests(void) static struct test_suite *_tests(void)
@ -320,6 +375,13 @@ static struct test_suite *_tests(void)
T("zero-cross-one-boundary", "zero across one boundary", _test_zero_cross_one_boundary); T("zero-cross-one-boundary", "zero across one boundary", _test_zero_cross_one_boundary);
T("zero-many-boundaries", "zero many boundaries", _test_zero_many_boundaries); T("zero-many-boundaries", "zero many boundaries", _test_zero_many_boundaries);
T("set-first-block", "set the first block", _test_set_first_block);
T("set-last-block", "set the last block", _test_set_last_block);
T("set-several-blocks", "set several whole blocks", _test_set_several_whole_blocks);
T("set-within-single-block", "set within single block", _test_set_within_single_block);
T("set-cross-one-boundary", "set across one boundary", _test_set_cross_one_boundary);
T("set-many-boundaries", "set many boundaries", _test_set_many_boundaries);
return ts; return ts;
} }