[ENBD] [gmane.network.aoe.aoetools.general] enbd and 4TB
Peter T. Breuer
ptb at inv.it.uc3m.es
Sat Jan 14 13:52:10 MST 2006
"Also sprach Florian Frank:"
> could enbd handle devices with 4TB size?
In principle, yes, but of course I have no way of checking!
> enbd-server displays the
> correct size:
enbd-server 1035 /dev/sda -i storage1b -b 512
...
enbd-server 4200: server (-1) sent size 3999887523840 ok
OK.
> but if i start enbd-client it displays:
> enbd-client storage1b:1035 -i storage1b -n 2 -m -b 512 /dev/ndb
> enbd-client 23395: client (-1) got size 3999887523840
Well, the right size was handed over in the negotiation.
> enbd-client 23395: client (-1) set device size 1800864268288
Interesting. Is that half? A bit less than half. Very strange. The code
goes:
sscanf(buf, "%Lu\n", &size64) ....
self->size = size64;
MSG ("client (%d) got size %Lu\n", self->i, size64);
and the size field is 64 bit:
u64 size; /* PTB size of device in bytes */
so I would guess tha right size data is safely lodged in the client.
Let's move on ...
sectors = size64 >> 9;
// PTB rounding to multiple of 512
size64 = ((u64) sectors) << 9;
err = self->ioctl (self, ENBD_SET_SECTORS,
(char *) (unsigned long) sectors);
MSG ("client (%d) set device size %Lu\n", self->i,
(unsigned long long) size64);
so the problem appears to be the "sectors" count.
unsigned sectors;
Yerrs .. that's 32 bit. The ENBD_SET_SECTORS call expects a 32 bit
argument. It counts in 512B sectors, which is 9 bits, so it can get to
41 bits in size, which is, uh, 2TB.
Hmmm. Houston, we seem to have a 2TB limit there!
> "Support for Large Block Devices" is aktiv on both systems, kernel
> 2.6.15 and enbd 2.4.32.
Well, I don't know what that means. It might mean that the internal
size count for a device is in 4KB blocks insteatead of 512B sectors, or
it might mean that they use a 64 bit count, still in sectors, and that
there is a new call to set a large block device size which takes some
kind of new unit or else is 64 bit.
Harumph. I suspect the easist thing to do is to invent a
ENBD_SET_SECTORS64 ioctl to accept 64 bits for starters, then worry
about what to do in the kernel driver later.
In the enbd_base.c code, you should see
case ENBD_SET_SECTORS:
err = enbd_set_size (lo, ((__u64) arg) << 9);
return err;
We will add another ioctl in like this:
case ENBD_SET_SECTORS64:
do {
u64 longlongval;
if (get_user (longlongval, (__u64 *)arg))
return -EFAULT;
err = enbd_set_size (lo, longlongval);
return err;
} while(0);
return -EINVAL;
and add a new ioctl definition in enbd.h
#define ENBD_SET_SECTORS64 _IOWR(0xab, 0x30, __u64)
Then I think you can modify the setdevicesize() routine in
enbd-client.c as follows:
- unsigned sectors;
+ u64 sectors64;
...
- if (self->ioctl (self, BLKGETSIZE, (char *) §ors) >= 0
+ if (self->ioctl (self, BLKGETSIZE64, (char *) §ors64) >= 0
- && (int) sectors >= 0) {
+ && (s64) sectors64 >= 0) {
- if (size64 != ((u64) sectors) << 9) {
+ if (size64 != sectors64 << 9) {
PERR ("client (%d) Warning! kernel says size is %Lu != %Lu\n",
- self->i, (unsigned long long) sectors,
+ self->i, sectors64,
(unsigned long long) size64);
...
- sectors = size64 >> 9;
+ sectors64 = size64 >> 9;
// PTB rounding to multiple of 512
- size64 = ((u64) sectors) << 9;
+ size64 = sectors64 << 9;
- err = self->ioctl (self, ENBD_SET_SECTORS,
+ err = self->ioctl (self, ENBD_SET_SECTORS64,
- (char *) (unsigned long) sectors);
+ (char *) §ors64);
Let me know if that works or if anything else is required.
Peter
More information about the ENBD
mailing list