Hi Eric,
On Tue, May 07, 2024 at 07:02:56AM -0500, Eric Blake wrote:
On Wed, Feb 21, 2024 at 12:26:08PM -0600, Eric Blake wrote:
> On Wed, Feb 21, 2024 at 12:19:49PM -0600, Eric Blake wrote:
> > setupexport()
> > - default to client->server->expected_size (if one was provided),
> > further validating that actual size is large enough when actual size
> > can be computed
> > - if neither treefile or F_WAIT is set, compute actual size by opening
> > one or more files and using size_autodetect() (which does the right
> > thing for block devices, so my earlier thought about over-reliance
> > on stat() was wrong)
> >
> > but these functions are only reached for NBD_OPT_EXPORT_NAME and
> > NBD_OPT_GO, not NBD_OPT_INFO. The upshot is that for NBD_OPT_GO,
> > there are some scenarios (treefile, F_WAIT) where nbd-server
> > advertises a size of 9223372036854775807 (0x7fffffff_ffffffff) meaning
> > unknown, but a size of 0 there is only possible if the file was
> > successfully opened and really is zero bytes in length. Conversely,
> > NBD_OPT_INFO is always advertising a size of 0, which means most of
> > the time, the size changes between NBD_OPT_INFO and NBD_OPT_GO.
>
> Amending myself: reading size_autodetect(), it tries ioctl(fd,
> BLKGETSIZE64) first (even when fd is not a block device!), then falls
> back to fstat(fd) coupled with lseek(SEEK_END) if fstat() reported
> st_size of 0 and not a regular file; but if all of those fail, it
> reports UINT64_MAX, which is different than OFFT_MAX.
Another wrinkle:
On BSD systems, lseek(fd_of_block, 0, SEEK_END) behaves identically to
lseek(fd_of_block, 0, SEEK_START), because BSD has the idea that the
size of a seekable file descriptor is whatever gets reported in
stat().st_size which is 0 on block devices (Linux is the odd system
out where lseek() and stat() disagree on this point - all other
systems surveyed either reliably report the block capacity in st_size
and SEEK_END, or use offset 0 in both places). See this POSIX bug for
more details:
https://austingroupbugs.net/view.php?id=1817
Sigh :-/
If we are going to report correct capacity of block devices, it
requires a LOT more code; compare what nbdkit is adding:
https://gitlab.com/nbdkit/nbdkit/-/merge_requests/54/diffs?commit_id=532b...
Yeah.
In this context, I've never done much on non-Linux systems. We do indeed
try stat and lseek, but I didn't realize that was not portable. We also
use the BLKGETSIZE64 ioctl to figure out the size of a block device,
but that's *definitely* Linux-specific.
I'm definitely OK with improving that situation if we can make it
happen...
--
w(a)uter.{be,co.za}
wouter(a){grep.be,fosdem.org,debian.org}
I will have a Tin-Actinium-Potassium mixture, thanks.