filter: use libblockdriver
Also work around clock_t now being unsigned. Change-Id: Ifbca2482e996ddca58036d45f557165e636fb3fa
This commit is contained in:
parent
665198b4c2
commit
df724f2e14
@ -583,7 +583,7 @@ static int flt_receive(message *mess, int which)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(mess->m_source == CLOCK && is_ipc_notify(ipc_status)) {
|
if(mess->m_source == CLOCK && is_ipc_notify(ipc_status)) {
|
||||||
if (mess->NOTIFY_TIMESTAMP < flt_alarm(-1)) {
|
if (mess->NOTIFY_TIMESTAMP < flt_alarm((clock_t) -1)) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("Filter: SKIPPING old alarm "
|
printf("Filter: SKIPPING old alarm "
|
||||||
"notification\n");
|
"notification\n");
|
||||||
|
@ -63,12 +63,6 @@ static struct optset optset_table[] = {
|
|||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Request message. */
|
|
||||||
static message m_in;
|
|
||||||
static endpoint_t who_e; /* m_source */
|
|
||||||
static long req_id; /* BDEV_ID */
|
|
||||||
static cp_grant_id_t grant_id; /* BDEV_GRANT */
|
|
||||||
|
|
||||||
/* Data buffers. */
|
/* Data buffers. */
|
||||||
static char *buf_array, *buffer; /* contiguous buffer */
|
static char *buf_array, *buffer; /* contiguous buffer */
|
||||||
|
|
||||||
@ -77,26 +71,46 @@ static void sef_local_startup(void);
|
|||||||
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
|
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
|
||||||
static void sef_cb_signal_handler(int signo);
|
static void sef_cb_signal_handler(int signo);
|
||||||
|
|
||||||
/*===========================================================================*
|
static int filter_open(devminor_t minor, int access);
|
||||||
* carry *
|
static int filter_close(devminor_t minor);
|
||||||
*===========================================================================*/
|
static ssize_t filter_transfer(devminor_t minor, int do_write, u64_t pos,
|
||||||
static int carry(size_t size, int flag_rw)
|
endpoint_t endpt, iovec_t *iov, unsigned int count, int flags);
|
||||||
{
|
static int filter_ioctl(devminor_t minor, unsigned long request,
|
||||||
/* Carry data between caller proc and filter.
|
endpoint_t endpt, cp_grant_id_t grant, endpoint_t user_endpt);
|
||||||
*/
|
static void filter_other(message *m, int ipc_status);
|
||||||
|
|
||||||
if (flag_rw == FLT_WRITE)
|
static struct blockdriver filter_tab = {
|
||||||
return sys_safecopyfrom(who_e, grant_id, 0,
|
.bdr_type = BLOCKDRIVER_TYPE_OTHER,
|
||||||
(vir_bytes) buffer, size);
|
.bdr_open = filter_open,
|
||||||
else
|
.bdr_close = filter_close,
|
||||||
return sys_safecopyto(who_e, grant_id, 0,
|
.bdr_transfer = filter_transfer,
|
||||||
(vir_bytes) buffer, size);
|
.bdr_ioctl = filter_ioctl,
|
||||||
|
.bdr_other = filter_other
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* filter_open *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int filter_open(devminor_t UNUSED(minor), int UNUSED(access))
|
||||||
|
{
|
||||||
|
/* Open is a noop for filter. */
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* filter_close *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int filter_close(devminor_t UNUSED(minor))
|
||||||
|
{
|
||||||
|
/* Close is a noop for filter. */
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* vcarry *
|
* vcarry *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int vcarry(int grants, iovec_t *iov, int flag_rw, size_t size)
|
static int vcarry(endpoint_t endpt, unsigned int grants, iovec_t *iov,
|
||||||
|
int do_write, size_t size)
|
||||||
{
|
{
|
||||||
/* Carry data between caller proc and filter, through grant-vector.
|
/* Carry data between caller proc and filter, through grant-vector.
|
||||||
*/
|
*/
|
||||||
@ -108,12 +122,12 @@ static int vcarry(int grants, iovec_t *iov, int flag_rw, size_t size)
|
|||||||
for(i = 0; i < grants && size > 0; i++) {
|
for(i = 0; i < grants && size > 0; i++) {
|
||||||
bytes = MIN(size, iov[i].iov_size);
|
bytes = MIN(size, iov[i].iov_size);
|
||||||
|
|
||||||
if (flag_rw == FLT_WRITE)
|
if (do_write)
|
||||||
r = sys_safecopyfrom(who_e,
|
r = sys_safecopyfrom(endpt,
|
||||||
(vir_bytes) iov[i].iov_addr, 0,
|
(vir_bytes) iov[i].iov_addr, 0,
|
||||||
(vir_bytes) bufp, bytes);
|
(vir_bytes) bufp, bytes);
|
||||||
else
|
else
|
||||||
r = sys_safecopyto(who_e,
|
r = sys_safecopyto(endpt,
|
||||||
(vir_bytes) iov[i].iov_addr, 0,
|
(vir_bytes) iov[i].iov_addr, 0,
|
||||||
(vir_bytes) bufp, bytes);
|
(vir_bytes) bufp, bytes);
|
||||||
|
|
||||||
@ -127,76 +141,19 @@ static int vcarry(int grants, iovec_t *iov, int flag_rw, size_t size)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* do_rdwt *
|
|
||||||
*===========================================================================*/
|
|
||||||
static int do_rdwt(int flag_rw)
|
|
||||||
{
|
|
||||||
size_t size, size_ret;
|
|
||||||
u64_t pos;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
pos = make64(m_in.BDEV_POS_LO, m_in.BDEV_POS_HI);
|
|
||||||
size = m_in.BDEV_COUNT;
|
|
||||||
|
|
||||||
if (rem64u(pos, SECTOR_SIZE) != 0 || size % SECTOR_SIZE != 0) {
|
|
||||||
printf("Filter: unaligned request from caller!\n");
|
|
||||||
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = flt_malloc(size, buf_array, BUF_SIZE);
|
|
||||||
|
|
||||||
if(flag_rw == FLT_WRITE)
|
|
||||||
carry(size, flag_rw);
|
|
||||||
|
|
||||||
reset_kills();
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
size_ret = size;
|
|
||||||
r = transfer(pos, buffer, &size_ret, flag_rw);
|
|
||||||
if(r != RET_REDO)
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
printf("Filter: transfer yielded RET_REDO, checking drivers\n");
|
|
||||||
#endif
|
|
||||||
if((r = check_driver(DRIVER_MAIN)) != OK) break;
|
|
||||||
if((r = check_driver(DRIVER_BACKUP)) != OK) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(r == OK && flag_rw == FLT_READ)
|
|
||||||
carry(size_ret, flag_rw);
|
|
||||||
|
|
||||||
flt_free(buffer, size, buf_array);
|
|
||||||
|
|
||||||
if (r != OK)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return size_ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_vrdwt *
|
* filter_transfer *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int do_vrdwt(int flag_rw)
|
static ssize_t filter_transfer(devminor_t UNUSED(minor), int do_write,
|
||||||
|
u64_t pos, endpoint_t endpt, iovec_t *iov, unsigned int count,
|
||||||
|
int UNUSED(flags))
|
||||||
{
|
{
|
||||||
size_t size, size_ret;
|
size_t size, size_ret;
|
||||||
int grants;
|
|
||||||
int r, i;
|
int r, i;
|
||||||
u64_t pos;
|
|
||||||
iovec_t iov_proc[NR_IOREQS];
|
|
||||||
|
|
||||||
/* Extract informations. */
|
for(size = 0, i = 0; i < count; i++)
|
||||||
grants = m_in.BDEV_COUNT;
|
size += iov[i].iov_size;
|
||||||
if((r = sys_safecopyfrom(who_e, grant_id, 0, (vir_bytes) iov_proc,
|
|
||||||
grants * sizeof(iovec_t))) != OK) {
|
|
||||||
panic("copying in grant vector failed: %d", r);
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = make64(m_in.BDEV_POS_LO, m_in.BDEV_POS_HI);
|
|
||||||
for(size = 0, i = 0; i < grants; i++)
|
|
||||||
size += iov_proc[i].iov_size;
|
|
||||||
|
|
||||||
if (rem64u(pos, SECTOR_SIZE) != 0 || size % SECTOR_SIZE != 0) {
|
if (rem64u(pos, SECTOR_SIZE) != 0 || size % SECTOR_SIZE != 0) {
|
||||||
printf("Filter: unaligned request from caller!\n");
|
printf("Filter: unaligned request from caller!\n");
|
||||||
@ -205,14 +162,15 @@ static int do_vrdwt(int flag_rw)
|
|||||||
|
|
||||||
buffer = flt_malloc(size, buf_array, BUF_SIZE);
|
buffer = flt_malloc(size, buf_array, BUF_SIZE);
|
||||||
|
|
||||||
if(flag_rw == FLT_WRITE)
|
if (do_write)
|
||||||
vcarry(grants, iov_proc, flag_rw, size);
|
vcarry(endpt, count, iov, do_write, size);
|
||||||
|
|
||||||
reset_kills();
|
reset_kills();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_ret = size;
|
size_ret = size;
|
||||||
r = transfer(pos, buffer, &size_ret, flag_rw);
|
r = transfer(pos, buffer, &size_ret,
|
||||||
|
do_write ? FLT_WRITE : FLT_READ);
|
||||||
if(r != RET_REDO)
|
if(r != RET_REDO)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -228,8 +186,8 @@ static int do_vrdwt(int flag_rw)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flag_rw == FLT_READ)
|
if (!do_write)
|
||||||
vcarry(grants, iov_proc, flag_rw, size_ret);
|
vcarry(endpt, count, iov, do_write, size_ret);
|
||||||
|
|
||||||
flt_free(buffer, size, buf_array);
|
flt_free(buffer, size, buf_array);
|
||||||
|
|
||||||
@ -237,13 +195,14 @@ static int do_vrdwt(int flag_rw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_ioctl *
|
* filter_ioctl *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int do_ioctl(message *m)
|
static int filter_ioctl(devminor_t UNUSED(minor), unsigned long request,
|
||||||
|
endpoint_t endpt, cp_grant_id_t grant, endpoint_t UNUSED(user_endpt))
|
||||||
{
|
{
|
||||||
struct part_geom sizepart;
|
struct part_geom sizepart;
|
||||||
|
|
||||||
switch(m->BDEV_REQUEST) {
|
switch (request) {
|
||||||
case DIOCSETP:
|
case DIOCSETP:
|
||||||
case DIOCTIMEOUT:
|
case DIOCTIMEOUT:
|
||||||
case DIOCOPENCT:
|
case DIOCOPENCT:
|
||||||
@ -258,8 +217,7 @@ static int do_ioctl(message *m)
|
|||||||
*/
|
*/
|
||||||
sizepart.size = convert(get_raw_size());
|
sizepart.size = convert(get_raw_size());
|
||||||
|
|
||||||
if(sys_safecopyto(who_e, (vir_bytes) grant_id, 0,
|
if (sys_safecopyto(endpt, grant, 0, (vir_bytes) &sizepart,
|
||||||
(vir_bytes) &sizepart,
|
|
||||||
sizeof(struct part_geom)) != OK) {
|
sizeof(struct part_geom)) != OK) {
|
||||||
printf("Filter: DIOCGETP safecopyto failed\n");
|
printf("Filter: DIOCGETP safecopyto failed\n");
|
||||||
return EIO;
|
return EIO;
|
||||||
@ -267,14 +225,24 @@ static int do_ioctl(message *m)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("Filter: unknown ioctl request: %ld!\n",
|
printf("Filter: unknown ioctl request: %ld!\n", request);
|
||||||
m->BDEV_REQUEST);
|
|
||||||
return ENOTTY;
|
return ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* filter_other *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void filter_other(message *m, int ipc_status)
|
||||||
|
{
|
||||||
|
/* Process other messages. */
|
||||||
|
if (m->m_source == DS_PROC_NR && is_ipc_notify(ipc_status)) {
|
||||||
|
ds_event();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* parse_arguments *
|
* parse_arguments *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
@ -371,53 +339,7 @@ int main(int argc, char *argv[])
|
|||||||
env_setargs(argc, argv);
|
env_setargs(argc, argv);
|
||||||
sef_local_startup();
|
sef_local_startup();
|
||||||
|
|
||||||
for (;;) {
|
blockdriver_task(&filter_tab);
|
||||||
/* Wait for request. */
|
|
||||||
if(driver_receive(ANY, &m_in, &ipc_status) != OK) {
|
|
||||||
panic("driver_receive failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG2
|
|
||||||
printf("Filter: got request %d from %d\n",
|
|
||||||
m_in.m_type, m_in.m_source);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(m_in.m_source == DS_PROC_NR && is_ipc_notify(ipc_status)) {
|
|
||||||
ds_event();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
who_e = m_in.m_source;
|
|
||||||
req_id = m_in.BDEV_ID;
|
|
||||||
grant_id = m_in.BDEV_GRANT;
|
|
||||||
size = 0;
|
|
||||||
|
|
||||||
/* Forword the request message to the drivers. */
|
|
||||||
switch(m_in.m_type) {
|
|
||||||
case BDEV_OPEN: /* open/close is a noop for filter. */
|
|
||||||
case BDEV_CLOSE: r = OK; break;
|
|
||||||
case BDEV_READ: r = do_rdwt(FLT_READ); break;
|
|
||||||
case BDEV_WRITE: r = do_rdwt(FLT_WRITE); break;
|
|
||||||
case BDEV_GATHER: r = do_vrdwt(FLT_READ); break;
|
|
||||||
case BDEV_SCATTER: r = do_vrdwt(FLT_WRITE); break;
|
|
||||||
case BDEV_IOCTL: r = do_ioctl(&m_in); break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("Filter: ignoring unknown request %d from %d\n",
|
|
||||||
m_in.m_type, m_in.m_source);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG2
|
|
||||||
printf("Filter: replying with code %d\n", r);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Send back reply message. */
|
|
||||||
m_out.m_type = BDEV_REPLY;
|
|
||||||
m_out.BDEV_ID = req_id;
|
|
||||||
m_out.BDEV_STATUS = r;
|
|
||||||
send(who_e, &m_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -490,4 +412,3 @@ static void sef_cb_signal_handler(int signo)
|
|||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ clock_t flt_alarm(clock_t dt)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(dt < 0)
|
if((int) dt < 0)
|
||||||
return next_alarm;
|
return next_alarm;
|
||||||
|
|
||||||
r = sys_setalarm(dt, 0);
|
r = sys_setalarm(dt, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user