2005-04-21 16:53:53 +02:00
|
|
|
/* this file contains the interface of the network software with the file
|
|
|
|
* system.
|
|
|
|
*
|
|
|
|
* Copyright 1995 Philip Homburg
|
|
|
|
*
|
|
|
|
* The valid messages and their parameters are:
|
|
|
|
*
|
|
|
|
* Requests:
|
|
|
|
*
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
* m_type DEVICE USER_ENDPT COUNT
|
2010-01-05 20:39:27 +01:00
|
|
|
* --------------------------------------------------
|
|
|
|
* | DEV_OPEN | minor dev | proc nr | mode |
|
|
|
|
* |-------------+-----------+-----------+----------+
|
|
|
|
* | DEV_CLOSE | minor dev | proc nr | |
|
|
|
|
* |-------------+-----------+-----------+----------+
|
2005-04-21 16:53:53 +02:00
|
|
|
*
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
* m_type DEVICE USER_ENDPT COUNT IO_GRANT
|
2010-01-05 20:39:27 +01:00
|
|
|
* ---------------------------------------------------------------
|
|
|
|
* | DEV_READ_S | minor dev | proc nr | count | grant ID |
|
|
|
|
* |-------------+-----------+-----------+-----------+-----------|
|
|
|
|
* | DEV_WRITE_S | minor dev | proc nr | count | grant ID |
|
|
|
|
* |-------------+-----------+-----------+-----------+-----------|
|
|
|
|
* | DEV_IOCTL_S | minor dev | proc nr | command | grant ID |
|
|
|
|
* |-------------+-----------+-----------+-----------+-----------|
|
|
|
|
* | DEV_SELECT | minor dev | ops | | |
|
|
|
|
* |-------------+-----------+-----------+-----------+-----------|
|
2005-04-21 16:53:53 +02:00
|
|
|
*
|
2010-01-05 20:39:27 +01:00
|
|
|
* m_type
|
|
|
|
* --------------|
|
|
|
|
* | DEV_STATUS |
|
|
|
|
* |-------------|
|
|
|
|
*
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
* m_type DEVICE USER_ENDPT COUNT
|
2010-01-05 20:39:27 +01:00
|
|
|
* --------------------------------------------------|
|
|
|
|
* | CANCEL | minor dev | proc nr | mode |
|
|
|
|
* |-------------+-----------+-----------+-----------|
|
2005-04-21 16:53:53 +02:00
|
|
|
*
|
|
|
|
* Replies:
|
|
|
|
*
|
2010-01-05 20:39:27 +01:00
|
|
|
* m_type REP_ENDPT REP_STATUS REP_IO_GRANT
|
|
|
|
* -------------------------------------------------------|
|
|
|
|
* | TASK_REPLY | proc nr | status | grant ID |
|
|
|
|
* |---------------+-----------+-----------+--------------|
|
|
|
|
*
|
|
|
|
* m_type REP_ENDPT REP_STATUS REP_IO_GRANT
|
|
|
|
* ----------------+-----------+--------------------------|
|
|
|
|
* | DEV_REVIVE | proc nr | | grant ID |
|
|
|
|
* |---------------+-----------+-----------+--------------|
|
|
|
|
* | DEV_IO_READY | minor dev | sel ops | |
|
|
|
|
* |---------------+-----------+-----------+--------------|
|
|
|
|
* | DEV_NO_STATUS | | | |
|
|
|
|
* |---------------+-----------+-----------+--------------|
|
2005-04-21 16:53:53 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "inet.h"
|
|
|
|
|
2005-06-28 17:19:58 +02:00
|
|
|
#include <sys/svrctl.h>
|
2005-04-21 16:53:53 +02:00
|
|
|
#include <minix/callnr.h>
|
|
|
|
|
|
|
|
#include "mq.h"
|
2005-06-28 17:19:58 +02:00
|
|
|
#include "qp.h"
|
2005-04-21 16:53:53 +02:00
|
|
|
#include "proto.h"
|
|
|
|
#include "generic/type.h"
|
|
|
|
|
|
|
|
#include "generic/assert.h"
|
|
|
|
#include "generic/buf.h"
|
2005-06-28 17:19:58 +02:00
|
|
|
#include "generic/event.h"
|
2005-04-21 16:53:53 +02:00
|
|
|
#include "generic/sr.h"
|
2005-06-28 17:19:58 +02:00
|
|
|
#include "sr_int.h"
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
THIS_FILE
|
|
|
|
|
2005-06-28 17:19:58 +02:00
|
|
|
PUBLIC sr_fd_t sr_fd_table[FD_NR];
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2005-06-28 17:19:58 +02:00
|
|
|
PRIVATE mq_t *repl_queue, *repl_queue_tail;
|
2010-01-05 20:39:27 +01:00
|
|
|
PRIVATE struct vscp_vec s_cp_req[SCPVEC_NR];
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
FORWARD _PROTOTYPE ( int sr_open, (message *m) );
|
|
|
|
FORWARD _PROTOTYPE ( void sr_close, (message *m) );
|
|
|
|
FORWARD _PROTOTYPE ( int sr_rwio, (mq_t *m) );
|
2005-06-28 17:19:58 +02:00
|
|
|
FORWARD _PROTOTYPE ( int sr_restart_read, (sr_fd_t *fdp) );
|
|
|
|
FORWARD _PROTOTYPE ( int sr_restart_write, (sr_fd_t *fdp) );
|
|
|
|
FORWARD _PROTOTYPE ( int sr_restart_ioctl, (sr_fd_t *fdp) );
|
2005-04-21 16:53:53 +02:00
|
|
|
FORWARD _PROTOTYPE ( int sr_cancel, (message *m) );
|
2005-06-28 17:19:58 +02:00
|
|
|
FORWARD _PROTOTYPE ( int sr_select, (message *m) );
|
2005-07-27 18:35:16 +02:00
|
|
|
FORWARD _PROTOTYPE ( void sr_status, (message *m) );
|
|
|
|
FORWARD _PROTOTYPE ( void sr_reply_, (mq_t *m, int reply, int is_revive) );
|
2005-04-21 16:53:53 +02:00
|
|
|
FORWARD _PROTOTYPE ( sr_fd_t *sr_getchannel, (int minor));
|
2009-11-28 14:28:55 +01:00
|
|
|
FORWARD _PROTOTYPE ( acc_t *sr_get_userdata, (int fd, size_t offset,
|
|
|
|
size_t count, int for_ioctl) );
|
|
|
|
FORWARD _PROTOTYPE ( int sr_put_userdata, (int fd, size_t offset,
|
2005-04-21 16:53:53 +02:00
|
|
|
acc_t *data, int for_ioctl) );
|
2005-06-28 17:19:58 +02:00
|
|
|
FORWARD _PROTOTYPE (void sr_select_res, (int fd, unsigned ops) );
|
2005-04-21 16:53:53 +02:00
|
|
|
FORWARD _PROTOTYPE ( int sr_repl_queue, (int proc, int ref, int operation) );
|
2005-08-08 17:49:16 +02:00
|
|
|
FORWARD _PROTOTYPE ( int walk_queue, (sr_fd_t *sr_fd, mq_t **q_head_ptr,
|
2005-07-27 18:35:16 +02:00
|
|
|
mq_t **q_tail_ptr, int type, int proc_nr, int ref, int first_flag) );
|
2005-06-28 17:19:58 +02:00
|
|
|
FORWARD _PROTOTYPE ( void sr_event, (event_t *evp, ev_arg_t arg) );
|
2010-03-30 16:07:15 +02:00
|
|
|
FORWARD _PROTOTYPE ( int cp_u2b, (endpoint_t proc, cp_grant_id_t gid,
|
|
|
|
vir_bytes offset, acc_t **var_acc_ptr, int size) );
|
|
|
|
FORWARD _PROTOTYPE ( int cp_b2u, (acc_t *acc_ptr, endpoint_t proc,
|
|
|
|
cp_grant_id_t gid, vir_bytes offset) );
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
PUBLIC void sr_init()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; i<FD_NR; i++)
|
2005-06-28 17:19:58 +02:00
|
|
|
{
|
2005-04-21 16:53:53 +02:00
|
|
|
sr_fd_table[i].srf_flags= SFF_FREE;
|
2005-06-28 17:19:58 +02:00
|
|
|
ev_init(&sr_fd_table[i].srf_ioctl_ev);
|
|
|
|
ev_init(&sr_fd_table[i].srf_read_ev);
|
|
|
|
ev_init(&sr_fd_table[i].srf_write_ev);
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
repl_queue= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
PUBLIC void sr_rec(m)
|
|
|
|
mq_t *m;
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
int send_reply, free_mess;
|
|
|
|
|
|
|
|
if (repl_queue)
|
|
|
|
{
|
2010-01-05 20:39:27 +01:00
|
|
|
if (m->mq_mess.m_type == CANCEL)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
result= sr_repl_queue(m->mq_mess.USER_ENDPT,
|
2006-06-26 13:17:19 +02:00
|
|
|
(int)m->mq_mess.IO_GRANT, 0);
|
2010-01-05 20:39:27 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
mq_free(m);
|
|
|
|
return; /* canceled request in queue */
|
|
|
|
}
|
|
|
|
}
|
2005-07-27 18:35:16 +02:00
|
|
|
#if 0
|
2005-04-21 16:53:53 +02:00
|
|
|
else
|
|
|
|
sr_repl_queue(ANY, 0, 0);
|
2005-07-27 18:35:16 +02:00
|
|
|
#endif
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (m->mq_mess.m_type)
|
|
|
|
{
|
|
|
|
case DEV_OPEN:
|
|
|
|
result= sr_open(&m->mq_mess);
|
|
|
|
send_reply= 1;
|
|
|
|
free_mess= 1;
|
|
|
|
break;
|
|
|
|
case DEV_CLOSE:
|
|
|
|
sr_close(&m->mq_mess);
|
|
|
|
result= OK;
|
|
|
|
send_reply= 1;
|
|
|
|
free_mess= 1;
|
|
|
|
break;
|
2006-06-26 13:17:19 +02:00
|
|
|
case DEV_READ_S:
|
|
|
|
case DEV_WRITE_S:
|
|
|
|
case DEV_IOCTL_S:
|
2010-01-05 20:39:27 +01:00
|
|
|
result= sr_rwio(m);
|
2006-06-26 13:17:19 +02:00
|
|
|
assert(result == OK || result == SUSPEND);
|
|
|
|
send_reply= (result == SUSPEND);
|
|
|
|
free_mess= 0;
|
|
|
|
break;
|
2010-01-05 20:39:27 +01:00
|
|
|
case CANCEL:
|
2005-04-21 16:53:53 +02:00
|
|
|
result= sr_cancel(&m->mq_mess);
|
|
|
|
assert(result == OK || result == EINTR);
|
|
|
|
send_reply= (result == EINTR);
|
|
|
|
free_mess= 1;
|
|
|
|
m->mq_mess.m_type= 0;
|
2005-06-28 17:19:58 +02:00
|
|
|
break;
|
|
|
|
case DEV_SELECT:
|
|
|
|
result= sr_select(&m->mq_mess);
|
|
|
|
send_reply= 1;
|
|
|
|
free_mess= 1;
|
2005-04-21 16:53:53 +02:00
|
|
|
break;
|
2005-07-27 18:35:16 +02:00
|
|
|
case DEV_STATUS:
|
|
|
|
sr_status(&m->mq_mess);
|
2010-01-27 11:23:58 +01:00
|
|
|
result= OK; /* Satisfy lint. */
|
2005-07-27 18:35:16 +02:00
|
|
|
send_reply= 0;
|
|
|
|
free_mess= 1;
|
|
|
|
break;
|
2005-04-21 16:53:53 +02:00
|
|
|
default:
|
|
|
|
ip_panic(("unknown message, from %d, type %d",
|
|
|
|
m->mq_mess.m_source, m->mq_mess.m_type));
|
|
|
|
}
|
|
|
|
if (send_reply)
|
|
|
|
{
|
2005-07-27 18:35:16 +02:00
|
|
|
sr_reply_(m, result, FALSE /* !is_revive */);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
if (free_mess)
|
|
|
|
mq_free(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
PUBLIC void sr_add_minor(minor, port, openf, closef, readf, writef,
|
2005-06-28 17:19:58 +02:00
|
|
|
ioctlf, cancelf, selectf)
|
2005-04-21 16:53:53 +02:00
|
|
|
int minor;
|
|
|
|
int port;
|
|
|
|
sr_open_t openf;
|
|
|
|
sr_close_t closef;
|
|
|
|
sr_read_t readf;
|
|
|
|
sr_write_t writef;
|
|
|
|
sr_ioctl_t ioctlf;
|
|
|
|
sr_cancel_t cancelf;
|
2005-06-28 17:19:58 +02:00
|
|
|
sr_select_t selectf;
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
|
|
|
|
assert (minor>=0 && minor<FD_NR);
|
|
|
|
|
|
|
|
sr_fd= &sr_fd_table[minor];
|
|
|
|
|
|
|
|
assert(!(sr_fd->srf_flags & SFF_INUSE));
|
|
|
|
|
|
|
|
sr_fd->srf_flags= SFF_INUSE | SFF_MINOR;
|
|
|
|
sr_fd->srf_port= port;
|
|
|
|
sr_fd->srf_open= openf;
|
|
|
|
sr_fd->srf_close= closef;
|
|
|
|
sr_fd->srf_write= writef;
|
|
|
|
sr_fd->srf_read= readf;
|
|
|
|
sr_fd->srf_ioctl= ioctlf;
|
|
|
|
sr_fd->srf_cancel= cancelf;
|
2005-06-28 17:19:58 +02:00
|
|
|
sr_fd->srf_select= selectf;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE int sr_open(m)
|
|
|
|
message *m;
|
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
int minor= m->DEVICE;
|
2005-04-21 16:53:53 +02:00
|
|
|
int i, fd;
|
|
|
|
|
|
|
|
if (minor<0 || minor>FD_NR)
|
|
|
|
{
|
|
|
|
DBLOCK(1, printf("replying EINVAL\n"));
|
|
|
|
return EINVAL;
|
|
|
|
}
|
|
|
|
if (!(sr_fd_table[minor].srf_flags & SFF_MINOR))
|
|
|
|
{
|
|
|
|
DBLOCK(1, printf("replying ENXIO\n"));
|
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
for (i=0; i<FD_NR && (sr_fd_table[i].srf_flags & SFF_INUSE); i++);
|
|
|
|
|
|
|
|
if (i>=FD_NR)
|
|
|
|
{
|
|
|
|
DBLOCK(1, printf("replying ENFILE\n"));
|
|
|
|
return ENFILE;
|
|
|
|
}
|
|
|
|
|
|
|
|
sr_fd= &sr_fd_table[i];
|
|
|
|
*sr_fd= sr_fd_table[minor];
|
|
|
|
sr_fd->srf_flags= SFF_INUSE;
|
|
|
|
fd= (*sr_fd->srf_open)(sr_fd->srf_port, i, sr_get_userdata,
|
2005-06-28 17:19:58 +02:00
|
|
|
sr_put_userdata, 0 /* no put_pkt */, sr_select_res);
|
2005-04-21 16:53:53 +02:00
|
|
|
if (fd<0)
|
|
|
|
{
|
|
|
|
sr_fd->srf_flags= SFF_FREE;
|
|
|
|
DBLOCK(1, printf("replying %d\n", fd));
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
sr_fd->srf_fd= fd;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE void sr_close(m)
|
|
|
|
message *m;
|
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
sr_fd= sr_getchannel(m->DEVICE);
|
2005-04-21 16:53:53 +02:00
|
|
|
assert (sr_fd);
|
|
|
|
|
2005-06-28 17:19:58 +02:00
|
|
|
if (sr_fd->srf_flags & SFF_BUSY)
|
|
|
|
ip_panic(("close on busy channel"));
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
assert (!(sr_fd->srf_flags & SFF_MINOR));
|
|
|
|
(*sr_fd->srf_close)(sr_fd->srf_fd);
|
|
|
|
sr_fd->srf_flags= SFF_FREE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE int sr_rwio(m)
|
|
|
|
mq_t *m;
|
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
mq_t **q_head_ptr, **q_tail_ptr;
|
2005-07-27 18:35:16 +02:00
|
|
|
int ip_flag, susp_flag, first_flag;
|
2005-04-21 16:53:53 +02:00
|
|
|
int r;
|
|
|
|
ioreq_t request;
|
|
|
|
size_t size;
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
sr_fd= sr_getchannel(m->mq_mess.DEVICE);
|
2006-06-26 13:17:19 +02:00
|
|
|
assert (sr_fd);
|
|
|
|
|
|
|
|
switch(m->mq_mess.m_type)
|
|
|
|
{
|
|
|
|
case DEV_READ_S:
|
|
|
|
q_head_ptr= &sr_fd->srf_read_q;
|
|
|
|
q_tail_ptr= &sr_fd->srf_read_q_tail;
|
|
|
|
ip_flag= SFF_READ_IP;
|
|
|
|
susp_flag= SFF_READ_SUSP;
|
|
|
|
first_flag= SFF_READ_FIRST;
|
|
|
|
break;
|
|
|
|
case DEV_WRITE_S:
|
|
|
|
q_head_ptr= &sr_fd->srf_write_q;
|
|
|
|
q_tail_ptr= &sr_fd->srf_write_q_tail;
|
|
|
|
ip_flag= SFF_WRITE_IP;
|
|
|
|
susp_flag= SFF_WRITE_SUSP;
|
|
|
|
first_flag= SFF_WRITE_FIRST;
|
|
|
|
break;
|
|
|
|
case DEV_IOCTL_S:
|
|
|
|
q_head_ptr= &sr_fd->srf_ioctl_q;
|
|
|
|
q_tail_ptr= &sr_fd->srf_ioctl_q_tail;
|
|
|
|
ip_flag= SFF_IOCTL_IP;
|
|
|
|
susp_flag= SFF_IOCTL_SUSP;
|
|
|
|
first_flag= SFF_IOCTL_FIRST;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ip_panic(("illegal case entry"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sr_fd->srf_flags & ip_flag)
|
|
|
|
{
|
|
|
|
assert(sr_fd->srf_flags & susp_flag);
|
|
|
|
assert(*q_head_ptr);
|
|
|
|
|
|
|
|
(*q_tail_ptr)->mq_next= m;
|
|
|
|
*q_tail_ptr= m;
|
|
|
|
return SUSPEND;
|
|
|
|
}
|
|
|
|
assert(!*q_head_ptr);
|
|
|
|
|
|
|
|
*q_tail_ptr= *q_head_ptr= m;
|
|
|
|
sr_fd->srf_flags |= ip_flag;
|
|
|
|
assert(!(sr_fd->srf_flags & first_flag));
|
|
|
|
sr_fd->srf_flags |= first_flag;
|
|
|
|
|
|
|
|
switch(m->mq_mess.m_type)
|
|
|
|
{
|
|
|
|
case DEV_READ_S:
|
|
|
|
r= (*sr_fd->srf_read)(sr_fd->srf_fd,
|
2010-01-05 20:39:27 +01:00
|
|
|
m->mq_mess.COUNT);
|
2006-06-26 13:17:19 +02:00
|
|
|
break;
|
|
|
|
case DEV_WRITE_S:
|
|
|
|
r= (*sr_fd->srf_write)(sr_fd->srf_fd,
|
2010-01-05 20:39:27 +01:00
|
|
|
m->mq_mess.COUNT);
|
2006-06-26 13:17:19 +02:00
|
|
|
break;
|
|
|
|
case DEV_IOCTL_S:
|
2010-01-05 20:39:27 +01:00
|
|
|
request= m->mq_mess.REQUEST;
|
2006-06-26 13:17:19 +02:00
|
|
|
size= (request >> 16) & _IOCPARM_MASK;
|
|
|
|
if (size>MAX_IOCTL_S)
|
|
|
|
{
|
|
|
|
DBLOCK(1, printf("replying EINVAL\n"));
|
|
|
|
r= sr_put_userdata(sr_fd-sr_fd_table, EINVAL,
|
|
|
|
NULL, 1);
|
|
|
|
assert(r == OK);
|
|
|
|
assert(sr_fd->srf_flags & first_flag);
|
|
|
|
sr_fd->srf_flags &= ~first_flag;
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
r= (*sr_fd->srf_ioctl)(sr_fd->srf_fd, request);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ip_panic(("illegal case entry"));
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(sr_fd->srf_flags & first_flag);
|
|
|
|
sr_fd->srf_flags &= ~first_flag;
|
|
|
|
|
|
|
|
assert(r == OK || r == SUSPEND ||
|
|
|
|
(printf("r= %d\n", r), 0));
|
|
|
|
if (r == SUSPEND)
|
|
|
|
sr_fd->srf_flags |= susp_flag;
|
|
|
|
else
|
|
|
|
mq_free(m);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2005-06-28 17:19:58 +02:00
|
|
|
PRIVATE int sr_restart_read(sr_fd)
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
{
|
|
|
|
mq_t *mp;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
mp= sr_fd->srf_read_q;
|
|
|
|
assert(mp);
|
|
|
|
|
|
|
|
if (sr_fd->srf_flags & SFF_READ_IP)
|
|
|
|
{
|
|
|
|
assert(sr_fd->srf_flags & SFF_READ_SUSP);
|
|
|
|
return SUSPEND;
|
|
|
|
}
|
|
|
|
sr_fd->srf_flags |= SFF_READ_IP;
|
|
|
|
|
|
|
|
r= (*sr_fd->srf_read)(sr_fd->srf_fd,
|
2010-01-05 20:39:27 +01:00
|
|
|
mp->mq_mess.COUNT);
|
2005-06-28 17:19:58 +02:00
|
|
|
|
|
|
|
assert(r == OK || r == SUSPEND ||
|
|
|
|
(printf("r= %d\n", r), 0));
|
|
|
|
if (r == SUSPEND)
|
|
|
|
sr_fd->srf_flags |= SFF_READ_SUSP;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE int sr_restart_write(sr_fd)
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
{
|
|
|
|
mq_t *mp;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
mp= sr_fd->srf_write_q;
|
|
|
|
assert(mp);
|
|
|
|
|
|
|
|
if (sr_fd->srf_flags & SFF_WRITE_IP)
|
|
|
|
{
|
|
|
|
assert(sr_fd->srf_flags & SFF_WRITE_SUSP);
|
|
|
|
return SUSPEND;
|
|
|
|
}
|
|
|
|
sr_fd->srf_flags |= SFF_WRITE_IP;
|
|
|
|
|
|
|
|
r= (*sr_fd->srf_write)(sr_fd->srf_fd,
|
2010-01-05 20:39:27 +01:00
|
|
|
mp->mq_mess.COUNT);
|
2005-06-28 17:19:58 +02:00
|
|
|
|
|
|
|
assert(r == OK || r == SUSPEND ||
|
|
|
|
(printf("r= %d\n", r), 0));
|
|
|
|
if (r == SUSPEND)
|
|
|
|
sr_fd->srf_flags |= SFF_WRITE_SUSP;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE int sr_restart_ioctl(sr_fd)
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
{
|
|
|
|
mq_t *mp;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
mp= sr_fd->srf_ioctl_q;
|
|
|
|
assert(mp);
|
|
|
|
|
|
|
|
if (sr_fd->srf_flags & SFF_IOCTL_IP)
|
|
|
|
{
|
|
|
|
assert(sr_fd->srf_flags & SFF_IOCTL_SUSP);
|
|
|
|
return SUSPEND;
|
|
|
|
}
|
|
|
|
sr_fd->srf_flags |= SFF_IOCTL_IP;
|
|
|
|
|
|
|
|
r= (*sr_fd->srf_ioctl)(sr_fd->srf_fd,
|
2010-01-05 20:39:27 +01:00
|
|
|
mp->mq_mess.COUNT);
|
2005-06-28 17:19:58 +02:00
|
|
|
|
|
|
|
assert(r == OK || r == SUSPEND ||
|
|
|
|
(printf("r= %d\n", r), 0));
|
|
|
|
if (r == SUSPEND)
|
|
|
|
sr_fd->srf_flags |= SFF_IOCTL_SUSP;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
PRIVATE int sr_cancel(m)
|
|
|
|
message *m;
|
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
2005-06-28 17:19:58 +02:00
|
|
|
int result;
|
2010-01-14 14:53:12 +01:00
|
|
|
int proc_nr, ref;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
result=EINTR;
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
proc_nr= m->USER_ENDPT;
|
2006-06-26 13:17:19 +02:00
|
|
|
ref= (int)m->IO_GRANT;
|
2010-01-05 20:39:27 +01:00
|
|
|
sr_fd= sr_getchannel(m->DEVICE);
|
2005-04-21 16:53:53 +02:00
|
|
|
assert (sr_fd);
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
result= walk_queue(sr_fd, &sr_fd->srf_ioctl_q,
|
|
|
|
&sr_fd->srf_ioctl_q_tail, SR_CANCEL_IOCTL,
|
|
|
|
proc_nr, ref, SFF_IOCTL_FIRST);
|
|
|
|
if (result != EAGAIN)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
result= walk_queue(sr_fd, &sr_fd->srf_read_q,
|
|
|
|
&sr_fd->srf_read_q_tail, SR_CANCEL_READ,
|
|
|
|
proc_nr, ref, SFF_READ_FIRST);
|
|
|
|
if (result != EAGAIN)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
result= walk_queue(sr_fd, &sr_fd->srf_write_q,
|
|
|
|
&sr_fd->srf_write_q_tail, SR_CANCEL_WRITE,
|
|
|
|
proc_nr, ref, SFF_WRITE_FIRST);
|
|
|
|
if (result != EAGAIN)
|
|
|
|
return result;
|
|
|
|
|
2005-06-28 17:19:58 +02:00
|
|
|
ip_panic((
|
2006-06-26 13:17:19 +02:00
|
|
|
"request not found: from %d, type %d, MINOR= %d, PROC= %d, REF= %d",
|
2010-01-05 20:39:27 +01:00
|
|
|
m->m_source, m->m_type, m->DEVICE,
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
m->USER_ENDPT, (int) m->IO_GRANT));
|
2010-07-02 14:41:19 +02:00
|
|
|
|
|
|
|
return result;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2005-06-28 17:19:58 +02:00
|
|
|
PRIVATE int sr_select(m)
|
|
|
|
message *m;
|
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
2010-01-14 14:53:12 +01:00
|
|
|
int r;
|
2005-06-28 17:19:58 +02:00
|
|
|
unsigned m_ops, i_ops;
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
sr_fd= sr_getchannel(m->DEVICE);
|
2005-06-28 17:19:58 +02:00
|
|
|
assert (sr_fd);
|
|
|
|
|
|
|
|
sr_fd->srf_select_proc= m->m_source;
|
|
|
|
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
m_ops= m->USER_ENDPT;
|
2005-06-28 17:19:58 +02:00
|
|
|
i_ops= 0;
|
|
|
|
if (m_ops & SEL_RD) i_ops |= SR_SELECT_READ;
|
|
|
|
if (m_ops & SEL_WR) i_ops |= SR_SELECT_WRITE;
|
|
|
|
if (m_ops & SEL_ERR) i_ops |= SR_SELECT_EXCEPTION;
|
|
|
|
if (!(m_ops & SEL_NOTIFY)) i_ops |= SR_SELECT_POLL;
|
|
|
|
|
|
|
|
r= (*sr_fd->srf_select)(sr_fd->srf_fd, i_ops);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
m_ops= 0;
|
|
|
|
if (r & SR_SELECT_READ) m_ops |= SEL_RD;
|
|
|
|
if (r & SR_SELECT_WRITE) m_ops |= SEL_WR;
|
|
|
|
if (r & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR;
|
|
|
|
|
|
|
|
return m_ops;
|
|
|
|
}
|
2005-07-27 18:35:16 +02:00
|
|
|
|
|
|
|
PRIVATE void sr_status(m)
|
|
|
|
message *m;
|
|
|
|
{
|
|
|
|
int fd, result;
|
|
|
|
unsigned m_ops;
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
mq_t *mq;
|
|
|
|
|
|
|
|
mq= repl_queue;
|
|
|
|
if (mq != NULL)
|
|
|
|
{
|
|
|
|
repl_queue= mq->mq_next;
|
|
|
|
|
|
|
|
mq->mq_mess.m_type= DEV_REVIVE;
|
|
|
|
result= send(mq->mq_mess.m_source, &mq->mq_mess);
|
|
|
|
if (result != OK)
|
|
|
|
ip_panic(("unable to send"));
|
|
|
|
mq_free(mq);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (fd=0, sr_fd= sr_fd_table; fd<FD_NR; fd++, sr_fd++)
|
|
|
|
{
|
|
|
|
if ((sr_fd->srf_flags &
|
|
|
|
(SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X)) == 0)
|
|
|
|
{
|
|
|
|
/* Nothing to report */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (sr_fd->srf_select_proc != m->m_source)
|
|
|
|
{
|
|
|
|
/* Wrong process */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ops= 0;
|
|
|
|
if (sr_fd->srf_flags & SFF_SELECT_R) m_ops |= SEL_RD;
|
|
|
|
if (sr_fd->srf_flags & SFF_SELECT_W) m_ops |= SEL_WR;
|
|
|
|
if (sr_fd->srf_flags & SFF_SELECT_X) m_ops |= SEL_ERR;
|
|
|
|
|
|
|
|
sr_fd->srf_flags &= ~(SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X);
|
|
|
|
|
|
|
|
m->m_type= DEV_IO_READY;
|
|
|
|
m->DEV_MINOR= fd;
|
|
|
|
m->DEV_SEL_OPS= m_ops;
|
|
|
|
|
|
|
|
result= send(m->m_source, m);
|
|
|
|
if (result != OK)
|
|
|
|
ip_panic(("unable to send"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m->m_type= DEV_NO_STATUS;
|
|
|
|
result= send(m->m_source, m);
|
|
|
|
if (result != OK)
|
|
|
|
ip_panic(("unable to send"));
|
|
|
|
}
|
2005-06-28 17:19:58 +02:00
|
|
|
|
2005-08-08 17:49:16 +02:00
|
|
|
PRIVATE int walk_queue(sr_fd, q_head_ptr, q_tail_ptr, type, proc_nr, ref,
|
2005-07-27 18:35:16 +02:00
|
|
|
first_flag)
|
2005-04-21 16:53:53 +02:00
|
|
|
sr_fd_t *sr_fd;
|
2005-08-08 17:49:16 +02:00
|
|
|
mq_t **q_head_ptr;
|
|
|
|
mq_t **q_tail_ptr;
|
2005-04-21 16:53:53 +02:00
|
|
|
int type;
|
|
|
|
int proc_nr;
|
|
|
|
int ref;
|
2005-07-27 18:35:16 +02:00
|
|
|
int first_flag;
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
mq_t *q_ptr_prv, *q_ptr;
|
|
|
|
int result;
|
|
|
|
|
2005-08-08 17:49:16 +02:00
|
|
|
for(q_ptr_prv= NULL, q_ptr= *q_head_ptr; q_ptr;
|
2005-04-21 16:53:53 +02:00
|
|
|
q_ptr_prv= q_ptr, q_ptr= q_ptr->mq_next)
|
|
|
|
{
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
if (q_ptr->mq_mess.USER_ENDPT != proc_nr)
|
2005-04-21 16:53:53 +02:00
|
|
|
continue;
|
2006-06-26 13:17:19 +02:00
|
|
|
if ((int)q_ptr->mq_mess.IO_GRANT != ref)
|
|
|
|
continue;
|
2005-04-21 16:53:53 +02:00
|
|
|
if (!q_ptr_prv)
|
|
|
|
{
|
2005-07-27 18:35:16 +02:00
|
|
|
assert(!(sr_fd->srf_flags & first_flag));
|
|
|
|
sr_fd->srf_flags |= first_flag;
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
result= (*sr_fd->srf_cancel)(sr_fd->srf_fd, type);
|
|
|
|
assert(result == OK);
|
2005-07-27 18:35:16 +02:00
|
|
|
|
2005-08-08 17:49:16 +02:00
|
|
|
*q_head_ptr= q_ptr->mq_next;
|
|
|
|
mq_free(q_ptr);
|
|
|
|
|
2005-07-27 18:35:16 +02:00
|
|
|
assert(sr_fd->srf_flags & first_flag);
|
|
|
|
sr_fd->srf_flags &= ~first_flag;
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
q_ptr_prv->mq_next= q_ptr->mq_next;
|
|
|
|
mq_free(q_ptr);
|
|
|
|
if (!q_ptr_prv->mq_next)
|
|
|
|
*q_tail_ptr= q_ptr_prv;
|
|
|
|
return EINTR;
|
|
|
|
}
|
|
|
|
return EAGAIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE sr_fd_t *sr_getchannel(minor)
|
|
|
|
int minor;
|
|
|
|
{
|
|
|
|
sr_fd_t *loc_fd;
|
|
|
|
|
|
|
|
compare(minor, >=, 0);
|
|
|
|
compare(minor, <, FD_NR);
|
|
|
|
|
|
|
|
loc_fd= &sr_fd_table[minor];
|
|
|
|
|
|
|
|
assert (!(loc_fd->srf_flags & SFF_MINOR) &&
|
|
|
|
(loc_fd->srf_flags & SFF_INUSE));
|
|
|
|
|
|
|
|
return loc_fd;
|
|
|
|
}
|
|
|
|
|
2005-07-27 18:35:16 +02:00
|
|
|
PRIVATE void sr_reply_(mq, status, is_revive)
|
2005-04-21 16:53:53 +02:00
|
|
|
mq_t *mq;
|
|
|
|
int status;
|
2005-07-27 18:35:16 +02:00
|
|
|
int is_revive;
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
2010-01-14 14:53:12 +01:00
|
|
|
int result, proc, ref;
|
2005-04-21 16:53:53 +02:00
|
|
|
message reply, *mp;
|
|
|
|
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
proc= mq->mq_mess.USER_ENDPT;
|
2006-06-26 13:17:19 +02:00
|
|
|
ref= (int)mq->mq_mess.IO_GRANT;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2005-07-27 18:35:16 +02:00
|
|
|
if (is_revive)
|
2005-04-21 16:53:53 +02:00
|
|
|
mp= &mq->mq_mess;
|
|
|
|
else
|
|
|
|
mp= &reply;
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
mp->m_type= TASK_REPLY;
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
mp->REP_ENDPT= proc;
|
2005-04-21 16:53:53 +02:00
|
|
|
mp->REP_STATUS= status;
|
2006-06-26 13:17:19 +02:00
|
|
|
mp->REP_IO_GRANT= ref;
|
2005-07-27 18:35:16 +02:00
|
|
|
if (is_revive)
|
|
|
|
{
|
2005-07-29 17:00:49 +02:00
|
|
|
notify(mq->mq_mess.m_source);
|
2005-07-27 18:35:16 +02:00
|
|
|
result= ELOCKED;
|
|
|
|
}
|
|
|
|
else
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2005-07-27 18:35:16 +02:00
|
|
|
result= send(mq->mq_mess.m_source, mp);
|
2006-06-26 13:17:19 +02:00
|
|
|
}
|
2005-07-27 18:35:16 +02:00
|
|
|
|
|
|
|
if (result == ELOCKED && is_revive)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
2005-06-28 17:19:58 +02:00
|
|
|
mq->mq_next= NULL;
|
2005-04-21 16:53:53 +02:00
|
|
|
if (repl_queue)
|
|
|
|
repl_queue_tail->mq_next= mq;
|
|
|
|
else
|
|
|
|
repl_queue= mq;
|
|
|
|
repl_queue_tail= mq;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (result != OK)
|
|
|
|
ip_panic(("unable to send"));
|
2005-07-27 18:35:16 +02:00
|
|
|
if (is_revive)
|
2005-04-21 16:53:53 +02:00
|
|
|
mq_free(mq);
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE acc_t *sr_get_userdata (fd, offset, count, for_ioctl)
|
|
|
|
int fd;
|
2009-11-28 14:28:55 +01:00
|
|
|
size_t offset;
|
|
|
|
size_t count;
|
2005-04-21 16:53:53 +02:00
|
|
|
int for_ioctl;
|
|
|
|
{
|
|
|
|
sr_fd_t *loc_fd;
|
2005-06-28 17:19:58 +02:00
|
|
|
mq_t **head_ptr, *m, *mq;
|
2010-01-05 20:39:27 +01:00
|
|
|
int ip_flag, susp_flag, first_flag;
|
2005-07-27 18:35:16 +02:00
|
|
|
int result, suspended, is_revive;
|
2005-04-21 16:53:53 +02:00
|
|
|
acc_t *acc;
|
2005-06-28 17:19:58 +02:00
|
|
|
event_t *evp;
|
|
|
|
ev_arg_t arg;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
loc_fd= &sr_fd_table[fd];
|
|
|
|
|
|
|
|
if (for_ioctl)
|
|
|
|
{
|
|
|
|
head_ptr= &loc_fd->srf_ioctl_q;
|
2005-06-28 17:19:58 +02:00
|
|
|
evp= &loc_fd->srf_ioctl_ev;
|
2005-04-21 16:53:53 +02:00
|
|
|
ip_flag= SFF_IOCTL_IP;
|
|
|
|
susp_flag= SFF_IOCTL_SUSP;
|
2005-07-27 18:35:16 +02:00
|
|
|
first_flag= SFF_IOCTL_FIRST;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
head_ptr= &loc_fd->srf_write_q;
|
2005-06-28 17:19:58 +02:00
|
|
|
evp= &loc_fd->srf_write_ev;
|
2005-04-21 16:53:53 +02:00
|
|
|
ip_flag= SFF_WRITE_IP;
|
|
|
|
susp_flag= SFF_WRITE_SUSP;
|
2005-07-27 18:35:16 +02:00
|
|
|
first_flag= SFF_WRITE_FIRST;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
assert (loc_fd->srf_flags & ip_flag);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (!count)
|
|
|
|
{
|
|
|
|
m= *head_ptr;
|
|
|
|
mq= m->mq_next;
|
2005-06-28 17:19:58 +02:00
|
|
|
*head_ptr= mq;
|
2005-04-21 16:53:53 +02:00
|
|
|
result= (int)offset;
|
2005-07-27 18:35:16 +02:00
|
|
|
is_revive= !(loc_fd->srf_flags & first_flag);
|
|
|
|
sr_reply_(m, result, is_revive);
|
2005-04-21 16:53:53 +02:00
|
|
|
suspended= (loc_fd->srf_flags & susp_flag);
|
|
|
|
loc_fd->srf_flags &= ~(ip_flag|susp_flag);
|
|
|
|
if (suspended)
|
|
|
|
{
|
2005-06-28 17:19:58 +02:00
|
|
|
if (mq)
|
|
|
|
{
|
|
|
|
arg.ev_ptr= loc_fd;
|
|
|
|
ev_enqueue(evp, sr_event, arg);
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
result= cp_u2b ((*head_ptr)->mq_mess.m_source,
|
2010-01-05 20:39:27 +01:00
|
|
|
(int)(*head_ptr)->mq_mess.IO_GRANT, offset, &acc, count);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
return result<0 ? NULL : acc;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE int sr_put_userdata (fd, offset, data, for_ioctl)
|
|
|
|
int fd;
|
2009-11-28 14:28:55 +01:00
|
|
|
size_t offset;
|
2005-04-21 16:53:53 +02:00
|
|
|
acc_t *data;
|
|
|
|
int for_ioctl;
|
|
|
|
{
|
|
|
|
sr_fd_t *loc_fd;
|
2005-06-28 17:19:58 +02:00
|
|
|
mq_t **head_ptr, *m, *mq;
|
2010-01-05 20:39:27 +01:00
|
|
|
int ip_flag, susp_flag, first_flag;
|
2005-07-27 18:35:16 +02:00
|
|
|
int result, suspended, is_revive;
|
2005-06-28 17:19:58 +02:00
|
|
|
event_t *evp;
|
|
|
|
ev_arg_t arg;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
loc_fd= &sr_fd_table[fd];
|
|
|
|
|
|
|
|
if (for_ioctl)
|
|
|
|
{
|
|
|
|
head_ptr= &loc_fd->srf_ioctl_q;
|
2005-06-28 17:19:58 +02:00
|
|
|
evp= &loc_fd->srf_ioctl_ev;
|
2005-04-21 16:53:53 +02:00
|
|
|
ip_flag= SFF_IOCTL_IP;
|
|
|
|
susp_flag= SFF_IOCTL_SUSP;
|
2005-07-27 18:35:16 +02:00
|
|
|
first_flag= SFF_IOCTL_FIRST;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
head_ptr= &loc_fd->srf_read_q;
|
2005-06-28 17:19:58 +02:00
|
|
|
evp= &loc_fd->srf_read_ev;
|
2005-04-21 16:53:53 +02:00
|
|
|
ip_flag= SFF_READ_IP;
|
|
|
|
susp_flag= SFF_READ_SUSP;
|
2005-07-27 18:35:16 +02:00
|
|
|
first_flag= SFF_READ_FIRST;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
assert (loc_fd->srf_flags & ip_flag);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
m= *head_ptr;
|
|
|
|
mq= m->mq_next;
|
2005-06-28 17:19:58 +02:00
|
|
|
*head_ptr= mq;
|
2005-04-21 16:53:53 +02:00
|
|
|
result= (int)offset;
|
2005-07-27 18:35:16 +02:00
|
|
|
is_revive= !(loc_fd->srf_flags & first_flag);
|
|
|
|
sr_reply_(m, result, is_revive);
|
2005-04-21 16:53:53 +02:00
|
|
|
suspended= (loc_fd->srf_flags & susp_flag);
|
|
|
|
loc_fd->srf_flags &= ~(ip_flag|susp_flag);
|
|
|
|
if (suspended)
|
|
|
|
{
|
2005-06-28 17:19:58 +02:00
|
|
|
if (mq)
|
|
|
|
{
|
|
|
|
arg.ev_ptr= loc_fd;
|
|
|
|
ev_enqueue(evp, sr_event, arg);
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
return cp_b2u (data, (*head_ptr)->mq_mess.m_source,
|
2010-01-05 20:39:27 +01:00
|
|
|
(int)(*head_ptr)->mq_mess.IO_GRANT, offset);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2010-03-30 16:07:15 +02:00
|
|
|
PRIVATE void sr_select_res(int fd, unsigned ops)
|
2005-06-28 17:19:58 +02:00
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
|
|
|
|
sr_fd= &sr_fd_table[fd];
|
|
|
|
|
2005-07-27 18:35:16 +02:00
|
|
|
if (ops & SR_SELECT_READ) sr_fd->srf_flags |= SFF_SELECT_R;
|
|
|
|
if (ops & SR_SELECT_WRITE) sr_fd->srf_flags |= SFF_SELECT_W;
|
|
|
|
if (ops & SR_SELECT_EXCEPTION) sr_fd->srf_flags |= SFF_SELECT_X;
|
2005-06-28 17:19:58 +02:00
|
|
|
|
2005-07-29 17:00:49 +02:00
|
|
|
notify(sr_fd->srf_select_proc);
|
2005-06-28 17:19:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE void sr_event(evp, arg)
|
|
|
|
event_t *evp;
|
|
|
|
ev_arg_t arg;
|
|
|
|
{
|
|
|
|
sr_fd_t *sr_fd;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
sr_fd= arg.ev_ptr;
|
|
|
|
if (evp == &sr_fd->srf_write_ev)
|
|
|
|
{
|
|
|
|
while(sr_fd->srf_write_q)
|
|
|
|
{
|
|
|
|
r= sr_restart_write(sr_fd);
|
|
|
|
if (r == SUSPEND)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (evp == &sr_fd->srf_read_ev)
|
|
|
|
{
|
|
|
|
while(sr_fd->srf_read_q)
|
|
|
|
{
|
|
|
|
r= sr_restart_read(sr_fd);
|
|
|
|
if (r == SUSPEND)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (evp == &sr_fd->srf_ioctl_ev)
|
|
|
|
{
|
|
|
|
while(sr_fd->srf_ioctl_q)
|
|
|
|
{
|
|
|
|
r= sr_restart_ioctl(sr_fd);
|
|
|
|
if (r == SUSPEND)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2010-01-05 20:39:27 +01:00
|
|
|
ip_panic(("sr_event: unknown event\n"));
|
2005-06-28 17:19:58 +02:00
|
|
|
}
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
PRIVATE int cp_u2b(proc, gid, offset, var_acc_ptr, size)
|
2010-03-30 16:07:15 +02:00
|
|
|
endpoint_t proc;
|
|
|
|
cp_grant_id_t gid;
|
2006-06-26 16:20:11 +02:00
|
|
|
vir_bytes offset;
|
2006-06-26 13:17:19 +02:00
|
|
|
acc_t **var_acc_ptr;
|
|
|
|
int size;
|
|
|
|
{
|
|
|
|
acc_t *acc;
|
2006-06-26 16:20:11 +02:00
|
|
|
int i, r;
|
2006-06-26 13:17:19 +02:00
|
|
|
|
|
|
|
acc= bf_memreq(size);
|
|
|
|
|
|
|
|
*var_acc_ptr= acc;
|
|
|
|
i=0;
|
|
|
|
|
|
|
|
while (acc)
|
|
|
|
{
|
|
|
|
size= (vir_bytes)acc->acc_length;
|
|
|
|
|
2006-06-26 16:20:11 +02:00
|
|
|
s_cp_req[i].v_from= proc;
|
|
|
|
s_cp_req[i].v_to= SELF;
|
|
|
|
s_cp_req[i].v_gid= gid;
|
|
|
|
s_cp_req[i].v_offset= offset;
|
|
|
|
s_cp_req[i].v_addr= (vir_bytes) ptr2acc_data(acc);
|
|
|
|
s_cp_req[i].v_bytes= size;
|
2006-06-26 13:17:19 +02:00
|
|
|
|
2006-06-26 16:20:11 +02:00
|
|
|
offset += size;
|
2006-06-26 13:17:19 +02:00
|
|
|
acc= acc->acc_next;
|
|
|
|
i++;
|
|
|
|
|
2006-06-26 16:20:11 +02:00
|
|
|
if (acc == NULL && i == 1)
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2006-06-26 16:20:11 +02:00
|
|
|
r= sys_safecopyfrom(s_cp_req[0].v_from,
|
|
|
|
s_cp_req[0].v_gid, s_cp_req[0].v_offset,
|
|
|
|
s_cp_req[0].v_addr, s_cp_req[0].v_bytes, D);
|
|
|
|
if (r <0)
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2006-06-26 16:20:11 +02:00
|
|
|
printf("sys_safecopyfrom failed: %d\n", r);
|
2006-06-26 13:17:19 +02:00
|
|
|
bf_afree(*var_acc_ptr);
|
|
|
|
*var_acc_ptr= 0;
|
2006-06-26 16:20:11 +02:00
|
|
|
return r;
|
2006-06-26 13:17:19 +02:00
|
|
|
}
|
|
|
|
i= 0;
|
2006-06-26 16:20:11 +02:00
|
|
|
continue;
|
2006-06-26 13:17:19 +02:00
|
|
|
}
|
2010-01-05 20:39:27 +01:00
|
|
|
if (i == SCPVEC_NR || acc == NULL)
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2006-06-26 16:20:11 +02:00
|
|
|
r= sys_vsafecopy(s_cp_req, i);
|
2006-06-26 13:17:19 +02:00
|
|
|
|
2006-06-26 16:20:11 +02:00
|
|
|
if (r <0)
|
|
|
|
{
|
2010-01-05 20:39:27 +01:00
|
|
|
printf("cp_u2b: sys_vsafecopy failed: %d\n",
|
2006-06-26 16:20:11 +02:00
|
|
|
r);
|
|
|
|
bf_afree(*var_acc_ptr);
|
|
|
|
*var_acc_ptr= 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
i= 0;
|
|
|
|
}
|
2006-06-26 13:17:19 +02:00
|
|
|
}
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
2010-01-05 20:39:27 +01:00
|
|
|
PRIVATE int cp_b2u(acc_ptr, proc, gid, offset)
|
2006-06-26 13:17:19 +02:00
|
|
|
acc_t *acc_ptr;
|
2010-03-30 16:07:15 +02:00
|
|
|
endpoint_t proc;
|
|
|
|
cp_grant_id_t gid;
|
2006-06-26 13:17:19 +02:00
|
|
|
vir_bytes offset;
|
|
|
|
{
|
|
|
|
acc_t *acc;
|
2006-06-26 16:20:11 +02:00
|
|
|
int i, r, size;
|
2006-06-26 13:17:19 +02:00
|
|
|
|
|
|
|
acc= acc_ptr;
|
|
|
|
i=0;
|
|
|
|
|
|
|
|
while (acc)
|
|
|
|
{
|
|
|
|
size= (vir_bytes)acc->acc_length;
|
|
|
|
|
|
|
|
if (size)
|
|
|
|
{
|
2006-06-26 16:20:11 +02:00
|
|
|
s_cp_req[i].v_from= SELF;
|
|
|
|
s_cp_req[i].v_to= proc;
|
|
|
|
s_cp_req[i].v_gid= gid;
|
|
|
|
s_cp_req[i].v_offset= offset;
|
|
|
|
s_cp_req[i].v_addr= (vir_bytes) ptr2acc_data(acc);
|
|
|
|
s_cp_req[i].v_bytes= size;
|
|
|
|
|
2006-06-26 13:17:19 +02:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2006-06-26 16:20:11 +02:00
|
|
|
offset += size;
|
2006-06-26 13:17:19 +02:00
|
|
|
acc= acc->acc_next;
|
|
|
|
|
2006-06-26 16:20:11 +02:00
|
|
|
if (acc == NULL && i == 1)
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2006-06-26 16:20:11 +02:00
|
|
|
r= sys_safecopyto(s_cp_req[0].v_to,
|
|
|
|
s_cp_req[0].v_gid, s_cp_req[0].v_offset,
|
|
|
|
s_cp_req[0].v_addr, s_cp_req[0].v_bytes, D);
|
|
|
|
if (r <0)
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2006-06-26 16:20:11 +02:00
|
|
|
printf("sys_safecopyto failed: %d\n", r);
|
2006-06-26 13:17:19 +02:00
|
|
|
bf_afree(acc_ptr);
|
2006-06-26 16:20:11 +02:00
|
|
|
return r;
|
2006-06-26 13:17:19 +02:00
|
|
|
}
|
|
|
|
i= 0;
|
2006-06-26 16:20:11 +02:00
|
|
|
continue;
|
2006-06-26 13:17:19 +02:00
|
|
|
}
|
2010-01-05 20:39:27 +01:00
|
|
|
if (i == SCPVEC_NR || acc == NULL)
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2006-06-26 16:20:11 +02:00
|
|
|
r= sys_vsafecopy(s_cp_req, i);
|
|
|
|
|
|
|
|
if (r <0)
|
2006-06-26 13:17:19 +02:00
|
|
|
{
|
2010-01-05 20:39:27 +01:00
|
|
|
printf("cp_b2u: sys_vsafecopy failed: %d\n",
|
2006-06-26 13:17:19 +02:00
|
|
|
r);
|
|
|
|
bf_afree(acc_ptr);
|
|
|
|
return r;
|
|
|
|
}
|
2006-06-26 16:20:11 +02:00
|
|
|
i= 0;
|
2006-06-26 13:17:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
bf_afree(acc_ptr);
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
PRIVATE int sr_repl_queue(proc, ref, operation)
|
|
|
|
int proc;
|
|
|
|
int ref;
|
|
|
|
int operation;
|
|
|
|
{
|
|
|
|
mq_t *m, *m_cancel, *m_tmp;
|
2006-06-26 13:17:19 +02:00
|
|
|
mq_t *new_queue;
|
2005-04-21 16:53:53 +02:00
|
|
|
int result;
|
|
|
|
|
|
|
|
m_cancel= NULL;
|
2006-06-26 13:17:19 +02:00
|
|
|
new_queue= NULL;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
for (m= repl_queue; m;)
|
|
|
|
{
|
2006-06-26 13:17:19 +02:00
|
|
|
if (m->mq_mess.REP_ENDPT == proc &&
|
|
|
|
m->mq_mess.REP_IO_GRANT == ref)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
2010-01-05 20:39:27 +01:00
|
|
|
assert(!m_cancel);
|
2005-04-21 16:53:53 +02:00
|
|
|
m_cancel= m;
|
|
|
|
m= m->mq_next;
|
|
|
|
continue;
|
|
|
|
}
|
2006-06-26 13:17:19 +02:00
|
|
|
m_tmp= m;
|
|
|
|
m= m->mq_next;
|
|
|
|
m_tmp->mq_next= new_queue;
|
|
|
|
new_queue= m_tmp;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
2006-06-26 13:17:19 +02:00
|
|
|
repl_queue= new_queue;
|
2005-04-21 16:53:53 +02:00
|
|
|
if (m_cancel)
|
|
|
|
{
|
|
|
|
result= send(m_cancel->mq_mess.m_source, &m_cancel->mq_mess);
|
|
|
|
if (result != OK)
|
|
|
|
ip_panic(("unable to send: %d", result));
|
|
|
|
mq_free(m_cancel);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-06-28 17:19:58 +02:00
|
|
|
* $PchId: sr.c,v 1.17 2005/06/28 14:26:16 philip Exp $
|
2005-04-21 16:53:53 +02:00
|
|
|
*/
|