Ejemplo n.º 1
0
Archivo: nd_pkt.c Proyecto: senjan/ndd
/*
 * Verify incoming packet.
 */
static int
verify_pkt(ndpkt_t *p, int len)
{
	ndmin_t *m;
	long blkno = ntohl(p->np_blkno);
	long bcount = ntohl(p->np_bcount);

	if (ntohl(p->np_bcount) > ND_MAXIO) {
		log_msg(3, "bcount is too big: %lu.",
		    (unsigned long) ntohl(p->np_bcount));
		return (EIO);
	}

	if ((m = get_minor(p->np_min)) == NULL) {
		log_msg(3, "nd%d does not exist.", p->np_min);
		return (EIO);
	}

	if (m->mode == RDONLY && p->np_op & ND_OP_WRITE) {
		log_msg(3, "nd%d is read only.", p->np_min);
		return (EROFS);
	}

	if (blkno != GET_SIZE_REQ && blkno > (m->size / 512)) {
		log_msg(1, "nd%d is too small: has no blkno %lu.",
		    p->np_min, (unsigned long) blkno);
		return (EIO);
	}

	if (blkno == GET_SIZE_REQ && bcount != sizeof (uint32_t))
		return (EINVAL);

	return (0);
}
Ejemplo n.º 2
0
Archivo: nd_pkt.c Proyecto: senjan/ndd
/*
 * Read request processing.
 */
static int
serve_read(ndd_t *nds, ndpkt_t *p, int err)
{
	long caddr = 0;
	long bcount = ntohl(p->np_bcount);
	long blkno = ntohl(p->np_blkno);

	prepare_ip_header(p);

	if (blkno == GET_SIZE_REQ) {
		/* The client wants to know the size of this disk */
		if (err == 0) {
			uint32_t disk_size = htonl(get_minor_size(p->np_min));

			assert(bcount == sizeof (uint32_t));
			memcpy(&p->np_data, &disk_size, bcount);
			p->np_op |= ND_OP_DONE;
			p->np_caddr = 0;
			p->np_ccount = htonl(bcount);
			log_msg(8, "nd%d: get size request - has %d blks",
			    p->np_min, get_minor_size(p->np_min));
		} else {
			log_msg(4, "nd%d: get size request failed", p->np_min);
		}
		return (send_packet(nds, p, ND_HDRSZ + bcount, err));
	}

	/* This is normal read request. */
	assert(blkno < GET_SIZE_REQ);
	log_msg(9, "nd%d: read - blkno: %ld, count: %ld",
	    p->np_min, blkno, bcount);
	while (bcount > caddr) {
		long size, ccount, resid = bcount - caddr;
		off_t offset = blkno * 512 + caddr;

		ccount = resid > ND_MAXDATA ? ND_MAXDATA : resid;
		size = ND_HDRSZ + ccount;
		p->np_op |= ND_OP_DONE;
		p->np_caddr = htonl(caddr);
		p->np_ccount = htonl(ccount);

		if (err)
			return (send_packet(nds, p, size, err));

		ssize_t rc = pread(get_minor(p->np_min)->fd, &p->np_data,
		    (size_t) ccount, offset);
		if (rc != ccount) {
			log_msg(1, "nd%d: unable to read %ld bytes at "
			    "%ld. Got %ld, error: %d", p->np_min,
			    ccount, offset,
			    rc, errno);
			err = errno;
		}
		caddr += ccount;
		/* send reply */
		if (send_packet(nds, p, size, err))
			return (1);
	}
	return (0);
}
Ejemplo n.º 3
0
Archivo: nd_pkt.c Proyecto: senjan/ndd
/*
 * Write request processing.
 */
static int
serve_write(ndd_t *nds, ndpkt_t *p, int err)
{
	long caddr = ntohl(p->np_caddr);
	long ccount = ntohl(p->np_ccount);
	long blkno = ntohl(p->np_blkno);
	off_t offset = blkno * 512 + caddr;

	log_msg(9, "nd%d: write - blkno: %ld, count: %ld",
	    p->np_min, blkno, ccount);
	if (err == 0) {
		ndmin_t *m = get_minor(p->np_min);

		if (pwrite(m->fd, &p->np_data, ccount, offset) != ccount) {
			log_msg(1, "nd%d: unable to write %ld bytes,"
			    " offset %lu: %d", p->np_min, ccount, offset,
			    errno);
			err = errno;
		}
	}

	/*
	 * Send nothing when the client does not wait for the response or
	 * the packet was invalid (and hence we pretend that we got none.
	 */
	if (!(p->np_op & ND_OP_WAIT) || err == EINVAL)
		return (0);

	/* Prepare and send the reply. */
	prepare_ip_header(p);
	p->np_op = ND_OP_WRITE | ND_OP_DONE | ND_OP_WAIT;
	p->np_caddr = htonl(caddr + ccount);

	return (send_packet(nds, p, sizeof (ndpkt_t) - sizeof (void*), err));
}
Ejemplo n.º 4
0
int DetComputation::step()
     // Compute one more determinant of size p.
     // increments I and/or J and updates 'dets', 'table'.
{
  if (done) return COMP_DONE;

  ring_elem r;

  if (strategy == DET_BAREISS)
    {
      get_minor(row_set,col_set,p,D);
      r = bareiss_det();
    }
  else
    r = calc_det(row_set, col_set, p);

  if (!R->is_zero(r))
    {
      if (do_exterior)
        result.set_entry(this_row,this_col,r);
      else
        result.append(R->make_vec(0,r));
    }
  else
    R->remove(r);

  this_row++;
  if (!Subsets::increment(M->n_rows(), p, row_set))
    {
      // Now we increment column
      if (!Subsets::increment(M->n_cols(), p, col_set))
        {
          done = true;
          return COMP_DONE;
        }
      // Now set the row set back to initial value
      this_col++;
      this_row = 0;
      for (size_t i=0; i<p; i++) row_set[i]=i;
    }
  return COMP_COMPUTING;
}