Message ID | 20200906012716.1553-2-tom.ty89@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [RESEND,1/4] scsi: sg: fix BLKSECTGET ioctl | expand |
On Sun, Sep 06, 2020 at 09:27:14AM +0800, Tom Yan wrote: > Provide an ioctl to get the logical sector size so that the maximum > bytes per request can be derived. > > Follow-up of the BLKSECTGET fix. I don't think this has any business going in. /dev/sg is a generic interface that is not specific to block based command sets. Just issue your command set specific command to query the logical block size if you care about it.
Feel free to omit this. But then you will probably want to ditch BLKSECTGET as well, and then any usage of queue_max_sectors(), and maybe more/all queue_*(). I'm not really interested in discussing/arguing whether general/ideally-speaking it's appropriate/necessary to keep BLKSECTGET / add BLKSSZGET. The only reason I added this is that, when BLKSECTGET was introduced to sg long time ago, it was wrongly implemented to gives out the limit in bytes, so now when I'm fixing it, I'm merely making sure that whatever has been relying on the ioctl (e.g. qemu) will only need to do one more ioctl (instead of e.g. doing SCSI in its non-SCSI-specific part), if they want/need the limit in bytes. If they can be implemented more "generic"-ly, feel free to improve/extend them to make them "SG_*-qualified". Even if you can do SCSI from the userspace, or even should, I don't see any reason that we shouldn't provide an ioctl to do queue_logical_block_size() *while we provide one to do queue_max_sectors()*. On Mon, 7 Sep 2020 at 14:09, Christoph Hellwig <hch@lst.de> wrote: > > On Sun, Sep 06, 2020 at 09:27:14AM +0800, Tom Yan wrote: > > Provide an ioctl to get the logical sector size so that the maximum > > bytes per request can be derived. > > > > Follow-up of the BLKSECTGET fix. > > I don't think this has any business going in. /dev/sg is a generic > interface that is not specific to block based command sets. Just issue > your command set specific command to query the logical block size if > you care about it.
On Mon, Sep 07, 2020 at 05:01:34PM +0800, Tom Yan wrote: > Feel free to omit this. But then you will probably want to ditch > BLKSECTGET as well, and then any usage of queue_max_sectors(), and > maybe more/all queue_*(). > > I'm not really interested in discussing/arguing whether > general/ideally-speaking it's appropriate/necessary to keep BLKSECTGET > / add BLKSSZGET. The only reason I added this is that, when BLKSECTGET > was introduced to sg long time ago, it was wrongly implemented to > gives out the limit in bytes, so now when I'm fixing it, I'm merely > making sure that whatever has been relying on the ioctl (e.g. qemu) > will only need to do one more ioctl (instead of e.g. doing SCSI in its > non-SCSI-specific part), if they want/need the limit in bytes. If they > can be implemented more "generic"-ly, feel free to improve/extend them > to make them "SG_*-qualified". > > Even if you can do SCSI from the userspace, or even should, I don't > see any reason that we shouldn't provide an ioctl to do > queue_logical_block_size() *while we provide one to do > queue_max_sectors()*. Well, the different definition in bytes for sg actually makes sense to me, as a bytes based limit is what fundamentally makes sense for the passthrough interface. Only that it reuses the same cmd value is a bit confusing. So instead of changing anything and potentially breaking applications I'd suggest to just better document the semantics.
If we rename it to e.g. SG_GET_MAX_XFER_BYTES, it will still break applications unless we also keep the wrong/ugly/confusing name (and you lose the advantage/generality that the two ioctls can be used on both sg and "pure" block devices; which seems to be the case of some SG_* ioctls as well). I don't see what it has to do with passthrough. Either way, it's just a matter of whether you want to decouple it and make things more flexible. The only real disadvantage is, you will have to do two ioctls instead of one, but no more than that, and for good reasons. I don't really care enough though. I mean, I'm okay with SG_GET_MAX_XFER_BYTES *and* NO "improper" BLKSECTGET. If that will get the patch series in, I am willing to send a new version. If not, I'm just gonna drop this. On Tue, 8 Sep 2020 at 16:43, Christoph Hellwig <hch@lst.de> wrote: > > On Mon, Sep 07, 2020 at 05:01:34PM +0800, Tom Yan wrote: > > Feel free to omit this. But then you will probably want to ditch > > BLKSECTGET as well, and then any usage of queue_max_sectors(), and > > maybe more/all queue_*(). > > > > I'm not really interested in discussing/arguing whether > > general/ideally-speaking it's appropriate/necessary to keep BLKSECTGET > > / add BLKSSZGET. The only reason I added this is that, when BLKSECTGET > > was introduced to sg long time ago, it was wrongly implemented to > > gives out the limit in bytes, so now when I'm fixing it, I'm merely > > making sure that whatever has been relying on the ioctl (e.g. qemu) > > will only need to do one more ioctl (instead of e.g. doing SCSI in its > > non-SCSI-specific part), if they want/need the limit in bytes. If they > > can be implemented more "generic"-ly, feel free to improve/extend them > > to make them "SG_*-qualified". > > > > Even if you can do SCSI from the userspace, or even should, I don't > > see any reason that we shouldn't provide an ioctl to do > > queue_logical_block_size() *while we provide one to do > > queue_max_sectors()*. > > Well, the different definition in bytes for sg actually makes sense > to me, as a bytes based limit is what fundamentally makes sense for > the passthrough interface. Only that it reuses the same cmd value > is a bit confusing. So instead of changing anything and potentially > breaking applications I'd suggest to just better document the semantics.
On Thu, Sep 10, 2020 at 09:59:05AM +0800, Tom Yan wrote: > If we rename it to e.g. SG_GET_MAX_XFER_BYTES, it will still break > applications unless we also keep the wrong/ugly/confusing name (and > you lose the advantage/generality that the two ioctls can be used on > both sg and "pure" block devices; which seems to be the case of some > SG_* ioctls as well). How is that an advantage? Applications that works with block devices don't really work with a magic passthrough character device. > I don't really care enough though. I mean, I'm okay with > SG_GET_MAX_XFER_BYTES *and* NO "improper" BLKSECTGET. If that will get > the patch series in, I am willing to send a new version. If not, I'm > just gonna drop this. You must assume that there are applications already that depend in the "weird" BLKSECTGET on sg, given that it has been around so long. Any change to the semantics will break them.
On Thu, 10 Sep 2020 at 13:28, Christoph Hellwig <hch@lst.de> wrote: > > On Thu, Sep 10, 2020 at 09:59:05AM +0800, Tom Yan wrote: > > If we rename it to e.g. SG_GET_MAX_XFER_BYTES, it will still break > > applications unless we also keep the wrong/ugly/confusing name (and > > you lose the advantage/generality that the two ioctls can be used on > > both sg and "pure" block devices; which seems to be the case of some > > SG_* ioctls as well). > > How is that an advantage? Applications that works with block devices > don't really work with a magic passthrough character device. You must assume that there are applications already assuming that work. (And it will, at least in some cases, if this series get merged.) And you have not been giving me a solid point anyway, as I said, it's just queue_*() at the end of the day; regardless of whether those would work in all sg cases, we have been using them in the sg driver anyway. And it's not like we have to guarantee that (the) ioctls can work in every case anyway, right? (Especially when they aren't named SG_*). I mean, what's even your point? How do you propose we fix this? Should we just leave it broken/wrong/rotten as-is (including the case that you don't consider it being so)? If that's what you are trying to say then please just say it, I'll just walk away quietly. I'm really kind of done with this sort of looping that leads to nowhere. > > > I don't really care enough though. I mean, I'm okay with > > SG_GET_MAX_XFER_BYTES *and* NO "improper" BLKSECTGET. If that will get > > the patch series in, I am willing to send a new version. If not, I'm > > just gonna drop this. > > You must assume that there are applications already that depend in the > "weird" BLKSECTGET on sg, given that it has been around so long. Any > change to the semantics will break them. While you forgot to assume that there are applications assuming BLKSECTGET is as "weird" in the block layer at the same time. (That's exactly what has happened in qemu.) You don't get the slightest advantage in "trying not to break things" by doing the wrong thing. It only goes on making more things broken.
On Fri, Sep 11, 2020 at 10:52:19AM +0800, Tom Yan wrote: > > How is that an advantage? Applications that works with block devices > > don't really work with a magic passthrough character device. > > You must assume that there are applications already assuming that > work. (And it will, at least in some cases, if this series get > merged.) Why "must" I assume that? > And you have not been giving me a solid point anyway, as I said, it's > just queue_*() at the end of the day; regardless of whether those > would work in all sg cases, we have been using them in the sg driver > anyway. > > And it's not like we have to guarantee that (the) ioctls can work in > every case anyway, right? (Especially when they aren't named SG_*). No. While it is unfortunte we have all kinds of cases of ioctls working differnetly on different devices. > > I mean, what's even your point? How do you propose we fix this? I propose to not "fix" anything, because nothing is broken except for maybe a lack of documentation.
On 2020-09-11 2:48 a.m., Christoph Hellwig wrote: > On Fri, Sep 11, 2020 at 10:52:19AM +0800, Tom Yan wrote: >>> How is that an advantage? Applications that works with block devices >>> don't really work with a magic passthrough character device. >> >> You must assume that there are applications already assuming that >> work. (And it will, at least in some cases, if this series get >> merged.) > > Why "must" I assume that? > >> And you have not been giving me a solid point anyway, as I said, it's >> just queue_*() at the end of the day; regardless of whether those >> would work in all sg cases, we have been using them in the sg driver >> anyway. >> >> And it's not like we have to guarantee that (the) ioctls can work in >> every case anyway, right? (Especially when they aren't named SG_*). > > No. While it is unfortunte we have all kinds of cases of ioctls working > differnetly on different devices. > >> >> I mean, what's even your point? How do you propose we fix this? > > I propose to not "fix" anything, because nothing is broken except for > maybe a lack of documentation. Alan Stern are you reading this thread? Why do I ask, you may ask? Because 'git blame' fingers you: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv commit 44ec95425c1d9dce6e4638c29e4362cfb44814e7 Author: Alan Stern <stern@rowland.harvard.edu> Date: Tue Feb 20 11:01:57 2007 -0500 [SCSI] sg: cap reserved_size values at max_sectors This patch (as857) modifies the SG_GET_RESERVED_SIZE and SG_SET_RESERVED_SIZE ioctls in the sg driver, capping the values at the device's request_queue's max_sectors value. This will permit cdrecord to obtain a legal value for the maximum transfer length, fixing Bugzilla #7026. The patch also caps the initial reserved_size value. There's no reason to have a reserved buffer larger than max_sectors, since it would be impossible to use the extra space. The corresponding ioctls in the block layer are modified similarly, and the initial value for the reserved_size is set as large as possible. This will effectively make it default to max_sectors. Note that the actual value is meaningless anyway, since block devices don't have a reserved buffer. Finally, the BLKSECTGET ioctl is added to sg, so that there will be a uniform way for users to determine the actual max_sectors value for any raw SCSI transport. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Jens Axboe <jens.axboe@oracle.com> Acked-by: Douglas Gilbert <dougg@torque.net> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Oops, I ack-ed this patch from 2007:-) Anyway it would seem BLKSECTGET ioctl was meant to be a "uniform way to determine the actual max_sectors value for any raw SCSI transport." Given that the initial implementation of BLKSECTGET now seems to be at odds with other implementations, what should we do? It is possible that it was correct on 2007 and the BLKSECTGET ioctl has changed elsewhere but failed to fix the sg driver's implementation. If I get a vote then it would be for Tom Yan's approach: reduce entropy or it will overwhelm us :-) So Christoph, it IS documented, both in the above commit message and: https://doug-gilbert.github.io/sg_v40.html in Table 8. So please stop with your "maybe a lack of documentation" line. Doug Gilbert
On Fri, Sep 11, 2020 at 01:52:07PM -0400, Douglas Gilbert wrote: > On 2020-09-11 2:48 a.m., Christoph Hellwig wrote: > > On Fri, Sep 11, 2020 at 10:52:19AM +0800, Tom Yan wrote: > > > > How is that an advantage? Applications that works with block devices > > > > don't really work with a magic passthrough character device. > > > > > > You must assume that there are applications already assuming that > > > work. (And it will, at least in some cases, if this series get > > > merged.) > > > > Why "must" I assume that? > > > > > And you have not been giving me a solid point anyway, as I said, it's > > > just queue_*() at the end of the day; regardless of whether those > > > would work in all sg cases, we have been using them in the sg driver > > > anyway. > > > > > > And it's not like we have to guarantee that (the) ioctls can work in > > > every case anyway, right? (Especially when they aren't named SG_*). > > > > No. While it is unfortunte we have all kinds of cases of ioctls working > > differnetly on different devices. > > > > > > > > I mean, what's even your point? How do you propose we fix this? > > > > I propose to not "fix" anything, because nothing is broken except for > > maybe a lack of documentation. > > Alan Stern are you reading this thread? Why do I ask, you may ask? > Because 'git blame' fingers you: > > vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv > > commit 44ec95425c1d9dce6e4638c29e4362cfb44814e7 > Author: Alan Stern <stern@rowland.harvard.edu> > Date: Tue Feb 20 11:01:57 2007 -0500 > > [SCSI] sg: cap reserved_size values at max_sectors > > This patch (as857) modifies the SG_GET_RESERVED_SIZE and > SG_SET_RESERVED_SIZE ioctls in the sg driver, capping the values at > the device's request_queue's max_sectors value. This will permit > cdrecord to obtain a legal value for the maximum transfer length, > fixing Bugzilla #7026. > > The patch also caps the initial reserved_size value. There's no > reason to have a reserved buffer larger than max_sectors, since it > would be impossible to use the extra space. > > The corresponding ioctls in the block layer are modified similarly, > and the initial value for the reserved_size is set as large as > possible. This will effectively make it default to max_sectors. > Note that the actual value is meaningless anyway, since block devices > don't have a reserved buffer. > > Finally, the BLKSECTGET ioctl is added to sg, so that there will be a > uniform way for users to determine the actual max_sectors value for > any raw SCSI transport. > > Signed-off-by: Alan Stern <stern@rowland.harvard.edu> > Acked-by: Jens Axboe <jens.axboe@oracle.com> > Acked-by: Douglas Gilbert <dougg@torque.net> > Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > Oops, I ack-ed this patch from 2007:-) The Bugzilla entry it talks about is from 2006! > Anyway it would seem BLKSECTGET ioctl > was meant to be a "uniform way to determine the actual max_sectors value for > any raw SCSI transport." Right. The question at hand was: Given an open file descriptor for an SG device, how can a program determine the largest amount it can send in a single transfer? This ioctl seemed to be the best answer. See comment #26 (https://bugzilla.kernel.org/show_bug.cgi?id=7026#c26) and following for the viewpoint of the notoriously prickly author of cdrecord. > Given that the initial implementation of BLKSECTGET > now seems to be at odds with other implementations, what should we do? > > It is possible that it was correct on 2007 and the BLKSECTGET ioctl has > changed elsewhere but failed to fix the sg driver's implementation. Could be. Also, I'm not sure how careful people were back then to distinguish between logical and physical sector sizes. > If I get a vote then it would be for Tom Yan's approach: reduce entropy or > it will overwhelm us :-) > > > So Christoph, it IS documented, both in the above commit message and: > https://doug-gilbert.github.io/sg_v40.html > > in Table 8. So please stop with your "maybe a lack of documentation" line. My vote is not to change an interface which a program like cdrecord may currently rely on. I can understand Christoph's point about documentation. It would be good to have something in the actual kernel source, rather than in the history or somebody's github files. Alan Stern
On Fri, 11 Sep 2020 at 14:48, Christoph Hellwig <hch@lst.de> wrote: > > On Fri, Sep 11, 2020 at 10:52:19AM +0800, Tom Yan wrote: > > > How is that an advantage? Applications that works with block devices > > > don't really work with a magic passthrough character device. > > > > You must assume that there are applications already assuming that > > work. (And it will, at least in some cases, if this series get > > merged.) > > Why "must" I assume that? Because of the name. The whole discussion was about the name. (Well, also because 'I must assume that some applications has already been "relying" on the wrong name.') > > > And you have not been giving me a solid point anyway, as I said, it's > > just queue_*() at the end of the day; regardless of whether those > > would work in all sg cases, we have been using them in the sg driver > > anyway. > > > > And it's not like we have to guarantee that (the) ioctls can work in > > every case anyway, right? (Especially when they aren't named SG_*). > > No. While it is unfortunte we have all kinds of cases of ioctls working > differnetly on different devices. > > > > > I mean, what's even your point? How do you propose we fix this? > > I propose to not "fix" anything, because nothing is broken except for > maybe a lack of documentation. It won't really help anyway. Documenting something wrong won't make it correct anyway. It's just wrong, semantically wrong, logically wrong; expecting people to "rtfm and realize the difference" only makes it even more wrong. End of story. This was never about whether it is "broken" or whether we should provide means to fetch the limit in the number of bytes or sectors. It was always just about the name. Just one last question. So should we not even replace the bit shift with queue_logicial_block_size() in max_sectors_bytes()? Given that we "must assume that it has been that way for long enough so applications must have been dealing with the flaw on their own already and fixing it will only breaks them"?
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index e57831910228..0e3f084141a3 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1118,6 +1118,8 @@ sg_ioctl_common(struct file *filp, Sg_device *sdp, Sg_fd *sfp, max_sectors = min_t(unsigned int, USHRT_MAX, queue_max_sectors(sdp->device->request_queue)); return put_user(max_sectors, ip); + case BLKSSZGET: + return put_user(queue_logical_block_size(sdp->device->request_queue), ip); case BLKTRACESETUP: return blk_trace_setup(sdp->device->request_queue, sdp->disk->disk_name,
Provide an ioctl to get the logical sector size so that the maximum bytes per request can be derived. Follow-up of the BLKSECTGET fix. Signed-off-by: Tom Yan <tom.ty89@gmail.com> --- drivers/scsi/sg.c | 2 ++ 1 file changed, 2 insertions(+)