123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- diff -uprN vblade-17.orig/aoe.c vblade-17/aoe.c
- --- vblade-17.orig/aoe.c 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/aoe.c 2008-06-09 11:05:23.000000000 -0400
- @@ -8,6 +8,9 @@
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <netinet/in.h>
- +#include <errno.h>
- +#include <aio.h>
- +#include <poll.h>
- #include "dat.h"
- #include "fns.h"
-
- @@ -22,6 +25,11 @@ char config[Nconfig];
- int nconfig = 0;
- int maxscnt = 2;
- char *ifname;
- +int queuepipe[2];
- +int pktlen[Nplaces], pending[Nplaces];
- +Ata *pkt[Nplaces];
- +Ataregs regs[Nplaces];
- +struct aiocb aiocb[Nplaces];
-
- void
- aoead(int fd) // advertise the virtual blade
- @@ -78,32 +86,52 @@ getlba(uchar *p)
- }
-
- int
- -aoeata(Ata *p, int pktlen) // do ATA reqeust
- +aoeata(int place) // do ATA reqeust
- {
- - Ataregs r;
- - int len = 60;
- int n;
- + int len = 60; // minimum ethernet packet size
-
- - r.lba = getlba(p->lba);
- - r.sectors = p->sectors;
- - r.feature = p->err;
- - r.cmd = p->cmd;
- - if (atacmd(&r, (uchar *)(p+1), maxscnt*512, pktlen - sizeof(*p)) < 0) {
- - p->h.flags |= Error;
- - p->h.error = BadArg;
- + regs[place].lba = getlba(pkt[place]->lba);
- + regs[place].sectors = pkt[place]->sectors;
- + regs[place].feature = pkt[place]->err;
- + regs[place].cmd = pkt[place]->cmd;
- + n = atacmd(regs + place, (uchar *)(pkt[place] + 1), maxscnt*512,
- + pktlen[place] - sizeof(Ata), aiocb + place);
- + if (n < 0) {
- + pkt[place]->h.flags |= Error;
- + pkt[place]->h.error = BadArg;
- return len;
- + } else if (n > 0) {
- + pending[place] = 1;
- + return 0;
- + }
- + if (!(pkt[place]->aflag & Write) && (n = pkt[place]->sectors)) {
- + n -= regs[place].sectors;
- + len = sizeof (Ata) + (n*512);
- }
- - if (!(p->aflag & Write))
- - if ((n = p->sectors)) {
- - n -= r.sectors;
- + pkt[place]->sectors = regs[place].sectors;
- + pkt[place]->err = regs[place].err;
- + pkt[place]->cmd = regs[place].status;
- + return len;
- +}
- +
- +int aoeatacomplete(int place, int pktlen)
- +{
- + int n;
- + int len = 60; // minimum ethernet packet size
- + atacmdcomplete(regs + place, aiocb + place);
- + if (!(pkt[place]->aflag & Write) && (n = pkt[place]->sectors)) {
- + n -= regs[place].sectors;
- len = sizeof (Ata) + (n*512);
- }
- - p->sectors = r.sectors;
- - p->err = r.err;
- - p->cmd = r.status;
- + pkt[place]->sectors = regs[place].sectors;
- + pkt[place]->err = regs[place].err;
- + pkt[place]->cmd = regs[place].status;
- + pending[place] = 0;
- return len;
- }
-
- +
- #define QCMD(x) ((x)->vercmd & 0xf)
-
- // yes, this makes unnecessary copies.
- @@ -156,8 +184,9 @@ confcmd(Conf *p, int payload) // process
- }
-
- void
- -doaoe(Aoehdr *p, int n)
- +doaoe(int place)
- {
- + Aoehdr *p = (Aoehdr *) pkt[place];
- int len;
- enum { // config query header size
- CHDR_SIZ = sizeof(Conf) - sizeof(((Conf *)0)->data),
- @@ -165,14 +194,16 @@ doaoe(Aoehdr *p, int n)
-
- switch (p->cmd) {
- case ATAcmd:
- - if (n < sizeof(Ata))
- + if (pktlen[place] < sizeof(Ata))
- + return;
- + len = aoeata(place);
- + if (len == 0)
- return;
- - len = aoeata((Ata*)p, n);
- break;
- case Config:
- - if (n < CHDR_SIZ)
- + if (pktlen[place] < CHDR_SIZ)
- return;
- - len = confcmd((Conf *)p, n - CHDR_SIZ);
- + len = confcmd((Conf *)p, pktlen[place] - CHDR_SIZ);
- if (len == 0)
- return;
- break;
- @@ -193,25 +224,129 @@ doaoe(Aoehdr *p, int n)
- }
-
- void
- +doaoecomplete(int place)
- +{
- + Aoehdr *p = (Aoehdr *) pkt[place];
- + int len = aoeatacomplete(place, pktlen[place]);
- + memmove(p->dst, p->src, 6);
- + memmove(p->src, mac, 6);
- + p->maj = htons(shelf);
- + p->min = slot;
- + p->flags |= Resp;
- + if (putpkt(sfd, (uchar *) p, len) == -1) {
- + perror("write to network");
- + exit(1);
- + }
- +
- +}
- +
- +// allocate the buffer so that the ata data area
- +// is page aligned for o_direct on linux
- +
- +void *
- +bufalloc(void **buf, long len)
- +{
- + long psize;
- + unsigned long n;
- +
- + psize = sysconf(_SC_PAGESIZE);
- + if (psize == -1) {
- + perror("sysconf");
- + exit(EXIT_FAILURE);
- + }
- + n = len/psize + 3;
- + *buf = malloc(psize * n);
- + if (!*buf) {
- + perror("malloc");
- + exit(EXIT_FAILURE);
- + }
- + n = (unsigned long) *buf;
- + n += psize * 2;
- + n &= ~(psize - 1);
- + return (void *) (n - sizeof (Ata));
- +}
- +
- +void
- +sigio(int signo)
- +{
- + const char dummy = 0;
- + write(queuepipe[1], &dummy, 1);
- +}
- +
- +void
- aoe(void)
- {
- Aoehdr *p;
- - uchar *buf;
- - int n, sh;
- + char dummy;
- + int n, place, sh;
- enum { bufsz = 1<<16, };
- -
- - buf = malloc(bufsz);
- + sigset_t mask, oldmask;
- + struct sigaction sigact;
- + struct pollfd pollfds[2];
- + void *freeme[Nplaces];
- +
- + for (n = 0; n < Nplaces; n++) {
- + pkt[n] = bufalloc(freeme + n, bufsz);
- + pending[n] = 0;
- + }
- aoead(sfd);
-
- + pipe(queuepipe);
- + fcntl(queuepipe[0], F_SETFL, O_NONBLOCK);
- + fcntl(queuepipe[1], F_SETFL, O_NONBLOCK);
- +
- + sigemptyset(&sigact.sa_mask);
- + sigact.sa_flags = 0;
- + sigact.sa_sigaction = (void *) sigio;
- + sigaction(SIGIO, &sigact, NULL);
- +
- + sigemptyset(&mask);
- + sigaddset(&mask, SIGIO);
- + sigprocmask(SIG_BLOCK, &mask, &oldmask);
- +
- + pollfds[0].fd = queuepipe[0];
- + pollfds[1].fd = sfd;
- + pollfds[0].events = pollfds[1].events = POLLIN;
- +
- for (;;) {
- - n = getpkt(sfd, buf, bufsz);
- - if (n < 0) {
- + sigprocmask(SIG_SETMASK, &oldmask, NULL);
- + n = poll(pollfds, 2, 1000);
- + sigprocmask(SIG_BLOCK, &mask, NULL);
- +
- + if (n < 0 && errno != EINTR) {
- + perror("poll");
- + continue;
- + } else if (n == 0 || pollfds[0].revents & POLLIN) {
- + while(read(queuepipe[0], &dummy, 1) > 0);
- + for (place = 0; place < Nplaces; place++) {
- + if (!pending[place])
- + continue;
- + if (aio_error(aiocb + place) == EINPROGRESS)
- + continue;
- + doaoecomplete(place);
- + pollfds[1].events = POLLIN;
- + }
- + }
- +
- + if ((pollfds[1].revents & POLLIN) == 0)
- + continue;
- +
- + for (place = 0; pending[place] && place < Nplaces; place++);
- + if (place >= Nplaces) {
- + pollfds[1].events = 0;
- + continue;
- + }
- +
- + pktlen[place] = getpkt(sfd, (uchar *) pkt[place], bufsz);
- + if (pktlen[place] < 0) {
- + if (errno == EINTR)
- + continue;
- perror("read network");
- exit(1);
- }
- - if (n < sizeof(Aoehdr))
- + if (pktlen[place] < sizeof(Aoehdr))
- continue;
- - p = (Aoehdr *) buf;
- + p = (Aoehdr *) pkt[place];
- if (ntohs(p->type) != 0x88a2)
- continue;
- if (p->flags & Resp)
- @@ -223,9 +358,10 @@ aoe(void)
- continue;
- if (nmasks && !maskok(p->src))
- continue;
- - doaoe(p, n);
- + doaoe(place);
- }
- - free(buf);
- + for (place = 0; place < Nplaces; place++)
- + free(freeme[place]);
- }
-
- void
- @@ -317,7 +453,7 @@ main(int argc, char **argv)
- }
- if (s.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))
- omode = O_RDWR;
- - bfd = open(argv[3], omode);
- + bfd = opendisk(argv[3], omode);
- if (bfd == -1) {
- perror("open");
- exit(1);
- diff -uprN vblade-17.orig/ata.c vblade-17/ata.c
- --- vblade-17.orig/ata.c 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/ata.c 2008-06-09 11:05:23.000000000 -0400
- @@ -3,6 +3,8 @@
- #include <string.h>
- #include <stdio.h>
- #include <sys/types.h>
- +#include <errno.h>
- +#include <aio.h>
- #include "dat.h"
- #include "fns.h"
-
- @@ -98,7 +100,7 @@ atainit(void)
- * check for that.
- */
- int
- -atacmd(Ataregs *p, uchar *dp, int ndp, int payload) // do the ata cmd
- +atacmd(Ataregs *p, uchar *dp, int ndp, int payload, struct aiocb *aiocb) // do the ata cmd
- {
- vlong lba;
- ushort *ip;
- @@ -155,14 +157,29 @@ atacmd(Ataregs *p, uchar *dp, int ndp, i
- return 0;
- }
- if (p->cmd == 0x20 || p->cmd == 0x24)
- - n = getsec(bfd, dp, lba, p->sectors);
- + n = getsec(bfd, dp, lba, p->sectors, aiocb);
- else {
- // packet should be big enough to contain the data
- if (payload < 512 * p->sectors)
- return -1;
- - n = putsec(bfd, dp, lba, p->sectors);
- + n = putsec(bfd, dp, lba, p->sectors, aiocb);
- }
- - n /= 512;
- + if (n < 0) {
- + p->err = ABRT;
- + p->status = ERR|DRDY;
- + p->lba += n;
- + p->sectors -= n;
- + return 0;
- + }
- + return 1; // callback expected
- +}
- +
- +
- +int
- +atacmdcomplete(Ataregs *p, struct aiocb *aiocb) // complete the ata cmd
- +{
- + int n;
- + n = aio_return(aiocb) / 512;
- if (n != p->sectors) {
- p->err = ABRT;
- p->status = ERR;
- @@ -173,4 +190,3 @@ atacmd(Ataregs *p, uchar *dp, int ndp, i
- p->sectors -= n;
- return 0;
- }
- -
- diff -uprN vblade-17.orig/dat.h vblade-17/dat.h
- --- vblade-17.orig/dat.h 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/dat.h 2008-06-09 11:05:23.000000000 -0400
- @@ -111,6 +111,8 @@ enum {
- Nconfig = 1024,
-
- Bufcount = 16,
- +
- + Nplaces = 32,
- };
-
- int shelf, slot;
- diff -uprN vblade-17.orig/fns.h vblade-17/fns.h
- --- vblade-17.orig/fns.h 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/fns.h 2008-06-09 11:07:21.000000000 -0400
- @@ -15,7 +15,8 @@ int maskok(uchar *);
- // ata.c
-
- void atainit(void);
- -int atacmd(Ataregs *, uchar *, int, int);
- +int atacmd(Ataregs *, uchar *, int, int, struct aiocb *);
- +int atacmdcomplete(Ataregs *, struct aiocb *);
-
- // bpf.c
-
- @@ -26,8 +27,9 @@ void free_bpf_program(void *);
-
- int dial(char *);
- int getea(int, char *, uchar *);
- -int putsec(int, uchar *, vlong, int);
- -int getsec(int, uchar *, vlong, int);
- +int opendisk(const char *, int);
- +int putsec(int, uchar *, vlong, int, struct aiocb *);
- +int getsec(int, uchar *, vlong, int, struct aiocb *);
- int putpkt(int, uchar *, int);
- int getpkt(int, uchar *, int);
- vlong getsize(int);
- diff -uprN vblade-17.orig/freebsd.c vblade-17/freebsd.c
- --- vblade-17.orig/freebsd.c 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/freebsd.c 2008-06-09 11:05:23.000000000 -0400
- @@ -209,19 +209,40 @@ getea(int s, char *eth, uchar *ea)
- return(0);
- }
-
- -
- int
- -getsec(int fd, uchar *place, vlong lba, int nsec)
- +opendisk(const char *disk, int omode)
- {
- - return pread(fd, place, nsec * 512, lba * 512);
- + return open(disk, omode);
- }
-
- int
- -putsec(int fd, uchar *place, vlong lba, int nsec)
- -{
- - return pwrite(fd, place, nsec * 512, lba * 512);
- +getsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
- +{
- + bzero((char *) aiocb, sizeof(struct aiocb));
- + aiocb->aio_fildes = fd;
- + aiocb->aio_buf = place;
- + aiocb->aio_nbytes = nsec * 512;
- + aiocb->aio_offset = lba * 512;
- + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- + aiocb->aio_sigevent.sigev_signo = SIGIO;
- + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
- + return aio_read(aiocb);
- }
-
- +int
- +putsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
- +{
- + bzero((char *) aiocb, sizeof(struct aiocb));
- + aiocb->aio_fildes = fd;
- + aiocb->aio_buf = place;
- + aiocb->aio_nbytes = nsec * 512;
- + aiocb->aio_offset = lba * 512;
- + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- + aiocb->aio_sigevent.sigev_signo = SIGIO;
- + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
- + return aio_write(aiocb);
- +}
- +
- static int pktn = 0;
- static uchar *pktbp = NULL;
-
- diff -uprN vblade-17.orig/linux.c vblade-17/linux.c
- --- vblade-17.orig/linux.c 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/linux.c 2008-06-09 11:05:23.000000000 -0400
- @@ -1,5 +1,6 @@
- // linux.c: low level access routines for Linux
- #include "config.h"
- +#define _GNU_SOURCE
- #include <sys/socket.h>
- #include <stdio.h>
- #include <string.h>
- @@ -22,6 +23,9 @@
- #include <netinet/in.h>
- #include <linux/fs.h>
- #include <sys/stat.h>
- +#include <fcntl.h>
- +#include <errno.h>
- +#include <aio.h>
-
- #include "dat.h"
- #include "fns.h"
- @@ -29,8 +33,6 @@
- int getindx(int, char *);
- int getea(int, char *, uchar *);
-
- -
- -
- int
- dial(char *eth) // get us a raw connection to an interface
- {
- @@ -84,7 +86,7 @@ getea(int s, char *name, uchar *ea)
- struct ifreq xx;
- int n;
-
- - strcpy(xx.ifr_name, name);
- + strcpy(xx.ifr_name, name);
- n = ioctl(s, SIOCGIFHWADDR, &xx);
- if (n == -1) {
- perror("Can't get hw addr");
- @@ -110,17 +112,37 @@ getmtu(int s, char *name)
- }
-
- int
- -getsec(int fd, uchar *place, vlong lba, int nsec)
- +opendisk(const char *disk, int omode)
- +{
- + return open(disk, omode|O_DIRECT);
- +}
- +
- +int
- +getsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
- {
- - lseek(fd, lba * 512, 0);
- - return read(fd, place, nsec * 512);
- + bzero((char *) aiocb, sizeof(struct aiocb));
- + aiocb->aio_fildes = fd;
- + aiocb->aio_buf = place;
- + aiocb->aio_nbytes = nsec * 512;
- + aiocb->aio_offset = lba * 512;
- + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- + aiocb->aio_sigevent.sigev_signo = SIGIO;
- + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
- + return aio_read(aiocb);
- }
-
- int
- -putsec(int fd, uchar *place, vlong lba, int nsec)
- +putsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb)
- {
- - lseek(fd, lba * 512, 0);
- - return write(fd, place, nsec * 512);
- + bzero((char *) aiocb, sizeof(struct aiocb));
- + aiocb->aio_fildes = fd;
- + aiocb->aio_buf = place;
- + aiocb->aio_nbytes = nsec * 512;
- + aiocb->aio_offset = lba * 512;
- + aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- + aiocb->aio_sigevent.sigev_signo = SIGIO;
- + aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb;
- + return aio_write(aiocb);
- }
-
- int
- diff -uprN vblade-17.orig/linux.h vblade-17/linux.h
- --- vblade-17.orig/linux.h 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/linux.h 2008-06-09 11:05:23.000000000 -0400
- @@ -6,6 +6,6 @@ typedef long long vlong;
- int dial(char *);
- int getindx(int, char *);
- int getea(int, char *, uchar *);
- -int getsec(int, uchar *, vlong, int);
- -int putsec(int, uchar *, vlong, int);
- +int getsec(int, uchar *, vlong, int, struct aiocb *);
- +int putsec(int, uchar *, vlong, int, struct aiocb *);
- vlong getsize(int);
- diff -uprN vblade-17.orig/makefile vblade-17/makefile
- --- vblade-17.orig/makefile 2008-06-09 10:53:07.000000000 -0400
- +++ vblade-17/makefile 2008-06-09 11:05:23.000000000 -0400
- @@ -13,7 +13,7 @@ CFLAGS += -Wall -g -O2
- CC = gcc
-
- vblade: $O
- - ${CC} -o vblade $O
- + ${CC} -lrt -o vblade $O
-
- aoe.o : aoe.c config.h dat.h fns.h makefile
- ${CC} ${CFLAGS} -c $<
|