Linux 内核使用register_filesystem添加自定义文件系统deanfs

内核版本:3.0.35

先上码:

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/backing-dev.h>
#include <linux/ramfs.h>
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/slab.h>
#include <asm/uaccess.h>


static struct dentry *deanfs_mount(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data)
{
    printk(KERN_INFO"dean: %s =>> %s ==>>%d\n",__FILE__,__FUNCTION__,__LINE__);
    return 0;
}

void kill_dean_super(struct super_block *sb)
{
    printk(KERN_INFO"dean: %s =>> %s ==>>%d\n",__FILE__,__FUNCTION__,__LINE__);
}



static struct file_system_type deanfs_fs_type = {
    .name		= "deanfs",
    .mount		= deanfs_mount,  // mount -t deanfs /mnt /mnt 执行此函数
    .kill_sb	= kill_dean_super,
};

static int __init init_deanfs_fs(void)
{
    printk(KERN_INFO"dean: %s =>> %s ==>>%d\n",__FILE__,__FUNCTION__,__LINE__);
    return register_filesystem(&deanfs_fs_type);
}

static void __exit exit_deanfs_fs(void)
{
    printk(KERN_INFO"dean: %s =>> %s ==>>%d\n",__FILE__,__FUNCTION__,__LINE__);
    unregister_filesystem(&deanfs_fs_type);
}

module_init(init_deanfs_fs)
module_exit(exit_deanfs_fs)

MODULE_LICENSE("GPL");


编译,执行:

/tmp # insmod deanfs.ko 
[ 2219.088567] dean: /home/dawu/network/filesystem/deanfs/deanfs.c =>> init_deanfs_fs ==>>39
/tmp # 

/tmp # cat /proc/filesystems 
nodev   sysfs
nodev   rootfs
nodev   bdev
nodev   proc
nodev   tmpfs
nodev   debugfs
nodev   sockfs
nodev   pipefs
nodev   anon_inodefs
nodev   rpc_pipefs
nodev   devpts
        ext3
        ext2
        ext4
        cramfs
        squashfs
nodev   ramfs
        vfat
        msdos
nodev   nfs
        ntfs
nodev   autofs
nodev   fuse
        fuseblk
nodev   fusectl
nodev   mqueue
nodev   oprofilefs
nodev   deanfs          //我们新添加的文件系统
/tmp # 

