]> Zhao Yanbai Git Server - minix.git/commitdiff
Understand *_S variants: DIAGNOSTICS_S, DEV_{READ,WRITE,IOCTL}_S,
authorBen Gras <ben@minix3.org>
Tue, 20 Jun 2006 08:55:35 +0000 (08:55 +0000)
committerBen Gras <ben@minix3.org>
Tue, 20 Jun 2006 08:55:35 +0000 (08:55 +0000)
include grant id in DEV_REVIVE messages

drivers/log/diag.c
drivers/log/kputc.c
drivers/log/log.c
drivers/log/log.h

index b829d10e51c509cda469df059b2d798cd9498856..7a1cce9142a5d80d9fe4f3a927b0b88bac7033e2 100644 (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;
   }
index 8714f8272a2160e7b08da02a7e3650330d01541a..f6e76655755e04dc1ab933b03bf5b120abc86659 100644 (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 */
index 0424f50749d86edb15366fac14ebf6c69a0cc7a4..09e665d525d83d07656c0a80199a6c6de4ba3b0a 100644 (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: {
index 48060bf52f79ea85381b1c2bda97fc87380a9723..8928b525f5374f40c3a928325eb152119f57b396 100644 (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)                              );