209 lines
6.5 KiB
C
209 lines
6.5 KiB
C
|
/* Copyright (C) 2005,2006 David Decotigny
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
as published by the Free Software Foundation; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||
|
USA.
|
||
|
*/
|
||
|
|
||
|
#include <crt.h>
|
||
|
#include <libc.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <string.h>
|
||
|
#include <debug.h>
|
||
|
#include <drivers/devices.h>
|
||
|
|
||
|
#include "fstest_utils.h"
|
||
|
|
||
|
/**
|
||
|
* @file blktest.c
|
||
|
*
|
||
|
* Block devices tests
|
||
|
*/
|
||
|
static int test_device(char const* path, char magic)
|
||
|
{
|
||
|
char wrbuff[32767];
|
||
|
char rdbuff[32767];
|
||
|
int fd, fdcheck, i;
|
||
|
char * mem;
|
||
|
|
||
|
fd = open(path, O_RDWR);
|
||
|
if (fd < 0)
|
||
|
{
|
||
|
bochs_printf("Cannot open %s: error %d\n", path, fd);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
bochs_printf("Testing %s...\n", path);
|
||
|
|
||
|
/* Basic seek tests */
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, 2*512, SEEK_SET), RETVAL == 2*512);
|
||
|
TEST_EXPECT_CONDITION(write(fd, wrbuff, 1), RETVAL == 1);
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, 4*512, SEEK_SET), RETVAL == 4*512);
|
||
|
TEST_EXPECT_CONDITION(read(fd, rdbuff, 1), RETVAL == 1);
|
||
|
|
||
|
/* Prepare to write a large chunk */
|
||
|
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
|
||
|
wrbuff[i] = magic + i;
|
||
|
memset(rdbuff, 0xaa, sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, 3*512 + 43, SEEK_SET), RETVAL == 3*512 + 43);
|
||
|
TEST_EXPECT_CONDITION(write(fd, wrbuff, sizeof(wrbuff)),
|
||
|
RETVAL == sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(write(fd, rdbuff, sizeof(rdbuff)),
|
||
|
RETVAL == sizeof(rdbuff));
|
||
|
|
||
|
memset(rdbuff, 0xbb, sizeof(rdbuff));
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, 3*512 + 47, SEEK_SET), RETVAL == 3*512 + 47);
|
||
|
TEST_EXPECT_CONDITION(read(fd, rdbuff, sizeof(wrbuff)),
|
||
|
RETVAL == sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(memcmp(rdbuff, wrbuff+4, sizeof(wrbuff)-4),
|
||
|
RETVAL == 0);
|
||
|
|
||
|
fdcheck = open(path, O_RDONLY);
|
||
|
|
||
|
#define MAPOFFS (50*4096)
|
||
|
|
||
|
/* Test mmap private mappings */
|
||
|
TEST_EXPECT_CONDITION(mem = mmap(NULL, sizeof(wrbuff), PROT_READ,
|
||
|
MAP_PRIVATE, fd, MAPOFFS + 3),
|
||
|
(void*)RETVAL == NULL);
|
||
|
TEST_EXPECT_CONDITION(mem = mmap(NULL, sizeof(wrbuff),
|
||
|
PROT_READ | PROT_WRITE, MAP_PRIVATE,
|
||
|
fd, MAPOFFS),
|
||
|
(void*)RETVAL != NULL);
|
||
|
|
||
|
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
|
||
|
wrbuff[i] = magic + i;
|
||
|
TEST_EXPECT_CONDITION(1, 1); /* Print a debug line */
|
||
|
|
||
|
memset(rdbuff, 0xaa, sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
|
||
|
TEST_EXPECT_CONDITION(write(fd, wrbuff, sizeof(wrbuff)),
|
||
|
RETVAL == sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(memcmp(wrbuff, mem, sizeof(wrbuff)),
|
||
|
RETVAL == 0);
|
||
|
|
||
|
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
|
||
|
mem[i] = wrbuff[i]*i;
|
||
|
TEST_EXPECT_CONDITION(1, 1); /* Print a debug line */
|
||
|
|
||
|
memset(rdbuff, 0xaa, sizeof(rdbuff));
|
||
|
TEST_EXPECT_CONDITION(lseek(fdcheck, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
|
||
|
TEST_EXPECT_CONDITION(read(fdcheck, rdbuff, sizeof(wrbuff)),
|
||
|
RETVAL == sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(memcmp(wrbuff, rdbuff, sizeof(wrbuff)), RETVAL == 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(msync(mem, sizeof(wrbuff), MS_SYNC), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(munmap(mem, sizeof(wrbuff)), RETVAL == 0);
|
||
|
|
||
|
/* Test mmap shared mappings */
|
||
|
TEST_EXPECT_CONDITION(mem = mmap(mem, sizeof(wrbuff), PROT_READ,
|
||
|
MAP_SHARED, fd, MAPOFFS + 3),
|
||
|
(void*)RETVAL == NULL);
|
||
|
TEST_EXPECT_CONDITION(mem = mmap(mem, sizeof(wrbuff),
|
||
|
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||
|
fd, MAPOFFS),
|
||
|
(void*)RETVAL != NULL);
|
||
|
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
|
||
|
wrbuff[i] = magic + i;
|
||
|
memset(rdbuff, 0xaa, sizeof(rdbuff));
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
|
||
|
TEST_EXPECT_CONDITION(write(fd, wrbuff, sizeof(wrbuff)),
|
||
|
RETVAL == sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(memcmp(wrbuff, mem, sizeof(wrbuff)), RETVAL == 0);
|
||
|
|
||
|
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
|
||
|
mem[i] = wrbuff[i]*i;
|
||
|
memset(rdbuff, 0xaa, sizeof(rdbuff));
|
||
|
TEST_EXPECT_CONDITION(lseek(fdcheck, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
|
||
|
TEST_EXPECT_CONDITION(read(fdcheck, rdbuff, sizeof(wrbuff)),
|
||
|
RETVAL == sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(memcmp(wrbuff, rdbuff, sizeof(wrbuff)), RETVAL != 0);
|
||
|
TEST_EXPECT_CONDITION(memcmp(mem, rdbuff, sizeof(wrbuff)), RETVAL == 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(msync(mem, sizeof(wrbuff), MS_SYNC), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(munmap(mem, sizeof(wrbuff)), RETVAL == 0);
|
||
|
|
||
|
#define STARTOFFS (3*512 + 43 + sizeof(wrbuff) + sizeof(rdbuff))
|
||
|
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, STARTOFFS, SEEK_SET), RETVAL == STARTOFFS);
|
||
|
TEST_EXPECT_CONDITION(lseek(fdcheck, STARTOFFS, SEEK_SET),
|
||
|
RETVAL == STARTOFFS);
|
||
|
int wrlen = 0;
|
||
|
while (1)
|
||
|
{
|
||
|
int sz;
|
||
|
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
|
||
|
wrbuff[i] = magic*magic*i + wrlen*wrlen + i;
|
||
|
|
||
|
TEST_EXPECT_CONDITION(sz = write(fd, wrbuff, sizeof(wrbuff)),
|
||
|
(RETVAL >= 0) && (RETVAL <= sizeof(wrbuff)));
|
||
|
if (sz <= 0)
|
||
|
break;
|
||
|
wrlen += sz;
|
||
|
|
||
|
memset(rdbuff, 0xcc, sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(read(fdcheck, rdbuff, sizeof(wrbuff)), RETVAL == sz);
|
||
|
TEST_EXPECT_CONDITION(memcmp(rdbuff, wrbuff, sz), RETVAL == 0);
|
||
|
}
|
||
|
|
||
|
/* Check the data was correctly written */
|
||
|
TEST_EXPECT_CONDITION(lseek(fd, STARTOFFS, SEEK_SET), RETVAL == STARTOFFS);
|
||
|
int rdlen = 0;
|
||
|
while (1)
|
||
|
{
|
||
|
int sz;
|
||
|
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
|
||
|
wrbuff[i] = magic*magic*i + rdlen*rdlen + i;
|
||
|
|
||
|
memset(rdbuff, 0xdd, sizeof(wrbuff));
|
||
|
TEST_EXPECT_CONDITION(sz = read(fd, rdbuff, sizeof(wrbuff)),
|
||
|
(RETVAL >= 0) && (RETVAL <= sizeof(wrbuff)));
|
||
|
if (sz <= 0)
|
||
|
break;
|
||
|
rdlen += sz;
|
||
|
TEST_EXPECT_CONDITION(memcmp(rdbuff, wrbuff, sz), RETVAL == 0);
|
||
|
}
|
||
|
TEST_EXPECT_CONDITION(rdlen, wrlen == rdlen);
|
||
|
|
||
|
bochs_printf("Synching %s...\n", path);
|
||
|
ioctl(fd, SOS_IOCTL_BLOCKDEV_SYNC, 0);
|
||
|
|
||
|
close(fd);
|
||
|
bochs_printf("End of test for %s.\n", path);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
int i;
|
||
|
bochs_printf("Hi from blktest\n");
|
||
|
|
||
|
/* Test partitions access */
|
||
|
for (i = 1 ; i <= 15 ; i ++)
|
||
|
{
|
||
|
char path[64];
|
||
|
snprintf(path, sizeof(path), "/dev/hda%d", i);
|
||
|
if (fork() == 0)
|
||
|
{
|
||
|
test_device(path, i);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bochs_printf("Bye from blktest\n");
|
||
|
return 0;
|
||
|
}
|