Understand *_S variants: DIAGNOSTICS_S, DEV_{READ,WRITE,IOCTL}_S,

include grant id in DEV_REVIVE messages
This commit is contained in:
Ben Gras 2006-06-20 08:55:35 +00:00
parent 3ca26c812d
commit 60bbcab13f
4 changed files with 63 additions and 35 deletions

View File

@ -9,6 +9,8 @@
#include <stdio.h>
#include <fcntl.h>
#include <minix/type.h>
#include <minix/safecopies.h>
#include "log.h"
#include "../../kernel/const.h"
@ -83,33 +85,33 @@ message *m; /* notification message */
/*===========================================================================*
* do_diagnostics *
*===========================================================================*/
PUBLIC int do_diagnostics(message *m)
PUBLIC int do_diagnostics(message *m, int safe)
{
/* The LOG server handles all diagnostic messages from servers and device
* drivers. It forwards the message to the TTY driver to display it to the
* user. It also saves a copy in a local buffer so that messages can be
* reviewed at a later time.
*/
int proc_nr_e;
vir_bytes src;
int count;
char c;
int i = 0;
int i = 0, offset = 0;
static char diagbuf[10240];
/* Change SELF to actual process number. */
if ((proc_nr_e = m->DIAG_ENDPT) == SELF)
m->DIAG_ENDPT = proc_nr_e = m->m_source;
/* Now also make a copy for the private buffer at the LOG server, so
/* Also make a copy for the private buffer at the LOG server, so
* that the messages can be reviewed at a later time.
*/
src = (vir_bytes) m->DIAG_PRINT_BUF;
src = (vir_bytes) m->DIAG_PRINT_BUF_G;
count = m->DIAG_BUF_COUNT;
while (count > 0 && i < sizeof(diagbuf)-1) {
if (sys_datacopy(proc_nr_e, src, SELF, (vir_bytes) &c, 1) != OK)
break; /* stop copying on error */
src ++;
int r;
if(safe) {
r = sys_safecopyfrom(m->m_source, src, offset, (vir_bytes) &c, 1, D);
} else {
r = sys_datacopy(m->m_source, src+offset, SELF, (vir_bytes) &c, 1);
}
if(r != OK) break;
offset ++;
count --;
diagbuf[i++] = c;
}

View File

@ -22,8 +22,7 @@ int c;
if ((c == 0 && buf_count > 0) || buf_count == sizeof(print_buf)) {
m.DIAG_BUF_COUNT = buf_count;
m.DIAG_PRINT_BUF = print_buf;
m.DIAG_ENDPT = SELF;
m.DIAG_PRINT_BUF_G = print_buf;
m.m_type = DIAGNOSTICS; /* request TTY to output this buffer */
_sendrec(TTY_PROC_NR, &m); /* if it fails, we give up */
buf_count = 0; /* clear buffer for next batch */

View File

@ -26,21 +26,21 @@ PRIVATE int log_device = -1; /* current device */
FORWARD _PROTOTYPE( char *log_name, (void) );
FORWARD _PROTOTYPE( struct device *log_prepare, (int device) );
FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, off_t position,
iovec_t *iov, unsigned nr_req) );
iovec_t *iov, unsigned nr_req, int safe) );
FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_select, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void log_signal, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr, int) );
FORWARD _PROTOTYPE( void log_geometry, (struct partition *entry) );
FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) );
FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir, size_t, int safe) );
/* Entry points to this driver. */
PRIVATE struct driver log_dtab = {
log_name, /* current device's name */
log_do_open, /* open or mount */
do_nop, /* nothing on a close */
do_nop, /* ioctl nop */
nop_ioctl, /* ioctl nop */
log_prepare, /* prepare for I/O on a given minor device */
log_transfer, /* do the I/O */
nop_cleanup, /* no need to clean up */
@ -104,7 +104,8 @@ int device;
* subwrite *
*===========================================================================*/
PRIVATE int
subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
subwrite(struct logdevice *log, int count, int proc_nr,
vir_bytes user_vir, size_t offset, int safe)
{
char *buf;
int r;
@ -116,8 +117,15 @@ subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
memcpy(buf, (char *) user_vir, count);
}
else {
if((r=sys_vircopy(proc_nr,D,user_vir, SELF,D,(int)buf, count)) != OK)
if(safe) {
if((r=sys_safecopyfrom(proc_nr, user_vir, offset,
(vir_bytes)buf, count, D)) != OK)
return r;
} else {
if((r=sys_vircopy(proc_nr, D,
user_vir + offset, SELF,D,(int)buf, count)) != OK)
return r;
}
}
LOGINC(log->log_write, count);
@ -135,7 +143,8 @@ subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
* be revived.
*/
log->log_status = subread(log, log->log_iosize,
log->log_proc_nr, log->log_user_vir);
log->log_proc_nr, log->log_user_vir_g,
log->log_user_vir_offset, log->log_safe);
notify(log->log_source);
log->log_revive_alerted = 1;
}
@ -174,10 +183,10 @@ log_append(char *buf, int count)
if(count > LOG_SIZE) skip = count - LOG_SIZE;
count -= skip;
buf += skip;
w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf);
w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf,0,0);
if(w > 0 && w < count)
subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w);
subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w,0,0);
return;
}
@ -185,7 +194,8 @@ log_append(char *buf, int count)
* subread *
*===========================================================================*/
PRIVATE int
subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
subread(struct logdevice *log, int count, int proc_nr,
vir_bytes user_vir, size_t offset, int safe)
{
char *buf;
int r;
@ -195,8 +205,15 @@ subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
count = LOG_SIZE - log->log_read;
buf = log->log_buffer + log->log_read;
if((r=sys_vircopy(SELF,D,(int)buf,proc_nr,D,user_vir, count)) != OK)
if(safe) {
if((r=sys_safecopyto(proc_nr, user_vir, offset,
(vir_bytes)buf, count, D)) != OK)
return r;
} else {
if((r=sys_vircopy(SELF,D,(int)buf,
proc_nr, safe ? GRANT_SEG : D, user_vir + offset, count)) != OK)
return r;
}
LOGINC(log->log_read, count);
log->log_size -= count;
@ -207,12 +224,13 @@ subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
/*===========================================================================*
* log_transfer *
*===========================================================================*/
PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req)
PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req, safe)
int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */
off_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
int safe; /* safe copies? */
{
/* Read or write one the driver's minor devices. */
unsigned count;
@ -222,6 +240,7 @@ unsigned nr_req; /* length of request vector */
int accumulated_read = 0;
struct logdevice *log;
static int f;
size_t vir_offset = 0;
if(log_device < 0 || log_device >= NR_DEVS)
return EIO;
@ -253,8 +272,10 @@ unsigned nr_req; /* length of request vector */
/* No data available; let caller block. */
log->log_proc_nr = proc_nr;
log->log_iosize = count;
log->log_user_vir = user_vir;
log->log_user_vir_g = user_vir;
log->log_user_vir_offset = 0;
log->log_revive_alerted = 0;
log->log_safe = safe;
/* Device_caller is a global in drivers library. */
log->log_source = device_caller;
@ -264,13 +285,13 @@ unsigned nr_req; /* length of request vector */
#endif
return(SUSPEND);
}
count = subread(log, count, proc_nr, user_vir);
count = subread(log, count, proc_nr, user_vir, vir_offset, safe);
if(count < 0) {
return count;
}
accumulated_read += count;
} else {
count = subwrite(log, count, proc_nr, user_vir);
count = subwrite(log, count, proc_nr, user_vir, vir_offset, safe);
if(count < 0)
return count;
}
@ -281,8 +302,8 @@ unsigned nr_req; /* length of request vector */
}
/* Book the number of bytes transferred. */
iov->iov_addr += count;
if ((iov->iov_size -= count) == 0) { iov++; nr_req--; }
vir_offset += count;
if ((iov->iov_size -= count) == 0) { iov++; nr_req--; vir_offset = 0; }
}
return(OK);
}
@ -401,9 +422,10 @@ message *m_ptr;
/*============================================================================*
* log_other *
*============================================================================*/
PRIVATE int log_other(dp, m_ptr)
PRIVATE int log_other(dp, m_ptr, safe)
struct driver *dp;
message *m_ptr;
int safe;
{
int r;
@ -412,7 +434,11 @@ message *m_ptr;
*/
switch(m_ptr->m_type) {
case DIAGNOSTICS: {
r = do_diagnostics(m_ptr);
r = do_diagnostics(m_ptr, 0);
break;
}
case DIAGNOSTICS_S: {
r = do_diagnostics(m_ptr, 1);
break;
}
case DEV_STATUS: {

View File

@ -23,7 +23,8 @@ struct logdevice {
log_iosize,
log_revive_alerted,
log_status; /* proc that is blocking on read */
vir_bytes log_user_vir;
vir_bytes log_user_vir_g, log_user_vir_offset;
int log_safe;
#endif
int log_selected, log_select_proc,
log_select_alerted, log_select_ready_ops;
@ -32,6 +33,6 @@ struct logdevice {
/* Function prototypes. */
_PROTOTYPE( void kputc, (int c) );
_PROTOTYPE( int do_new_kmess, (message *m) );
_PROTOTYPE( int do_diagnostics, (message *m) );
_PROTOTYPE( int do_diagnostics, (message *m, int safe) );
_PROTOTYPE( void log_append, (char *buf, int len) );