/*===========================================================================*
 *				subread					     *
 *===========================================================================*/
static int
subread(struct logdevice *log, size_t size, endpoint_t endpt,
	cp_grant_id_t grant)
{
  size_t offset, count;
  char *buf;
  int r;

  for (offset = 0; log->log_size > 0 && offset < size; offset += count) {
	count = size - offset;

    	if (count > log->log_size)
    		count = log->log_size;
        if (log->log_read + count > LOG_SIZE)
        	count = LOG_SIZE - log->log_read;

    	buf = log->log_buffer + log->log_read;
	if((r=sys_safecopyto(endpt, grant, offset, (vir_bytes)buf,
		count)) != OK)
		return r;

  	LOGINC(log->log_read, count);
        log->log_size -= count;
  }

  return offset;
}
Esempio n. 2
0
/*===========================================================================*
 *				subread					     *
 *===========================================================================*/
PRIVATE int
subread(struct logdevice *log, int count, endpoint_t endpt,
	cp_grant_id_t grant, size_t offset)
{
	char *buf;
	int r;
    	if (count > log->log_size)
    		count = log->log_size;
        if (log->log_read + count > LOG_SIZE)
        	count = LOG_SIZE - log->log_read;

    	buf = log->log_buffer + log->log_read;
	if((r=sys_safecopyto(endpt, grant, offset,
		(vir_bytes)buf, count, D)) != OK)
		return r;

  	LOGINC(log->log_read, count);
        log->log_size -= count;

        return count;
}
Esempio n. 3
0
/*===========================================================================*
 *				subwrite				     *
 *===========================================================================*/
PRIVATE int
subwrite(struct logdevice *log, int count, endpoint_t endpt,
	cp_grant_id_t grant, size_t offset, char *localbuf)
{
	int d, r;
	char *buf;
	message m;

	if (log->log_write + count > LOG_SIZE)
		count = LOG_SIZE - log->log_write;
	buf = log->log_buffer + log->log_write;

	if(localbuf != NULL) {
		memcpy(buf, localbuf, count);
	}
	else {
		if((r=sys_safecopyfrom(endpt, grant, offset,
			(vir_bytes)buf, count, D)) != OK)
			return r;
	}

	LOGINC(log->log_write, count);
	log->log_size += count;

        if(log->log_size > LOG_SIZE) {
        	int overflow;
        	overflow = log->log_size - LOG_SIZE;
        	log->log_size -= overflow;
        	LOGINC(log->log_read, overflow);
        }

        if(log->log_size > 0 && log->log_source != NONE &&
			!log->log_revive_alerted) {
        	/* Someone who was suspended on read can now
        	 * be revived.
        	 */
    		log->log_status = subread(log, log->log_iosize,
    			log->log_source, log->log_user_grant,
			log->log_user_offset);

		m.m_type = DEV_REVIVE;
		m.REP_ENDPT = log->log_proc_nr;
		m.REP_STATUS  = log->log_status;
		m.REP_IO_GRANT  = log->log_user_grant;
  		r= send(log->log_source, &m);
		if (r != OK)
		{
			printf("log`subwrite: send to %d failed: %d\n",
				log->log_source, r);
		}
		log->log_source = NONE;
 	} 

	if(log->log_size > 0)
		log->log_select_ready_ops |= SEL_RD;

	if(log->log_size > 0 && log->log_selected &&
	  !(log->log_select_alerted)) {
  		/* Someone(s) who was/were select()ing can now
  		 * be awoken. If there was a blocking read (above),
  		 * this can only happen if the blocking read didn't
  		 * swallow all the data (log_size > 0).
  		 */
  		if(log->log_selected & SEL_RD) {
			d= log-logdevices;
			m.m_type = DEV_SEL_REPL2;
			m.DEV_SEL_OPS = log->log_select_ready_ops;
			m.DEV_MINOR   = d;
#if LOG_DEBUG
			printf("select sending DEV_SEL_REPL2\n");
#endif
  			r= send(log->log_select_proc, &m);
			if (r != OK)
			{
				printf(	
				"log`subwrite: send to %d failed: %d\n",
					log->log_select_proc, r);
			}
			log->log_selected &= ~log->log_select_ready_ops;
  		}
  	}

        return count;
}
/*===========================================================================*
 *				subwrite				     *
 *===========================================================================*/
static int
subwrite(struct logdevice *log, size_t size, endpoint_t endpt,
	cp_grant_id_t grant, char *localbuf)
{
  size_t count, offset;
  int overflow, r, result;
  devminor_t minor;
  char *buf;
  message m;

  /* With a sufficiently large input size, we might wrap around the ring buffer
   * multiple times.
   */
  result = 0;
  for (offset = 0; offset < size; offset += count) {
	count = size - offset;

	if (log->log_write + count > LOG_SIZE)
		count = LOG_SIZE - log->log_write;
	buf = log->log_buffer + log->log_write;

	if(localbuf != NULL) {
		memcpy(buf, localbuf, count);
		localbuf += count;
	}
	else {
		if((r=sys_safecopyfrom(endpt, grant, offset,
			(vir_bytes)buf, count)) != OK) {
			/* return any partial success upon error */
			result = (offset > 0) ? (int)offset : r;
			break;
		}
	}

	LOGINC(log->log_write, count);
	log->log_size += count;

        if(log->log_size > LOG_SIZE) {
        	overflow = log->log_size - LOG_SIZE;
        	log->log_size -= overflow;
        	LOGINC(log->log_read, overflow);
        }

	result += (int)count;
  }

  if (log->log_size > 0 && log->log_source != NONE) {
	/* Someone who was suspended on read can now be revived. */
	r = subread(log, log->log_iosize, log->log_source, log->log_grant);

	chardriver_reply_task(log->log_source, log->log_id, r);

	log->log_source = NONE;
  }

  if (log->log_size > 0 && (log->log_selected & CDEV_OP_RD)) {
	/* Someone(s) who was/were select()ing can now be awoken. If there was
	 * a blocking read (above), this can only happen if the blocking read
	 * didn't swallow all the data (log_size > 0).
	 */
	minor = log-logdevices;
#if LOG_DEBUG
	printf("select sending CDEV_SEL2_REPLY\n");
#endif
	chardriver_reply_select(log->log_select_proc, minor, CDEV_OP_RD);
	log->log_selected &= ~CDEV_OP_RD;
  }

  return result;
}