/tmp # mount -t deanfs /mnt /mnt
[ 2313.598446] dean: /home/dawu/network/filesystem/deanfs/deanfs.c =>> deanfs_mount ==>>20   //这里调用mount回调函数
[ 2313.607580] Unable to handle kernel NULL pointer dereference at virtual address 00000058
[ 2313.615776] pgd = e40ec000
[ 2313.618532] [00000058] *pgd=39ed7831, *pte=00000000, *ppte=00000000
[ 2313.625088] Internal error: Oops: 17 [#2] PREEMPT SMP
[ 2313.630144] Modules linked in: deanfs [last unloaded: deanfs]
[ 2313.635941] CPU: 0    Tainted: G      D      (3.0.35 #3)
[ 2313.641271] PC is at mount_fs+0x30/0xdc
[ 2313.645123] LR is at __schedule+0x2cc/0x79c
[ 2313.649313] pc : [<c0771c94>]    lr : [<c0b22d88>]    psr: 00000013
[ 2313.649318] sp : e9cb9ea0  ip : e9cb9cf8  fp : e9cb9ecc
[ 2313.660809] r10: e9ee17e0  r9 : e9ee1a60  r8 : 00000000
[ 2313.666038] r7 : 00008000  r6 : bf0081c8  r5 : 00000000  r4 : e9fc9a80
[ 2313.672570] r3 : 00000002  r2 : 00000001  r1 : e9ec8be0  r0 : 00000000
[ 2313.679104] Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[ 2313.686245] Control: 10c53c7d  Table: 340ec04a  DAC: 00000015
[ 2313.691996] Process mount (pid: 633, stack limit = 0xe9cb82f0)
[ 2313.697834] Stack: (0xe9cb9ea0 to 0xe9cba000)
[ 2313.702199] 9ea0: 00000000 bf0081c8 bf0081c8 e9fc9a80 bf0081c8 e9ee17e0 00000000 e9ee1a60
[ 2313.710384] 9ec0: e9cb9ef4 e9cb9ed0 c078b52c c0771c70 00000000 bf0081c8 e9ee1a60 00000000
[ 2313.718570] 9ee0: e9ee17e0 00008000 e9cb9f1c e9cb9ef8 c078b9e4 c078b4dc 00000000 00000020
[ 2313.726756] 9f00: 00000000 00008000 00000000 00008000 e9cb9f6c e9cb9f20 c078d2a4 c078b9ac
[ 2313.734940] 9f20: be8e8f88 00001000 e9fc9940 e60c4f70 c07493bc c07492b0 e9cb9f80 be8e8f88
[ 2313.743125] 9f40: 00000000 e9e36000 be8e8f88 00000000 00008000 c0683104 e9cb8000 00000000
[ 2313.751310] 9f60: e9cb9fa4 e9cb9f70 c078d96c c078ce98 00000000 00000000 00000000 e9ee1a60
[ 2313.759494] 9f80: e9ee17e0 00000000 00000000 00000000 be8e8f88 00000015 00000000 e9cb9fa8
[ 2313.767679] 9fa0: c0682ec0 c078d8e4 00000000 00000000 be8e8f88 be8e8f8d be8e8f81 00008000
[ 2313.775864] 9fc0: 00000000 00000000 be8e8f88 00000015 be8e8f8d 00000000 be8e8f81 00000000
[ 2313.784050] 9fe0: 00008000 be8e8b6c 0007e4f8 4028fb64 60000010 be8e8f88 7bfdffff 6ff9fcff
[ 2313.792254] [<c0771c94>] (mount_fs+0x30/0xdc) from [<c078b52c>] (vfs_kern_mount+0x5c/0x9c)
[ 2313.800533] [<c078b52c>] (vfs_kern_mount+0x5c/0x9c) from [<c078b9e4>] (do_kern_mount+0x44/0xe4)
[ 2313.809245] [<c078b9e4>] (do_kern_mount+0x44/0xe4) from [<c078d2a4>] (do_mount+0x418/0x708)
[ 2313.817609] [<c078d2a4>] (do_mount+0x418/0x708) from [<c078d96c>] (sys_mount+0x94/0xd4)
[ 2313.825628] [<c078d96c>] (sys_mount+0x94/0xd4) from [<c0682ec0>] (ret_fast_syscall+0x0/0x30)
[ 2313.834077] Code: e12fff3c e3700a01 e1a05000 8a000011 (e5904058) 
[ 2313.840401] ---[ end trace 6fbf4607db252efa ]---
Segmentation fault
/tmp # 

注:这里出现oops是因为这个只是不完整的文件系统,还差很多东西填充,接下去有空会慢慢完善。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
register_filesystem函数是Linux内核中用于向系统注册文件系统的函数,其源代码如下: ``` int register_filesystem(struct file_system_type *fs) { int err; down_write(&file_systems_lock); err = __register_filesystem(fs, false); up_write(&file_systems_lock); return err; } ``` 该函数接受一个file_system_type结构体指针作为参数,其中包含了要注册的文件系统的名称、挂载函数、卸载函数等信息。函数首先使用down_write函数获取文件系统锁,以确保在注册过程中不会发生并发问题。接着调用__register_filesystem函数进行具体的注册操作。最后使用up_write函数释放文件系统锁,并返回注册结果。 __register_filesystem函数的源代码如下: ``` int __register_filesystem(struct file_system_type *fs, int is_default) { struct file_system_type *old; int err = 0; /* Make sure we are not un-registering a file system while it is * being mounted. */ if (is_default) down_write(&file_systems_lock); else down_write_trylock(&file_systems_lock); old = find_filesystem(fs->name); if (old) { /* File system already exists */ err = -EBUSY; if (fs->owner != old->owner) err = -EEXIST; goto out; } err = -ENOMEM; if (fs->fs_supers) { err = radix_tree_preload(GFP_KERNEL); if (err) goto out; } err = security_fs_context_dup(fs->fs_context); if (err) goto out_radix; err = security_fs_context_parse_param(fs->fs_context, fs->name); if (err) goto out_fs_context; list_add(&fs->fs_supers, &file_systems); if (is_default) up_write(&file_systems_lock); else up_write(&file_systems_lock); return 0; out_fs_context: security_fs_context_free(fs->fs_context); out_radix: if (fs->fs_supers) radix_tree_preload_end(); out: up_write(&file_systems_lock); return err; } ``` 该函数首先获取文件系统锁,接着使用find_filesystem函数查找是否已经存在同名的文件系统。如果已经存在,则返回错误码。如果不存在,则进行一系列初始化操作,如调用radix_tree_preload函数预加载文件系统的超级块、复制安全上下文等。最后将文件系统加入到file_systems链表中,并释放文件系统锁。 总体来说,register_filesystem函数和__register_filesystem函数的功能非常简单明了,主要就是向系统注册文件系统。在实现过程中,需要注意并发问题,尤其是多线程同时注册文件系统时可能会引发竞争问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值