11

期待される引数と ioctl 0x1268 (BLKSSZGET) の動作を説明する最終的な仕様を探しています。

この番号は、 などの多くの場所で宣言されています (決定的な参照元を含む場所はありません) が、そのlinux/fs.h仕様を見つけることができません。

確かに、過去のある時点で、誰かが 0x1268 でデバイスの物理セクター サイズを取得できると判断し、それをどこかに文書化しました。この情報はどこから来て、どこで見つけることができますか?

編集: BLKSSZGET が一般的に何をするかを尋ねているわけでも、それが定義されているヘッダーを尋ねているわけでもありません。どのような引数の型をとるべきか、どのようなドライバーに対してどのような動作をすべきかを述べた、決定的で標準化されたソースを探しています。実装します。

具体的には、util-linux 2.23 (および 2.24) にバグがあり、セクター サイズが にクエリされているように見えるので質問していますが、BLKSSZGETは 32 ビット整数を期待しているように見えるため、上位 32 ビットは変更されていません。 、そしてこれは、不正確なセクターサイズ、不正確なアライメント計算、および成功するはずの失敗につながります。そのため、パッチを送信する前に、問題が32 ビット整数を使用する必要があるのか​​、それともカーネルのドライバー実装が 64 ビット整数を使用する必要があるのか​​を、確実に判断する必要があります。blkdiscarduint64_tblkdiscardblkdiscard

編集 2: 話題になっているので、提案されたパッチが間違っていると推定するblkdiscardのは次のとおりです。

--- 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/に適用されます。

4

1 に答える 1

12

「これはどこに指定されていますか?」に対する答え。カーネルソースのようです。

ここのカーネル メーリング リストで質問しました: https://lkml.org/lkml/2013/11/1/620

それに応じて、Theodore Ts'oは次のように書いています (注: 彼はリストで sys-utils/blkdiscard.c を誤って識別しましたが、重要ではありません)。

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 にパッチ¹ を提出しました。

--- 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 を変更するのは簡単です。これは、「これはどこに文書化されていますか?」という本当の問題から気をそらしてしまいました。

したがって、詳細については、私よりも公式な誰かが BLKSSZGET ioctl が int を取ると述べていますが、ドキュメントに関する一般的な質問は残っていました。その後、 https://lkml.org/lkml/2013/11/3/125でフォローアップし、Theodore Ts'o (信頼性のためのwiki ) から質問に答える別の返信を受け取りました。彼は書いた

> 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" の使用についても尋ねました。ここではトピック外ですが、彼の回答があります。

回答:これで、最終的な回答は次のようになります。ioctl インターフェイスは、カーネル ソース自体によって指定されます。カーネルが準拠しているドキュメントはありません。さまざまな ioctl のカーネルの実装を説明するドキュメントがありますが、不一致がある場合、それはカーネルではなくドキュメントのエラーです。

¹ 上記のすべてを念頭に置いて、Theodore Ts'o が提出したパッチの重要な違いは、私のものと比較して、「uint32_t」ではなく「int」を使用していることを指摘したいと思います -- カーネル ソースによると BLKSSZGET 、実際には、強制的な 32 ビット値ではなく、プラットフォーム上の "int" のサイズに関係なく引数が必要です。

于 2013-11-03T17:56:56.507 に答える