开发者

Can't access super_blocks list from kernel module: undefined!

I'm trying to write a kernel module, which prints some information about the objects in the VFS subsystem. That way I want to learn how the VFS works and what structures it uses.

However, I can't manage to iterate the super_blocks list, because of this compiler warning:

WARNING: "super_blocks" [/path/to/module/vfsinfo.ko] undefined!

If I still try to insert the module, insmod fails and returns a similar message.

开发者_StackOverflow

Here is the relevant part of my code:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/fs.h>

#define PRINT(...) printk(KERN_ALERT __VA_ARGS__)

/*
 * Print all super blocks
 */
static void vfsinfo_print_super_blocks(void) {
        struct super_block *s;

        list_for_each_entry(s, &super_blocks, s_list) {
                PRINT("%s\n", s->s_type->name);
        }
}

What am I doing wrong?


It seems super_blocks is not exported with EXPORT_SYMBOL() to modules. See

http://www.kernel.org/doc/htmldocs/kernel-hacking.html#symbols

for more information.


Even after some research I couldn't find any helpful list_head or function that is exported for kernel modules. Since this project should just help me to learn the VFS data structures, I decided to create a pointer to a struct list_head and assign it the address to the "real" list_head super_blocks.

For this purpose I first looked up the address in the System.map file.

$ grep super_blocks /boot/System.map-2.6.36
ffffffff81a22650 D super_blocks

Then I set up my list_head and started working with it:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/fs.h>

#define PRINT(...) printk(KERN_ALERT __VA_ARGS__)

/*
 * Print all super blocks
 */
static void vfsinfo_print_super_blocks(void) {
        struct list_head *super_blocks = 0xffffffff81a22650;
        struct super_block *s;

        list_for_each_entry(s, super_blocks, s_list) {
                PRINT("%s\n", s->s_type->name);
        }
}

Now I am able to access all my super blocks :)

[ 1218.356475] sysfs
[ 1218.357066] rootfs
[ 1218.358450] bdev
[ 1218.359600] proc
[ 1218.360368] tmpfs
[ 1218.361612] sockfs
[ 1218.362388] debugfs
[ 1218.363090] pipefs
[ 1218.363752] anon_inodefs
[ 1218.364076] devpts
[ 1218.365077] hugetlbfs
[ 1218.365654] mqueue
[ 1218.366459] selinuxfs
[ 1218.367060] usbfs
[ 1218.367489] ext2
[ 1218.368065] sysfs
[ 1218.369076] tmpfs

Bye

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