1

関連する構造は次のようになります。struct node {int a; int b; }

struct ioctl_node {
    struct node **ptr;
    int         count; //Stores the no of pointers this ptr is pointing to.
};

ユーザースペースでは、ioctl_nodeの構造に。を入力しましたcount = 3。そしてptr[0]ptr[2]はノード型の2つの構造体を指していますが、ptr[1]NULLです。これをカーネルに渡してほしい。この情報をユーザースペースからカーネルスペースに渡すためにioctl呼び出しを発行しました。

私はカーネル空間で次のことをしました。

struct ioctl_node k_node;

copy_from_user(&k_node, arg, sizeof(struct ioctl_node)) //arg is the source

//k_node.count is showing the right value what I have set in the user space.

struct node *tmp = NULL;

それから私はそうしました、copy_from_user(&tmp, k_node.ptr, sizeof(struct node *)そしてこの呼びかけも成功を返しています。**ptrしかし、カーネル空間にコンテンツ全体を適切にコピーするのに苦労しています。誰か助けてください、どうすればそれができますか?次のcopy_from_userを実行して、すべてのコンテンツをコピーするにはどうすればよいですか。試しましたが、コピーエラーが発生しました。

4

1 に答える 1

1

copy_from_user連続するバイトの1ブロックをユーザースペースからカーネルスペースにコピーします。最初にをコピーしstruct ioctl_node、次にポインタを個々のノードにコピーしてからstruct node、ループ内で'をコピーする必要があります。必ず適切な量のメモリを割り当ててください。ノードの数は事前にわかっているので、それらの配列を割り当てることができます。

struct node_data {
    size_t node_count;
    struct nodes *nodes;
};
struct node_data *read_nodes(struct ioctl_node_user_pointer *arg)
{
    struct node_data *nd = NULL;
    struct ioctl_node kin = {0};
    struct node *node_user_pointers = NULL;
    int i;
    int err;
    /* Step 1: retrieve the root node */
    nd = kmalloc(sizeof(*nd), GFP_KERNEL);
    if (!nd) {
        err = -ENOMEM;
        goto error;
    }
    if (copy_from_user(ioctl_node_user_pointer, &kin, sizeof(kin))) {
        err = -EFAULT;
        goto error;
    }
    if (kin->count < 0 || kin->count > ((size_t)-1)/sizeof(*nodes)) {
        err = -EINVAL;
        goto error;
    }
    nd->node_count = kin.count;
    /* Step 2: retrieve the pointers to individual nodes */
    node_user_pointers = kmalloc(sizeof(*node_user_pointers) * nd->node_count, GFP_KERNEL);
    if (node_user_pointers) {
        err = -ENOMEM;
        goto error;
    }
    if (copy_from_user(kin->nodes, node_user_pointers, sizeof(*node_user_pointers) * nd->node_count)) {
        err = -EFAULT;
        goto error;
    }
    /* Step 3: retrieve the nodes themselves */
    nd->nodes = kmalloc(sizeof(*nodes) * nd->node_count, GFP_KERNEL);
    if (!nd->nodes) {
        err = -ENOMEM;
        goto error;
    }
    for (i = 0; i < head.count; i++) {
        if (copy_from_user(node_user_pointers[i], nd->nodes + i, sizeof(nd->nodes[0]))) {
            err = -EFAULT;
            goto error;
        }
    }
    kfree(node_user_pointers);
    return nd;
error:
    if (nd) {
        kfree(nd->nodes);
        kfree(nd);
    }
    kfree(node_user_pointers);
    return ERR_PTR(err);
}
于 2012-08-26T20:55:18.007 に答える