1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-24 02:04:21 +03:00

lib: add sys_block_align[_truncate]()

This implements MS-FSA algorithms BlockAlign() and BlockAlignTruncate().

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Ralph Boehme 2021-06-22 18:58:21 +02:00 committed by Jeremy Allison
parent 8fa7848b4a
commit 2f523a03f5
3 changed files with 85 additions and 0 deletions

View File

@ -23,6 +23,7 @@
#include "replace.h"
#include "system/filesys.h"
#include "lib/util/sys_rw.h"
#include <assert.h>
bool sys_valid_io_range(off_t offset, size_t length)
{
@ -73,6 +74,20 @@ bool sys_io_ranges_overlap(size_t c1, off_t o1,
}
}
off_t sys_block_align_truncate(off_t len, off_t align)
{
assert(align > 1);
assert(((align - 1) & align) == 0);
return len & (~align + 1);
}
off_t sys_block_align(off_t len, off_t align)
{
assert(align > 1);
assert(((align - 1) & align) == 0);
return (len + (align - 1)) & ~(align - 1);
}
/*******************************************************************
A read wrapper that will deal with EINTR/EWOULDBLOCK
********************************************************************/

View File

@ -27,6 +27,8 @@
struct iovec;
off_t sys_block_align_truncate(off_t len, off_t align);
off_t sys_block_align(off_t len, off_t align);
bool sys_valid_io_range(off_t offset, size_t length);
bool sys_io_ranges_overlap(size_t c1, off_t o1,
size_t c2, off_t o2);

View File

@ -98,10 +98,78 @@ static void test_sys_io_ranges_overlap(void **state)
assert_true(overlap);
}
static void test_sys_block_align(void **state)
{
int asize;
asize = sys_block_align(0, 2);
assert_int_equal(asize, 0);
asize = sys_block_align(1, 2);
assert_int_equal(asize, 2);
asize = sys_block_align(2, 2);
assert_int_equal(asize, 2);
asize = sys_block_align(3, 2);
assert_int_equal(asize, 4);
asize = sys_block_align(0, 4);
assert_int_equal(asize, 0);
asize = sys_block_align(1, 4);
assert_int_equal(asize, 4);
asize = sys_block_align(3, 4);
assert_int_equal(asize, 4);
asize = sys_block_align(4, 4);
assert_int_equal(asize, 4);
asize = sys_block_align(5, 4);
assert_int_equal(asize, 8);
asize = sys_block_align(7, 4);
assert_int_equal(asize, 8);
asize = sys_block_align(8, 4);
assert_int_equal(asize, 8);
asize = sys_block_align(9, 4);
assert_int_equal(asize, 12);
}
static void test_sys_block_align_truncate(void **state)
{
int asize;
asize = sys_block_align_truncate(0, 2);
assert_int_equal(asize, 0);
asize = sys_block_align_truncate(1, 2);
assert_int_equal(asize, 0);
asize = sys_block_align_truncate(2, 2);
assert_int_equal(asize, 2);
asize = sys_block_align_truncate(3, 2);
assert_int_equal(asize, 2);
asize = sys_block_align_truncate(4, 2);
assert_int_equal(asize, 4);
asize = sys_block_align_truncate(5, 2);
assert_int_equal(asize, 4);
asize = sys_block_align_truncate(0, 4);
assert_int_equal(asize, 0);
asize = sys_block_align_truncate(1, 4);
assert_int_equal(asize, 0);
asize = sys_block_align_truncate(3, 4);
assert_int_equal(asize, 0);
asize = sys_block_align_truncate(4, 4);
assert_int_equal(asize, 4);
asize = sys_block_align_truncate(5, 4);
assert_int_equal(asize, 4);
asize = sys_block_align_truncate(7, 4);
assert_int_equal(asize, 4);
asize = sys_block_align_truncate(8, 4);
assert_int_equal(asize, 8);
asize = sys_block_align_truncate(9, 4);
assert_int_equal(asize, 8);
}
int main(int argc, char **argv)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_sys_io_ranges_overlap),
cmocka_unit_test(test_sys_block_align),
cmocka_unit_test(test_sys_block_align_truncate),
};
cmocka_set_message_output(CM_OUTPUT_SUBUNIT);