2013-11-01 19 views
7

Sto cercando una specifica definitiva che descriva gli argomenti e il comportamento previsti di ioctl 0x1268 (BLKSSZGET).Dove sono effettivamente specificati i parametri ioctl (come 0x1268/BLKSSZGET)?

Questo numero è dichiarato in molti luoghi (nessuno dei quali contiene una fonte di riferimento definitiva), come ad esempio linux/fs.h, ma non riesco a trovare alcuna specifica per questo.

Sicuramente, qualcuno a un certo punto nel passato ha deciso che 0x1268 avrebbe ottenuto la dimensione del settore fisico di un dispositivo e l'avrebbe documentata da qualche parte. Da dove proviene questa informazione e dove posso trovarla?

Modifica: non sto chiedendo cosa BLKSSZGET fa in generale, né sto chiedendo in quale intestazione è definito. Sto cercando una fonte definitiva e standardizzata che indichi quali tipi di argomenti dovrebbe prendere e quale dovrebbe essere il suo comportamento per qualsiasi driver che lo implementa.

In particolare, chiedo perché ci sembra tratta di un problema in blkdiscard in util-linux 2.23 (e 2.24) dove la dimensione del settore viene interrogato in un uint64_t, ma le alte 32 bit sono intatti dal BLKSSZGET appare in attesa di un numero intero a 32 bit e ciò porta a una dimensione del settore errata, a calcoli di allineamento errati e a errori in blkdiscard quando deve riuscire. Quindi, prima di inviare una patch, ho bisogno di determinare, con assoluta certezza, se il problema è che blkdiscard dovrebbe usare un numero intero a 32 bit, o se l'implementazione del driver nel mio kernel dovrebbe usare un numero intero a 64-bit.

Edit 2: Dal momento che siamo in tema, la patch proposto presumendo blkdiscard non è corretto è:

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

applicata a esempio https://www.kernel.org/pub/linux/utils/util-linux/v2.23/.

+0

Grazie, ma so già cosa fa BLKSSZGET. Sto cercando una specifica definitiva del suo comportamento. In particolare, ci vuole un puntatore a un numero intero a 32 o 64 bit come parametro e, cosa più importante, * come fai a sapere *? –

+0

Abbastanza corretto, ne so 0, pensavo che potesse essere d'aiuto; continuerà a scavare. – slm

+0

Dato che alcuni probabilmente sanno di questo, potresti elaborare il tuo Q aggiungendo un po 'di contesto? – slm

risposta

7

La risposta a "dove è specificato?" sembra essere la fonte del kernel.

ho posto la domanda sulla mailing list del kernel qui: https://lkml.org/lkml/2013/11/1/620

In risposta, Theodore Ts'o wrote (nota: ha erroneamente identificato sys-utils/blkdiscard.c nella sua lista, ma è irrilevante):

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. 

Ha poi continuato a presentare una patch¹ a 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[] = { 

avevo esitato a me ntion lo strumento blkdiscard sia nel mio post sulla mailing list sia nella versione originale di questa domanda SO specificatamente per questo motivo: so cosa c'è nel sorgente del mio kernel, è già abbastanza facile modificare blkdiscard per essere d'accordo con la fonte, e questo ha finito per distogliere la vera domanda di "dove è documentato?".

Quindi, come per le specifiche, qualcuno più ufficiale di me ha anche dichiarato che l'ioctl di BLKSSZGET accetta un int, ma la domanda generale riguardante la documentazione è rimasta. Ho quindi risposto con https://lkml.org/lkml/2013/11/3/125 e ho ricevuto un'altra risposta da Theodore Ts'o (wiki per la credibilità) rispondendo alla domanda.Egli 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. 

Ho anche chiesto circa l'uso di "int" in generale per le API del kernel pubblici, his response is there anche se questo è off-topic qui.

Risposta: Quindi, ecco, la risposta finale è: Le interfacce ioctl sono specificate dalla fonte del kernel stesso; non esiste alcun documento a cui il kernel aderisce. C'è una documentazione per descrivere le implementazioni del kernel di vari ioctls, ma se c'è una mancata corrispondenza, è un errore nella documentazione, non nel kernel.

¹ Con tutto ciò che precede in mente, voglio sottolineare che un'importante differenza nella patch che Theodore Ts'o ha presentato, rispetto alla mia, è l'uso di "int" piuttosto che "uint32_t" - BLKSSZGET , come da origine del kernel, si aspetta effettivamente un argomento che sia la dimensione "int" sulla piattaforma, non un valore forzato a 32 bit.

Problemi correlati