|
@@ -0,0 +1,536 @@
|
|
|
+diff -uprN vblade-15/aoe.c vblade-15-aio/aoe.c
|
|
|
+--- vblade-15/aoe.c 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/aoe.c 2008-04-19 22:31:21.000000000 +0100
|
|
|
+@@ -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-15/ata.c vblade-15-aio/ata.c
|
|
|
+--- vblade-15/ata.c 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/ata.c 2008-04-19 22:12:32.000000000 +0100
|
|
|
+@@ -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-15/dat.h vblade-15-aio/dat.h
|
|
|
+--- vblade-15/dat.h 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/dat.h 2008-04-19 16:34:35.000000000 +0100
|
|
|
+@@ -111,6 +111,8 @@ enum {
|
|
|
+ Nconfig = 1024,
|
|
|
+
|
|
|
+ Bufcount = 16,
|
|
|
++
|
|
|
++ Nplaces = 32,
|
|
|
+ };
|
|
|
+
|
|
|
+ int shelf, slot;
|
|
|
+diff -uprN vblade-15/fns.h vblade-15-aio/fns.h
|
|
|
+--- vblade-15/fns.h 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/fns.h 2008-04-17 00:11:36.000000000 +0100
|
|
|
+@@ -15,14 +15,16 @@ 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 *);
|
|
|
+
|
|
|
+ // os specific
|
|
|
+
|
|
|
+ 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-15/freebsd.c vblade-15-aio/freebsd.c
|
|
|
+--- vblade-15/freebsd.c 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/freebsd.c 2008-04-19 22:24:57.000000000 +0100
|
|
|
+@@ -241,19 +241,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-15/linux.c vblade-15-aio/linux.c
|
|
|
+--- vblade-15/linux.c 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/linux.c 2008-04-19 22:23:51.000000000 +0100
|
|
|
+@@ -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
|
|
|
+ {
|
|
|
+@@ -76,7 +78,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");
|
|
|
+@@ -102,17 +104,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-15/linux.h vblade-15-aio/linux.h
|
|
|
+--- vblade-15/linux.h 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/linux.h 2008-04-16 23:03:07.000000000 +0100
|
|
|
+@@ -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-15/makefile vblade-15-aio/makefile
|
|
|
+--- vblade-15/makefile 2008-03-07 20:22:16.000000000 +0000
|
|
|
++++ vblade-15-aio/makefile 2008-04-16 19:09:46.000000000 +0100
|
|
|
+@@ -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 $<
|