2

私はこのリンク ( http://www.spinics.net/lists/newbies/msg41016.html ) を見つけ、それを行うことを検討しています。そこで、カーネル モジュールにコードを書きました。

#include <linux/path.h>
#include <linux/namei.h>
#include <linux/fs.h>

struct path p;
struct kstat ks;
kern_path(filepath, 0, &p);
vfs_getattr(&p, &ks);
printk(KERN_INFO "size: %lld\n", ks.size);

次の理由でコンパイルされません。

/root/kernelmodule/hello.c:15: warning: passing argument 1 of ‘vfs_getattr’ from incompatible pointer type
include/linux/fs.h:2563: note: expected ‘struct vfsmount *’ but argument is of type ‘struct path *’
/root/kernelmodule/hello.c:15: warning: passing argument 2 of ‘vfs_getattr’ from incompatible pointer type
include/linux/fs.h:2563: note: expected ‘struct dentry *’ but argument is of type ‘struct kstat *’
/root/kernelmodule/hello.c:15: error: too few arguments to function ‘vfs_getattr’

このドキュメントを見ていたので、本当に混乱しています: http://lxr.free-electrons.com/source/fs/stat.c#L40

そして今、/linux/fs.h の中に vfs_getattr のプロトタイプがあることがわかります:

extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);

誰かが私の実装を手伝ってくれますか? vfsmount と dentry を読み込んでいますが、まだ失われています。

4

4 に答える 4

5

この関数の呼び出しは、使用しているカーネル バージョンによって異なります。引数が 2 つのバージョンは、3.8 から 3.9 の間に導入されました。したがって、カーネル 3.8 以前を使用している場合は「3 つの引数」が必要であり、3.9 以降では 2 つの引数が必要です。

本当にこれをカーネル モードで実行したい場合は、3.9 よりも古いカーネルで、vfs_fstatまたはvfs_stat

ただし、カーネル内でファイルを処理することは嫌われており、より良い代替手段がないかどうかを検討することをお勧めします。たとえば、システム上のボードのメモリにファイルをロードしたい場合などです。 、ユーザーモードプロセスでファイルをロードし、ロードされた部分をプライベートIOCTLタイプの関数を介してカーネルに渡すことができます。これははるかに「カーネルフレンドリー」であり、カーネルソースコード全体にドライバー/モジュールを含めることを計画している場合は、おそらくこれを行う必要があります.

于 2013-09-23T20:10:44.760 に答える
0

vfs_stat が奇妙なエラーを返す: modpost: "vfs_fstatat" [/mydir/module.ko] undefined! だから私は vfs_getattr または vfs_llseek を使用することを好みます

static char *load_file(char* filename)
{
    struct kstat *stat;
    struct file *fp;
    mm_segment_t fs;
    loff_t pos = 0;
    char *buf;
    int input_size;
    int rc;
    //loff_t mPos;

    fp = filp_open(filename, O_RDONLY, 0644);// O_RDWR O_RDONLY O_WRONLY O_APPEND O_CREAT
            if (IS_ERR(fp)) {
                    printk("Open file error!\n");
                    return ERR_PTR(-ENOENT);
    }

    fs = get_fs();
    set_fs(KERNEL_DS);
    
    stat =(struct kstat *) kmalloc(sizeof(struct kstat), GFP_KERNEL);

    rc = vfs_getattr(&fp->f_path, stat, STATX_SIZE, AT_STATX_SYNC_AS_STAT);
    if(rc != 0){
        printk("vfs_getattr Error");
    }
    //OR symply
    //mPos = vfs_llseek(fp, 0, SEEK_END);
    
    input_size = stat->size;
    //input_size = (int)mPos;

    buf = kmalloc(input_size, GFP_KERNEL);
            if (!buf) {
                    kfree(stat);
                    printk("malloc input buf error!\n");
                    return ERR_PTR(-ENOMEM);
            }
    kernel_read(fp, buf, input_size, &pos);

    filp_close(fp, NULL);
    set_fs(fs);
    kfree(stat);
    return buf;
}
于 2021-09-24T07:29:44.057 に答える
0

すでに開いている場合は、file* filpfilp_openのようにサイズを読み取ることができます。

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
    loff_t size = i_size_read(file_inode(filp));
#else   
    loff_t size = i_size_read(filp->f_path.dentry->d_inode);
#endif
于 2021-11-26T13:23:02.017 に答える