Bug 191251

Summary: nbd can't use devices with 2^31 or more blocks
Product: Drivers Reporter: Felix J. Ogris (fjo-linux)
Component: OtherAssignee: drivers_other
Status: NEW ---    
Severity: normal    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.8.0 4.8.14 4.9 Tree: Mainline
Regression: No

Description Felix J. Ogris 2016-12-27 14:46:44 UTC
Symptom:
nbd can't use devices with 2^31 or more blocks, read: 2, 4, or 8 TB if using a blocksize of 1024, 2048, or 4096 bytes, respectively.

How to trigger:
# cd /tmp/
# truncate -s 2T foobar.img
# ls -la foobar.img 
-rw-r--r-- 1 root root 2199023255552 Dec 27 15:27 foobar.img
# nbd-server -d 12345 /tmp/foobar.img
(...another terminal...)
# nbd-client -b 1024 localhost 12345 /dev/nbd0
Warning: the oldstyle protocol is no longer supported.
This method now uses the newstyle protocol with a default export
Negotiation: ..size = 2097152MB
bs=1024, sz=2199023255552 bytes
# cat /sys/block/nbd0/size 
18446744069414584320

strace of ioctl()s called by nbd-client looks ok:

ioctl(4, NBD_SET_BLKSIZE, 0x400)        = 0
ioctl(4, NBD_SET_SIZE_BLOCKS, 0x80000000) = 0
write(2, "bs=1024, sz=2199023255552 bytes\n", 32bs=1024, sz=2199023255552 bytes
) = 32
ioctl(4, NBD_CLEAR_SOCK, 0x20)          = 0
ioctl(4, NBD_SET_FLAGS, 0x141)          = 0
ioctl(4, BLKROSET, [0])                 = 0
ioctl(4, NBD_SET_SOCK, 0x5)             = 0

How to fix:
4th parameter nr_blocks to nbd_size_set() in drivers/block/nbd.c should be a 64 bit type, e.g. a loff_t, and not a 32 bit signed integer as it currently is.

BR,
Felix