Where do the ioctl parameters actually appear (e.g. 0x1268 / BLKSSZGET)?

I am looking for the final specification describing the expected arguments and behavior of ioctl 0x1268 (BLKSSZGET).

This number is declared in many places (none of which contain a specific link source), for example linux/fs.h , but I can not find any specifications for it.

Of course, at some point in the past, someone decided that 0x1268 would get the size of the physical sector of the device and document it somewhere. Where does this information come from and where can I find it?

Edit: I do not ask what BLKSSZGET does at all, and I do not ask what heading it is defined in. I am looking for a final, standardized source that indicates what types of arguments it should accept and what its behavior is for any driver that implements it.

In particular, I ask because there is an blkdiscard in blkdiscard in util-linux 2.23 (and 2.24) in which the sector size is requested in uint64_t , but high 32-bits are untouched, since it seems that BLKSSZGET expects a 32-bit integer, resulting in incorrect sector size, incorrect alignment calculations, and blkdiscard failures when it blkdiscard . Therefore, before I post the patch, I need to determine with absolute certainty whether there is a problem that blkdiscard should use a 32-bit integer, or if a 64-bit integer should be used in the kernel implementation in my kernel.

Edit 2: Since we're on topic, the alleged patch assuming blkdiscard is incorrect:

 --- 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]; 

Used, for example, https://www.kernel.org/pub/linux/utils/util-linux/v2.23/ .

+7
standards linux kernel specifications ioctl
source share
1 answer

The answer to the question "Where is this indicated?" seems to be the source of the kernel.

I asked a question about the kernel mailing list here: https://lkml.org/lkml/2013/11/1/620

In response, Theodor Tso wrote (note: he mistakenly identified sys-utils / blkdiscard.c in his list, but this is not significant)

 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 a bug in sys-util/blkdiscard.c. 

Then he sent the patch¹ to blkdiscard in 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[] = { 

I did not dare to mention the blkdiscard tool both in my mailing list and in the original version of this SO question precisely for this reason: I know that in my kernel source code it is already easy enough to modify blkdiscard to agree with the source, and this ultimately distracted from the real question of “where is this documented?”.

So, with regard to specifics, someone more official than me also stated that BLKSSZGET ioctl is int, but the general question regarding documentation remains. Then I looked through https://lkml.org/lkml/2013/11/3/125 and got another answer from Theodor Tso ( wiki for credibility), answering a 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. 

I also asked about using "int" in general for the open kernel API, its answer is , although it is off topic here.

Answer: So here it is, the final answer: ioctl interfaces are indicated by the kernel source itself; there is no document to which the kernel is attached. There is documentation to describe the kernel implementations of various ioctls, but if there is a mismatch, this is a mistake in the documentation, not in the kernel.

¹ Given all of the above, I want to note that the important difference in the Theodor Tso patch, presented, compared to mine, is the use of "int" and not "uint32_t" - BLKSSZGET, in accordance with the kernel source code, does expect an argument that represents any size of "int" on the platform, and not a forced 32-bit value.

+7
source share

All Articles