/* * 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); }
/* * 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); }
/* * 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)); }
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; }