#define ELEMENTS(a) (sizeof(a)/sizeof((a)[0]))
-FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t, int,
+FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t,
cp_grant_id_t *, int *, cp_grant_id_t *, int, endpoint_t *,
- void *, int *, vir_bytes, off_t *));
-FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *, int));
+ void **, int *, vir_bytes, off_t *));
+FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *,
+ int));
extern int dmap_size;
PRIVATE int dummyproc;
revive(endpt, st.REP_STATUS);
break;
case DEV_IO_READY:
- select_notified(d, st.DEV_MINOR, st.DEV_SEL_OPS);
+ select_notified(d, st.DEV_MINOR,
+ st.DEV_SEL_OPS);
break;
default:
- printf("FS: unrecognized reply %d to DEV_STATUS\n", st.m_type);
+ printf("FS: unrecognized reply %d to "
+ "DEV_STATUS\n", st.m_type);
/* Fall through. */
case DEV_NO_STATUS:
get_more = 0;
/*===========================================================================*
* safe_io_conversion *
*===========================================================================*/
-PRIVATE int safe_io_conversion(driver, dev, gid, op, gids, gids_size,
+PRIVATE int safe_io_conversion(driver, gid, op, gids, gids_size,
io_ept, buf, vec_grants, bytes, pos)
endpoint_t driver;
-int dev;
cp_grant_id_t *gid;
int *op;
cp_grant_id_t *gids;
int gids_size;
endpoint_t *io_ept;
-void *buf;
+void **buf;
int *vec_grants;
vir_bytes bytes;
off_t *pos;
int access = 0, size;
int j;
iovec_t *v;
- static iovec_t new_iovec[NR_IOREQS];
+ static iovec_t new_iovec[NR_IOREQS];
/* Number of grants allocated in vector I/O. */
*vec_grants = 0;
*op = *op == DEV_READ ? DEV_READ_S : DEV_WRITE_S;
if((*gid=cpf_grant_magic(driver, *io_ept,
- (vir_bytes) buf, bytes,
+ (vir_bytes) *buf, bytes,
*op == DEV_READ_S ? CPF_WRITE : CPF_READ)) < 0) {
panic(__FILE__,
"cpf_grant_magic of buffer failed\n", NO_NUM);
*op = *op == DEV_GATHER ? DEV_GATHER_S : DEV_SCATTER_S;
/* Grant access to my new i/o vector. */
- if((*gid = cpf_grant_direct(driver, (vir_bytes)
- new_iovec, bytes * sizeof(iovec_t),
+ if((*gid = cpf_grant_direct(driver,
+ (vir_bytes) new_iovec, bytes * sizeof(iovec_t),
CPF_READ | CPF_WRITE)) < 0) {
panic(__FILE__,
"cpf_grant_direct of vector failed", NO_NUM);
}
- v = (iovec_t *) buf;
+ v = (iovec_t *) *buf;
/* Grant access to i/o buffers. */
for(j = 0; j < bytes; j++) {
+ if(j >= NR_IOREQS)
+ panic(__FILE__, "vec too big", bytes);
new_iovec[j].iov_addr = gids[j] =
cpf_grant_direct(driver, (vir_bytes)
v[j].iov_addr, v[j].iov_size,
new_iovec[j].iov_size = v[j].iov_size;
(*vec_grants)++;
}
+
+ /* Set user's vector to the new one. */
+ *buf = new_iovec;
break;
case DEV_IOCTL:
*pos = *io_ept; /* Old endpoint in POSITION field. */
* order to disambiguate requests with DEV_IOCTL_S.
*/
if((*gid=cpf_grant_magic(driver, *io_ept,
- (vir_bytes) buf, size, access)) < 0) {
+ (vir_bytes) *buf, size, access)) < 0) {
panic(__FILE__,
"cpf_grant_magic failed (ioctl)\n",
NO_NUM);
struct dmap *dp;
int r, safe;
message m;
+ iovec_t *v;
+ cp_grant_id_t gid = GRANT_INVALID;
+ int vec_grants;
/* Determine task dmap. */
dp = &dmap[(dev >> MAJOR) & BYTE];
+ /* The io vector copying relies on this I/O being for FS itself. */
+ if(proc_e != FS_PROC_NR)
+ panic(__FILE__, "doing dev_bio for non-self", proc_e);
+
for (;;)
{
int op_used;
+ void *buf_used;
static cp_grant_id_t gids[NR_IOREQS];
cp_grant_id_t gid = GRANT_INVALID;
int vec_grants;
}
/* By default, these are right. */
- m.IO_ENDPT = proc_e;
- m.ADDRESS = buf;
+ m.IO_ENDPT = proc_e;
+ m.ADDRESS = buf;
+ buf_used = buf;
/* Convert parameters to 'safe mode'. */
op_used = op;
- safe = safe_io_conversion(dp->dmap_driver, dev, &gid,
- &op_used, gids, NR_IOREQS, &m.IO_ENDPT, buf,
+ safe = safe_io_conversion(dp->dmap_driver, &gid,
+ &op_used, gids, NR_IOREQS, &m.IO_ENDPT, &buf_used,
&vec_grants, bytes, &pos);
/* Set up rest of the message. */
if(safe) m.IO_GRANT = (char *) gid;
+
m.m_type = op_used;
m.DEVICE = (dev >> MINOR) & BYTE;
m.POSITION = pos;
if (m.REP_STATUS == SUSPEND) {
panic(__FILE__, "dev_bio: driver returned SUSPEND", NO_NUM);
}
+
+ if(buf != buf_used) {
+ memcpy(buf, buf_used, bytes * sizeof(iovec_t));
+ }
+
return(m.REP_STATUS);
}
}
cp_grant_id_t gid = GRANT_INVALID;
static cp_grant_id_t gids[NR_IOREQS];
int vec_grants = 0, orig_op, safe;
+ void *buf_used;
/* Determine task dmap. */
dp = &dmap[(dev >> MAJOR) & BYTE];
dev_mess.ADDRESS = buf;
/* Convert DEV_* to DEV_*_S variants. */
- safe = safe_io_conversion(dp->dmap_driver, dev, &gid,
- &op, gids, NR_IOREQS, &dev_mess.IO_ENDPT, buf, &vec_grants, bytes, &pos);
+ buf_used = buf;
+ safe = safe_io_conversion(dp->dmap_driver, &gid,
+ &op, gids, NR_IOREQS, &dev_mess.IO_ENDPT, &buf_used,
+ &vec_grants, bytes, &pos);
+
+ if(buf != buf_used)
+ panic(__FILE__,"dev_io: safe_io_conversion changed buffer", NO_NUM);
/* If the safe conversion was done, set the ADDRESS to
* the grant id.