Plan 9 from Bell Labs’s /usr/web/sources/contrib/quanstro/root/sys/src/cmd/aoesnap/aoe.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <goo.h>
#include "snap.h"

int	shelf;

enum{
	Rbsize	= 8192,
};

typedef struct{
	int	fd;
	uchar	buf[Rbsize];
	long	blen;
	uvlong	boff;
}Afd;

Afd atab[3] = {{.fd =-1,}, {.fd = -1,}, {.fd = -1,},};

static int
tailio(Afd *t, long (*io)(int, void*, long, vlong), void *buf, ulong l, uvlong byte)
{
	int r;
	ulong rem;

	rem = byte&(Rbsize-1);
	if(l+rem > Rbsize)
		l = Rbsize-rem;
	if(t->boff == byte)
		r = t->blen;
	else{
		r = pread(t->fd, t->buf, Rbsize, byte-rem);
		if(r < 0){
			t->boff = -1;
			return -1;
		}
		t->boff = byte-rem;
		t->blen = r;
	}
	if(l+rem >= r)
		l = r-rem;
	else if(io == pwrite)
		return -1;

	if(io == pwrite){
		memmove(t->buf+rem, buf, l);
		r = io(t->fd, t->buf, r, byte-rem);
		if(r != t->blen)
			return -1;
	}else
		memmove(buf, t->buf+rem, l);
	return l;
}

static int
byteio(Afd *t, long (*d)(int, void*, long, vlong), char *buf, ulong l, uvlong byte)
{
	int r;
	ulong l0;

	l0 = l;
loop:
	if(l == 0)
		return l0-l;
	if((r = tailio(t, d, buf, l, byte)) < 0)
		return -1;
	byte += r;
	buf += r;
	l -= r;
	if(byte%Rbsize)
		return l0-l;

	while(l >= Rbsize){
		if((r = d(t->fd, buf, Rbsize, byte)) < 0)
			return -1;
		byte += r;
		buf += r;
		l -= r;
		if(r < Rbsize)
			return l0-l;
	}
	goto loop;
}

Afd*
afd(int fd)
{
	int i;

	for(i = 0; i < nelem(atab); i++)
		if(atab[i].fd == fd)
			return atab+i;
	return 0;
}

long
aoepread(int fd, void *buf, long n, vlong offset)
{
	return byteio(afd(fd), pread, buf, n, offset);
}

long
aoepwrite(int fd, void *buf, long n, vlong offset)
{
	return byteio(afd(fd), pwrite, buf, n, offset);
}

void
aoeclose(int fd)
{
	Afd *a;

	a = afd(fd);
	if(a == 0)
		sysfatal("bad aoefd %d", fd);
	close(fd);
	a->fd = -1;
}

int
aoeopen(int slot)
{
	char buf[64];
	Afd *a;

	for(a = atab; a < atab+nelem(atab); a++)
		if(a->fd == -1)
			goto found;
	sysfatal("too many open aoe devices");
found:
#ifdef LINUX
	snprint(buf, sizeof buf, "/dev/etherd/e%d.%d", shelf, slot);
#else
	snprint(buf, sizeof buf, "/dev/aoe/%d.%d/data", shelf, slot);
#endif
	a->fd = open(buf, OREAD);
	a->boff = -1;
	if(a->fd == -1)
		sysfatal("aoeopen[%s]: %r", buf);
	return a->fd;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].