blocktest: add support for no alignment

Some block drivers do not impose any alignment requirements, and this
patch allows such block drivers to pass the test set. As a side effect,
minimal support for min_write is added, but this part of blocktest is
in need of further improvement.

Change-Id: I9ea81433a6fe1177742020e6a584f876043d7e9a
This commit is contained in:
David van Moolenbroek 2013-08-01 18:20:33 +02:00 committed by Lionel Sambuc
parent de27460e2e
commit b0ea2920e6
2 changed files with 67 additions and 44 deletions

View file

@ -33,6 +33,7 @@ static endpoint_t driver_endpt; /* driver endpoint */
static int may_write = FALSE; /* may we write to the device? */
static int sector_size = 512; /* size of a single disk sector */
static int min_read = 512; /* minimum total size of read req */
static int min_write = 0; /* minimum total size of write req */
static int element_size = 512; /* minimum I/O vector element size */
static int max_size = 131072; /* maximum total size of any req */
/* Note that we do not test exceeding the max_size limit, so it is safe to set
@ -60,6 +61,7 @@ static struct optset optset_table[] = {
{ "sector", OPT_INT, &sector_size, 10 },
{ "element", OPT_INT, &element_size, 10 },
{ "min_read", OPT_INT, &min_read, 10 },
{ "min_write", OPT_INT, &min_write, 10 },
{ "max", OPT_INT, &max_size, 10 },
{ NULL, 0, NULL, 0 }
};
@ -723,6 +725,14 @@ static void bad_read2(void)
cpf_revoke(grant);
/* Test word-unaligned position. */
/* Only perform this test if the minimum read size is not 1, in which
* case it is safe to assume that the driver expects no position
* alignment either. These tests are indeed not exhaustive yet. For now
* we assume that if no alignment is required at all, the driver does
* not implement special logic to achieve this, so we don't need to
* test all possible positions and sizes either (yes, laziness..).
*/
if (min_read > 1) {
memcpy(iov, iovt, sizeof(iovt));
buf_sum = fill_rand(buf_ptr, buf_size);
@ -736,6 +746,7 @@ static void bad_read2(void)
test_sum(buf3_ptr, buf3_size, buf3_sum, TRUE, &res);
got_result(&res, "word-unaligned position");
}
/* Test normal vector request (final check). */
memcpy(iov, iovt, sizeof(iovt));
@ -759,16 +770,14 @@ static void bad_read2(void)
free_buf_and_grant(buf_ptr, buf_grant, buf_size);
}
#define SECTOR_UNALIGN 2ULL /* word-aligned and sector-unaligned */
static void bad_write(void)
{
/* Test various illegal write transfer requests, if writing is allowed.
* If handled correctly, these requests will not actually write data.
* However, the last test currently erroneously does end up writing.
* This part of the test set is in need of further expansion.
*/
u8_t *buf_ptr, *buf2_ptr, *buf3_ptr;
size_t buf_size, buf2_size, buf3_size;
size_t buf_size, buf2_size, buf3_size, sector_unalign;
cp_grant_id_t buf_grant, buf2_grant, buf3_grant;
cp_grant_id_t grant;
u32_t buf_sum, buf2_sum, buf3_sum;
@ -793,6 +802,17 @@ static void bad_write(void)
iovt[2].iov_grant = buf3_grant;
iovt[2].iov_size = buf3_size;
/* Only perform write alignment tests if writes require alignment. */
if (min_write == 0)
min_write = sector_size;
if (min_write > 1) {
/* If min_write is larger than 2, use 2 as sector-unaligned
* size, as word-unaligned values (e.g., 1) may be filtered out
* on another code path.
*/
sector_unalign = (min_write > 2) ? 2 : 1;
/* Test sector-unaligned write position. */
memcpy(iov, iovt, sizeof(iovt));
@ -800,7 +820,8 @@ static void bad_write(void)
buf2_sum = fill_rand(buf2_ptr, buf2_size);
buf3_sum = fill_rand(buf3_ptr, buf3_size);
raw_xfer(driver_minor, SECTOR_UNALIGN, iov, 3, TRUE, EINVAL, &res);
raw_xfer(driver_minor, (u64_t)sector_unalign, iov, 3, TRUE,
EINVAL, &res);
test_sum(buf_ptr, buf_size, buf_sum, TRUE, &res);
test_sum(buf2_ptr, buf2_size, buf2_sum, TRUE, &res);
@ -810,7 +831,7 @@ static void bad_write(void)
/* Test sector-unaligned write size. */
memcpy(iov, iovt, sizeof(iovt));
iov[1].iov_size -= SECTOR_UNALIGN;
iov[1].iov_size -= sector_unalign;
buf_sum = fill_rand(buf_ptr, buf_size);
buf2_sum = fill_rand(buf2_ptr, buf2_size);
@ -823,6 +844,7 @@ static void bad_write(void)
test_sum(buf3_ptr, buf3_size, buf3_sum, TRUE, &res);
got_result(&res, "sector-unaligned write size");
}
/* Test write-only grant in iovec element. */
memcpy(iov, iovt, sizeof(iovt));
@ -1933,10 +1955,9 @@ static void unaligned_size(void)
static void unaligned_pos1(void)
{
/* Test sector-unaligned positions and total sizes for requests. This
* is a read-only test as no driver currently supports sector-unaligned
* writes. In this context, the term "lead" means an unwanted first
* part of a sector, and "trail" means an unwanted last part of a
* sector.
* is a read-only test for now. Write support should be added later.
* In the current context, the term "lead" means an unwanted first part
* of a sector, and "trail" means an unwanted last part of a sector.
*/
u8_t *buf_ptr, *buf2_ptr;
size_t buf_size, buf2_size, size;

View file

@ -22,15 +22,17 @@
# on other partitions and possibly other disks) WILL BE DESTROYED.
# Use "ro" for read-only mediums, such as CD-ROMs.
# sector Sector size, in bytes. This should be 512 for ATA devices, and
# 2048 for ATAPI devices.
# min_read Minimum size of a read request. This must be at least 2 and at
# 2048 for ATAPI devices. The default is 512.
# min_read Minimum size of a read request. This must be at least 1 and at
# most the sector size, and the sector size must be divisible by
# it. A value other than the sector size allows blocktest to test
# sub-sector reads. Sub-sector writes are currently not supported
# by any driver and hence not by blocktest, so there is no
# matching "min_write" (yet).
# sub-sector reads.
# min_write Minimum size of a write request. This must be at least 1 and at
# most the sector size. Sub-sector write support is not common in
# drivers, and therefore not yet well tested by blocktest. This
# parameter is optional; if omitted, the sector size is used.
# element Minimum size of a vector element within a larger I/O request.
# This must be at least 2 and at most min_read, and min_read must
# This must be at least 1 and at most min_read, and min_read must
# be divisible by this value. The idea is that several small
# elements may add up to the minimum read size.
# max Maximum size of any request. This should be a multiple of the