问题描述
我正在寻找一个明确的规范,以描述ioctl 0x1268(BLKSSZGET)的预期参数和行为.
I am looking for a definitive specification describing the expected arguments and behavior of ioctl 0x1268 (BLKSSZGET).
在许多地方都声明了这个数字(其中没有一个包含明确的参考源),例如linux/fs.h,但是我找不到它的规范.
This number is declared in many places (none of which contain a definitive reference source), such as linux/fs.h, but I can find no specification for it.
当然,过去某个时候有人决定0x1268可以获取设备的物理扇区大小,并在某处进行记录.这些信息从何而来?在哪里可以找到?
Surely, somebody at some point in the past decided that 0x1268 would get the physical sector size of a device and documented that somewhere. Where does this information come from and where can I find it?
我不是在问BLKSSZGET通常做什么,也不是在问它定义在哪个标头中.我正在寻找一个确定的,标准化的源,该源说明应采用何种参数类型以及其行为应针对什么.任何实现它的驱动程序.
I am not asking what BLKSSZGET does in general, nor am I asking what header it is defined in. I am looking for a definitive, standardized source that states what argument types it should take and what its behavior should be for any driver that implements it.
具体来说,我问是因为util-linux 2.23(和2.24)中的中出现了 中的错误,其中扇区大小被查询到uint64_t,但是由于出现BLKSSZGET 期望使用32位整数,因此未触及高32位,这会导致错误的扇区大小,不正确的对齐方式计算以及应成功的blkdiscard失败.因此,在提交补丁之前,我必须绝对确定问题是blkdiscard应该使用32位整数,还是内核中的驱动程序实现应该使用64位整数.
Specifically, I am asking because there appears to be a bug in blkdiscard in util-linux 2.23 (and 2.24) where the sector size is queried in to a uint64_t, but the high 32-bits are untouched since BLKSSZGET appears to expect a 32-bit integer, and this leads to an incorrect sector size, incorrect alignment calculations, and failures in blkdiscard when it should succeed. So before I submit a patch, I need to determine, with absolute certainty, if the problem is that blkdiscard should be using a 32-bit integer, or if the driver implementation in my kernel should be using a 64-bit integer.
由于我们在讨论主题,因此建议的补丁假定blkdiscard不正确为:
Edit 2: Since we're on the topic, the proposed patch presuming blkdiscard is incorrect is:
--- sys-utils/blkdiscard.c-2.23 2013-11-01 18:28:19.270004947 -0400 +++ sys-utils/blkdiscard.c 2013-11-01 18:29:07.334002382 -0400 @@ -71,7 +71,8 @@ { char *path; int c, fd, verbose = 0, secure = 0; - uint64_t end, blksize, secsize, range[2]; + uint64_t end, blksize, range[2]; + uint32_t secsize; struct stat sb; static const struct option longopts[] = { @@ -146,8 +147,8 @@ err(EXIT_FAILURE, _("%s: BLKSSZGET ioctl failed"), path); /* align range to the sector size */ - range[0] = (range[0] + secsize - 1) & ~(secsize - 1); - range[1] &= ~(secsize - 1); + range[0] = (range[0] + (uint64_t)secsize - 1) & ~((uint64_t)secsize - 1); + range[1] &= ~((uint64_t)secsize - 1); /* is the range end behind the end of the device ?*/ end = range[0] + range[1];
应用于 https://www.kernel.org/pub/linux/utils/util-linux/v2.23/.
推荐答案
在何处指定此答案?"的答案确实是内核的来源.
The answer to "where is this specified?" does seem to be the kernel source.
我在这里的内核邮件列表中问了这个问题: https://lkml.org /lkml/2013/11/1/620
I asked the question on the kernel mailing list here: https://lkml.org/lkml/2013/11/1/620
Theodore Ts'o作为回应,写(注意:他误认了sys-utils/blkdiscard.c在他的列表中,但这无关紧要):
In response, Theodore Ts'o wrote (note: he mistakenly identified sys-utils/blkdiscard.c in his list but it's inconsequential):
BLKSSZGET returns an int. If you look at the sources of util-linux v2.23, you'll see it passes an int to BLKSSZGET in sys-utils/blkdiscard.c lib/blkdev.c E2fsprogs also expects BLKSSZGET to return an int, and if you look at the kernel sources, it very clearly returns an int. The one place it doesn't is in sys-utils/blkdiscard.c, where as you have noted, it is passing in a uint64 to BLKSSZGET. This looks like it's a bug in sys-util/blkdiscard.c.
然后,他继续在util-linux上向blkdiscard提交补丁¹
He then went on to submit a patch¹ to blkdiscard at util-linux:
--- a/sys-utils/blkdiscard.c +++ b/sys-utils/blkdiscard.c @@ -70,8 +70,8 @@ static void __attribute__((__noreturn__)) usage(FILE *out) int main(int argc, char **argv) { char *path; - int c, fd, verbose = 0, secure = 0; - uint64_t end, blksize, secsize, range[2]; + int c, fd, verbose = 0, secure = 0, secsize; + uint64_t end, blksize, range[2]; struct stat sb; static const struct option longopts[] = {
我一直很犹豫在我的邮件列表帖子和这个SO问题的原始版本中都提到blkdiscard工具,原因是这样的:我知道内核源代码中的内容,修改blkdiscard以使其与来源,这最终分散了人们对此文件记录在哪里?"这个真实问题的关注.
I had been hesitant to mention the blkdiscard tool in both my mailing list post and the original version of this SO question specifically for this reason: I know what's in my kernel's source, it's already easy enough to modify blkdiscard to agree with the source, and this ended up distracting from the real question of "where is this documented?".
因此,就细节而言,比我更正式的人也表示,BLKSSZGET ioctl具有int功能,但有关文档的一般问题仍然存在.然后,我跟进 https://lkml.org/lkml/2013/11/3/125 ,并收到西奥多·特索(Theodore Ts'o)的另一封答复(出于信誉, wiki )回答问题.他写:
So, as for the specifics, somebody more official than me has also stated that the BLKSSZGET ioctl takes an int, but the general question regarding documentation remained. I then followed up with https://lkml.org/lkml/2013/11/3/125 and received another reply from Theodore Ts'o (wiki for credibility) answering the question. He wrote:
> There was a bigger question hidden behind the context there that I'm > still wondering about: Are these ioctl interfaces specified and > documented somewhere? From what I've seen, and from your response, the > implication is that the kernel source *is* the specification, and not > document exists that the kernel is expected to comply with; is this > the case? The kernel source is the specification. Some of these ioctl are documented as part of the linux man pages, for which the project home page is here: https://www.kernel.org/doc/man-pages/ However, these document existing practice; if there is a discrepancy between what is in the kernel has implemented and the Linux man pages, it is the Linux man pages which are buggy and which will be changed. That is man pages are descriptive, not perscriptive.
我还询问了公共内核API通常使用"int"的情况,他的响应在那里,尽管这里没有话题.
I also asked about the use of "int" in general for public kernel APIs, his response is there although that is off-topic here.
答案:因此,您已经有了答案,最后的答案是:ioctl接口由内核源本身指定;没有内核遵循的文档.有文档描述了内核对各种ioctl的实现,但是如果存在不匹配,则说明文档中存在错误,而不是内核中存在错误.
Answer: So, there you have it, the final answer is: The ioctl interfaces are specified by the kernel source itself; there is no document that the kernel adheres to. There is documentation to describe the kernel's implementations of various ioctls, but if there is a mismatch, it is an error in the documentation, not in the kernel.
¹考虑到以上所有情况,我想指出的是,与我的相比,Theodore Ts'o提交的补丁中的一个重要区别是使用了"int"而不是"uint32_t"-根据内核来源,BLKSSZGET确实期望平台上的参数为"int"大小,而不是强制的32位值.
这篇关于ioctl参数(例如0x1268/BLKSSZGET)在哪里实际指定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!