1 diff -uprN vblade-17.orig/aoe.c vblade-17/aoe.c
2 --- vblade-17.orig/aoe.c 2008-06-09 10:53:07.000000000 -0400
3 +++ vblade-17/aoe.c 2008-06-09 11:05:23.000000000 -0400
7 #include <netinet/in.h>
14 @@ -22,6 +25,11 @@ char config[Nconfig];
19 +int pktlen[Nplaces], pending[Nplaces];
21 +Ataregs regs[Nplaces];
22 +struct aiocb aiocb[Nplaces];
25 aoead(int fd) // advertise the virtual blade
26 @@ -78,32 +86,52 @@ getlba(uchar *p)
30 -aoeata(Ata *p, int pktlen) // do ATA reqeust
31 +aoeata(int place) // do ATA reqeust
36 + int len = 60; // minimum ethernet packet size
38 - r.lba = getlba(p->lba);
39 - r.sectors = p->sectors;
42 - if (atacmd(&r, (uchar *)(p+1), maxscnt*512, pktlen - sizeof(*p)) < 0) {
43 - p->h.flags |= Error;
44 - p->h.error = BadArg;
45 + regs[place].lba = getlba(pkt[place]->lba);
46 + regs[place].sectors = pkt[place]->sectors;
47 + regs[place].feature = pkt[place]->err;
48 + regs[place].cmd = pkt[place]->cmd;
49 + n = atacmd(regs + place, (uchar *)(pkt[place] + 1), maxscnt*512,
50 + pktlen[place] - sizeof(Ata), aiocb + place);
52 + pkt[place]->h.flags |= Error;
53 + pkt[place]->h.error = BadArg;
59 + if (!(pkt[place]->aflag & Write) && (n = pkt[place]->sectors)) {
60 + n -= regs[place].sectors;
61 + len = sizeof (Ata) + (n*512);
63 - if (!(p->aflag & Write))
64 - if ((n = p->sectors)) {
66 + pkt[place]->sectors = regs[place].sectors;
67 + pkt[place]->err = regs[place].err;
68 + pkt[place]->cmd = regs[place].status;
72 +int aoeatacomplete(int place, int pktlen)
75 + int len = 60; // minimum ethernet packet size
76 + atacmdcomplete(regs + place, aiocb + place);
77 + if (!(pkt[place]->aflag & Write) && (n = pkt[place]->sectors)) {
78 + n -= regs[place].sectors;
79 len = sizeof (Ata) + (n*512);
81 - p->sectors = r.sectors;
84 + pkt[place]->sectors = regs[place].sectors;
85 + pkt[place]->err = regs[place].err;
86 + pkt[place]->cmd = regs[place].status;
92 #define QCMD(x) ((x)->vercmd & 0xf)
94 // yes, this makes unnecessary copies.
95 @@ -156,8 +184,9 @@ confcmd(Conf *p, int payload) // process
99 -doaoe(Aoehdr *p, int n)
102 + Aoehdr *p = (Aoehdr *) pkt[place];
104 enum { // config query header size
105 CHDR_SIZ = sizeof(Conf) - sizeof(((Conf *)0)->data),
106 @@ -165,14 +194,16 @@ doaoe(Aoehdr *p, int n)
110 - if (n < sizeof(Ata))
111 + if (pktlen[place] < sizeof(Ata))
113 + len = aoeata(place);
116 - len = aoeata((Ata*)p, n);
120 + if (pktlen[place] < CHDR_SIZ)
122 - len = confcmd((Conf *)p, n - CHDR_SIZ);
123 + len = confcmd((Conf *)p, pktlen[place] - CHDR_SIZ);
127 @@ -193,25 +224,129 @@ doaoe(Aoehdr *p, int n)
131 +doaoecomplete(int place)
133 + Aoehdr *p = (Aoehdr *) pkt[place];
134 + int len = aoeatacomplete(place, pktlen[place]);
135 + memmove(p->dst, p->src, 6);
136 + memmove(p->src, mac, 6);
137 + p->maj = htons(shelf);
140 + if (putpkt(sfd, (uchar *) p, len) == -1) {
141 + perror("write to network");
147 +// allocate the buffer so that the ata data area
148 +// is page aligned for o_direct on linux
151 +bufalloc(void **buf, long len)
156 + psize = sysconf(_SC_PAGESIZE);
159 + exit(EXIT_FAILURE);
162 + *buf = malloc(psize * n);
165 + exit(EXIT_FAILURE);
167 + n = (unsigned long) *buf;
170 + return (void *) (n - sizeof (Ata));
176 + const char dummy = 0;
177 + write(queuepipe[1], &dummy, 1);
188 enum { bufsz = 1<<16, };
190 - buf = malloc(bufsz);
191 + sigset_t mask, oldmask;
192 + struct sigaction sigact;
193 + struct pollfd pollfds[2];
194 + void *freeme[Nplaces];
196 + for (n = 0; n < Nplaces; n++) {
197 + pkt[n] = bufalloc(freeme + n, bufsz);
203 + fcntl(queuepipe[0], F_SETFL, O_NONBLOCK);
204 + fcntl(queuepipe[1], F_SETFL, O_NONBLOCK);
206 + sigemptyset(&sigact.sa_mask);
207 + sigact.sa_flags = 0;
208 + sigact.sa_sigaction = (void *) sigio;
209 + sigaction(SIGIO, &sigact, NULL);
211 + sigemptyset(&mask);
212 + sigaddset(&mask, SIGIO);
213 + sigprocmask(SIG_BLOCK, &mask, &oldmask);
215 + pollfds[0].fd = queuepipe[0];
216 + pollfds[1].fd = sfd;
217 + pollfds[0].events = pollfds[1].events = POLLIN;
220 - n = getpkt(sfd, buf, bufsz);
222 + sigprocmask(SIG_SETMASK, &oldmask, NULL);
223 + n = poll(pollfds, 2, 1000);
224 + sigprocmask(SIG_BLOCK, &mask, NULL);
226 + if (n < 0 && errno != EINTR) {
229 + } else if (n == 0 || pollfds[0].revents & POLLIN) {
230 + while(read(queuepipe[0], &dummy, 1) > 0);
231 + for (place = 0; place < Nplaces; place++) {
232 + if (!pending[place])
234 + if (aio_error(aiocb + place) == EINPROGRESS)
236 + doaoecomplete(place);
237 + pollfds[1].events = POLLIN;
241 + if ((pollfds[1].revents & POLLIN) == 0)
244 + for (place = 0; pending[place] && place < Nplaces; place++);
245 + if (place >= Nplaces) {
246 + pollfds[1].events = 0;
250 + pktlen[place] = getpkt(sfd, (uchar *) pkt[place], bufsz);
251 + if (pktlen[place] < 0) {
252 + if (errno == EINTR)
254 perror("read network");
257 - if (n < sizeof(Aoehdr))
258 + if (pktlen[place] < sizeof(Aoehdr))
260 - p = (Aoehdr *) buf;
261 + p = (Aoehdr *) pkt[place];
262 if (ntohs(p->type) != 0x88a2)
265 @@ -223,9 +358,10 @@ aoe(void)
267 if (nmasks && !maskok(p->src))
273 + for (place = 0; place < Nplaces; place++)
274 + free(freeme[place]);
278 @@ -317,7 +453,7 @@ main(int argc, char **argv)
280 if (s.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))
282 - bfd = open(argv[3], omode);
283 + bfd = opendisk(argv[3], omode);
287 diff -uprN vblade-17.orig/ata.c vblade-17/ata.c
288 --- vblade-17.orig/ata.c 2008-06-09 10:53:07.000000000 -0400
289 +++ vblade-17/ata.c 2008-06-09 11:05:23.000000000 -0400
293 #include <sys/types.h>
299 @@ -98,7 +100,7 @@ atainit(void)
303 -atacmd(Ataregs *p, uchar *dp, int ndp, int payload) // do the ata cmd
304 +atacmd(Ataregs *p, uchar *dp, int ndp, int payload, struct aiocb *aiocb) // do the ata cmd
308 @@ -155,14 +157,29 @@ atacmd(Ataregs *p, uchar *dp, int ndp, i
311 if (p->cmd == 0x20 || p->cmd == 0x24)
312 - n = getsec(bfd, dp, lba, p->sectors);
313 + n = getsec(bfd, dp, lba, p->sectors, aiocb);
315 // packet should be big enough to contain the data
316 if (payload < 512 * p->sectors)
318 - n = putsec(bfd, dp, lba, p->sectors);
319 + n = putsec(bfd, dp, lba, p->sectors, aiocb);
324 + p->status = ERR|DRDY;
329 + return 1; // callback expected
334 +atacmdcomplete(Ataregs *p, struct aiocb *aiocb) // complete the ata cmd
337 + n = aio_return(aiocb) / 512;
338 if (n != p->sectors) {
341 @@ -173,4 +190,3 @@ atacmd(Ataregs *p, uchar *dp, int ndp, i
346 diff -uprN vblade-17.orig/dat.h vblade-17/dat.h
347 --- vblade-17.orig/dat.h 2008-06-09 10:53:07.000000000 -0400
348 +++ vblade-17/dat.h 2008-06-09 11:05:23.000000000 -0400
349 @@ -111,6 +111,8 @@ enum {
358 diff -uprN vblade-17.orig/fns.h vblade-17/fns.h
359 --- vblade-17.orig/fns.h 2008-06-09 10:53:07.000000000 -0400
360 +++ vblade-17/fns.h 2008-06-09 11:07:21.000000000 -0400
361 @@ -15,7 +15,8 @@ int maskok(uchar *);
365 -int atacmd(Ataregs *, uchar *, int, int);
366 +int atacmd(Ataregs *, uchar *, int, int, struct aiocb *);
367 +int atacmdcomplete(Ataregs *, struct aiocb *);
371 @@ -26,8 +27,9 @@ void free_bpf_program(void *);
374 int getea(int, char *, uchar *);
375 -int putsec(int, uchar *, vlong, int);
376 -int getsec(int, uchar *, vlong, int);
377 +int opendisk(const char *, int);
378 +int putsec(int, uchar *, vlong, int, struct aiocb *);
379 +int getsec(int, uchar *, vlong, int, struct aiocb *);
380 int putpkt(int, uchar *, int);
381 int getpkt(int, uchar *, int);
383 diff -uprN vblade-17.orig/freebsd.c vblade-17/freebsd.c
384 --- vblade-17.orig/freebsd.c 2008-06-09 10:53:07.000000000 -0400
385 +++ vblade-17/freebsd.c 2008-06-09 11:05:23.000000000 -0400
386 @@ -209,19 +209,40 @@ getea(int s, char *eth, uchar *ea)
392 -getsec(int fd, uchar *place, vlong lba, int nsec)
393 +opendisk(const char *disk, int omode)
395 - return pread(fd, place, nsec * 512, lba * 512);
396 + return open(disk, omode);
400 -putsec(int fd, uchar *place, vlong lba, int nsec)
402 - return pwrite(fd, place, nsec * 512, lba * 512);
403 +getsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
405 + bzero((char *) aiocb, sizeof(struct aiocb));
406 + aiocb->aio_fildes = fd;
407 + aiocb->aio_buf = place;
408 + aiocb->aio_nbytes = nsec * 512;
409 + aiocb->aio_offset = lba * 512;
410 + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
411 + aiocb->aio_sigevent.sigev_signo = SIGIO;
412 + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
413 + return aio_read(aiocb);
417 +putsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
419 + bzero((char *) aiocb, sizeof(struct aiocb));
420 + aiocb->aio_fildes = fd;
421 + aiocb->aio_buf = place;
422 + aiocb->aio_nbytes = nsec * 512;
423 + aiocb->aio_offset = lba * 512;
424 + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
425 + aiocb->aio_sigevent.sigev_signo = SIGIO;
426 + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
427 + return aio_write(aiocb);
431 static uchar *pktbp = NULL;
433 diff -uprN vblade-17.orig/linux.c vblade-17/linux.c
434 --- vblade-17.orig/linux.c 2008-06-09 10:53:07.000000000 -0400
435 +++ vblade-17/linux.c 2008-06-09 11:05:23.000000000 -0400
437 // linux.c: low level access routines for Linux
440 #include <sys/socket.h>
444 #include <netinet/in.h>
445 #include <linux/fs.h>
446 #include <sys/stat.h>
454 int getindx(int, char *);
455 int getea(int, char *, uchar *);
460 dial(char *eth) // get us a raw connection to an interface
462 @@ -84,7 +86,7 @@ getea(int s, char *name, uchar *ea)
466 - strcpy(xx.ifr_name, name);
467 + strcpy(xx.ifr_name, name);
468 n = ioctl(s, SIOCGIFHWADDR, &xx);
470 perror("Can't get hw addr");
471 @@ -110,17 +112,37 @@ getmtu(int s, char *name)
475 -getsec(int fd, uchar *place, vlong lba, int nsec)
476 +opendisk(const char *disk, int omode)
478 + return open(disk, omode|O_DIRECT);
482 +getsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
484 - lseek(fd, lba * 512, 0);
485 - return read(fd, place, nsec * 512);
486 + bzero((char *) aiocb, sizeof(struct aiocb));
487 + aiocb->aio_fildes = fd;
488 + aiocb->aio_buf = place;
489 + aiocb->aio_nbytes = nsec * 512;
490 + aiocb->aio_offset = lba * 512;
491 + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
492 + aiocb->aio_sigevent.sigev_signo = SIGIO;
493 + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
494 + return aio_read(aiocb);
498 -putsec(int fd, uchar *place, vlong lba, int nsec)
499 +putsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
501 - lseek(fd, lba * 512, 0);
502 - return write(fd, place, nsec * 512);
503 + bzero((char *) aiocb, sizeof(struct aiocb));
504 + aiocb->aio_fildes = fd;
505 + aiocb->aio_buf = place;
506 + aiocb->aio_nbytes = nsec * 512;
507 + aiocb->aio_offset = lba * 512;
508 + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
509 + aiocb->aio_sigevent.sigev_signo = SIGIO;
510 + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
511 + return aio_write(aiocb);
515 diff -uprN vblade-17.orig/linux.h vblade-17/linux.h
516 --- vblade-17.orig/linux.h 2008-06-09 10:53:07.000000000 -0400
517 +++ vblade-17/linux.h 2008-06-09 11:05:23.000000000 -0400
518 @@ -6,6 +6,6 @@ typedef long long vlong;
520 int getindx(int, char *);
521 int getea(int, char *, uchar *);
522 -int getsec(int, uchar *, vlong, int);
523 -int putsec(int, uchar *, vlong, int);
524 +int getsec(int, uchar *, vlong, int, struct aiocb *);
525 +int putsec(int, uchar *, vlong, int, struct aiocb *);
527 diff -uprN vblade-17.orig/makefile vblade-17/makefile
528 --- vblade-17.orig/makefile 2008-06-09 10:53:07.000000000 -0400
529 +++ vblade-17/makefile 2008-06-09 11:05:23.000000000 -0400
530 @@ -13,7 +13,7 @@ CFLAGS += -Wall -g -O2
535 + ${CC} -lrt -o vblade $O
537 aoe.o : aoe.c config.h dat.h fns.h makefile
538 ${CC} ${CFLAGS} -c $<