[lvm-devel] master - bcache-utils: bcache_set_bytes()

Joe Thornber thornber at sourceware.org
Wed May 9 10:08:14 UTC 2018


Gitweb:        https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1c5c99afceb28f6ee464a705f1337866d29a9819
Commit:        1c5c99afceb28f6ee464a705f1337866d29a9819
Parent:        2e1869b9231181cbd5c3cfa7dbbb3ef237ffa4a9
Author:        Joe Thornber <ejt at redhat.com>
AuthorDate:    Wed May 9 11:05:29 2018 +0100
Committer:     Joe Thornber <ejt at redhat.com>
CommitterDate: Wed May 9 11:05:29 2018 +0100

bcache-utils: bcache_set_bytes()

---
 lib/device/bcache-utils.c  |   43 ++++++++++++++++++++++++++++
 lib/device/bcache.h        |    1 +
 test/unit/bcache_utils_t.c |   66 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/lib/device/bcache-utils.c b/lib/device/bcache-utils.c
index 92e25c8..1487732 100644
--- a/lib/device/bcache-utils.c
+++ b/lib/device/bcache-utils.c
@@ -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);
+}
+
diff --git a/lib/device/bcache.h b/lib/device/bcache.h
index c07f012..599b4c6 100644
--- a/lib/device/bcache.h
+++ b/lib/device/bcache.h
@@ -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_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_set_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, uint8_t val);
 
 //----------------------------------------------------------------
 
diff --git a/test/unit/bcache_utils_t.c b/test/unit/bcache_utils_t.c
index d3ddb9a..255caff 100644
--- a/test/unit/bcache_utils_t.c
+++ b/test/unit/bcache_utils_t.c
@@ -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;
         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);
 		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;
         	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)
 {
         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));
 }
 
+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)
 {
         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)
 
 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-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;
 }
 




More information about the lvm-devel mailing list