Maybe you want to add some condition for this: https://github.com/qemu/qemu/blob/v5.1.0/nbd/server.c#L659 Or not clamp it at all.
On Sun, 6 Sep 2020 at 18:58, Tom Yan <tom.t...@gmail.com> wrote: > > In commit 867eccfed84f96b54f4a432c510a02c2ce03b430, Levitsky appears > to have assumed that the only "SCSI Passthrough" is `-device > scsi-generic`, while the fact is there's also `-device scsi-block` > (passthrough without the sg driver). Unlike `-device scsi-hd`, getting > max_sectors is necessary to it (more precisely, hw_max_sectors might > what matters, but BLKSECTGET reports max_sectors, so). > > I'm unsure about how qemu-nbd works, but the commit clearly wasn't the > right approach to fix the original issue it addresses. (It should for > example ignore the max_transfer if it will never matter in to it, or > overrides it in certain cases; when I glimpsed over > https://bugzilla.redhat.com/show_bug.cgi?id=1647104, I don't see how > it could be file-posix problem when it is reporting the right thing, > regardless of whether "removing" the code helps.) > > I don't think we want to "mark" `-device scsi-block` as sg either. It > will probably bring even more unexpected problems, because they are > literally different sets of things behind the scene / in the kernel. > > On Fri, 4 Sep 2020 at 10:09, Tom Yan <tom.t...@gmail.com> wrote: > > > > sg devices have different major/minor than their corresponding > > block devices. Using sysfs to get max segments never really worked > > for them. > > > > Fortunately the sg driver provides an ioctl to get sg_tablesize, > > which is apparently equivalent to max segments. > > > > Signed-off-by: Tom Yan <tom.t...@gmail.com> > > --- > > block/file-posix.c | 17 ++++++++++++++++- > > 1 file changed, 16 insertions(+), 1 deletion(-) > > > > diff --git a/block/file-posix.c b/block/file-posix.c > > index 411a23cf99..9e37594145 100644 > > --- a/block/file-posix.c > > +++ b/block/file-posix.c > > @@ -1178,6 +1178,21 @@ static int sg_get_max_transfer_length(int fd) > > #endif > > } > > > > +static int sg_get_max_segments(int fd) > > +{ > > +#ifdef SG_GET_SG_TABLESIZE > > + long max_segments = 0; > > + > > + if (ioctl(fd, SG_GET_SG_TABLESIZE, &max_segments) == 0) { > > + return max_segments; > > + } else { > > + return -errno; > > + } > > +#else > > + return -ENOSYS; > > +#endif > > +} > > + > > static int get_max_transfer_length(int fd) > > { > > #if defined(BLKSECTGET) && defined(BLKSSZGET) > > @@ -1268,7 +1283,7 @@ static void hdev_refresh_limits(BlockDriverState *bs, > > Error **errp) > > bs->bl.max_transfer = pow2floor(ret); > > } > > > > - ret = get_max_segments(s->fd); > > + ret = bs->sg ? sg_get_max_segments(s->fd) : get_max_segments(s->fd); > > if (ret > 0) { > > bs->bl.max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, > > ret * qemu_real_host_page_size); > > -- > > 2.28.0 > >