FUSE 内核实现代码分析(一) 初始化

基于linux-3.10内核

用户可以使用libfuse编写自己的文件系统,关键在于FUSE内核模块。做为实现用户空间文件系统的桥梁模块,还是很值得分析一下的。

USE Kernel模块由两部分组成:

第一部分——设备文件接口:fs/fuse/dev.c——回应io请求到/dev/fuse。fuse_dev_read()函数负责读出文件,并将来自“list of request”结构体的命令返回到调用函数。fuse_dev_write ()负责文件写入,并将写入的数据置放到“req→out”数据结构中。

第二部分——文件系统调用部分:fs/fuse/file.c,fs/fuse/inode.c,fs/fuse/dir.c——调用request_send(),将请求加入到“list of request”结构体中,等待回复(reply)。

第三部分——sysfs接口:fs/fuse/connect.c 对fuse一些简单控制和一些数据的导出。


[fs/fuse/inode.c]

static int __init fuse_init(void)
{
        int res; 

        printk(KERN_INFO "fuse init (API version %i.%i)\n",
               FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);

        INIT_LIST_HEAD(&fuse_conn_list);
        res = fuse_fs_init();
        if (res)
                goto err; 

        res = fuse_dev_init();
        if (res)
                goto err_fs_cleanup;

        res = fuse_sysfs_init();
        if (res)
                goto err_dev_cleanup;

        res = fuse_ctl_init();
        if (res)
                goto err_sysfs_cleanup;

        sanitize_global_limit(&max_user_bgreq);
        sanitize_global_limit(&max_user_congthresh);

        return 0;

 err_sysfs_cleanup:
        fuse_sysfs_cleanup();
 err_dev_cleanup:
        fuse_dev_cleanup();
 err_fs_cleanup:
        fuse_fs_cleanup();
 err: 
        return res;
}

fuse_fs_init() 完成fuse_inode的kmem_cache的创建,注册fuse和fuseblk两种文件系统

static int __init fuse_fs_init(void)
{
        int err;

        fuse_inode_cachep = kmem_cache_create("fuse_inode",
                                              sizeof(struct fuse_inode),
                                              0, SLAB_HWCACHE_ALIGN,
                                              fuse_inode_init_once);
        err = -ENOMEM;
        if (!fuse_inode_cachep)
                goto out;

        err = register_fuseblk();
        if (err)
                goto out2;

        err = register_filesystem(&fuse_fs_type);
        if (err)
                goto out3;

        return 0;

 out3:
        unregister_fuseblk();
 out2:
        kmem_cache_destroy(fuse_inode_cachep);
 out:
        return err;
}

fuse_dev_init()完成fuse_request的kmem_cache的建仓,并注册/dev/fuse杂项设备,主设备号10,次设备号229

const struct file_operations fuse_dev_operations = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .read           = do_sync_read,
        .aio_read       = fuse_dev_read,
        .splice_read    = fuse_dev_splice_read,
        .write          = do_sync_write,
        .aio_write      = fuse_dev_write,
        .splice_write   = fuse_dev_splice_write,
        .poll           = fuse_dev_poll,
        .release        = fuse_dev_release,
        .fasync         = fuse_dev_fasync,
};
EXPORT_SYMBOL_GPL(fuse_dev_operations);

static struct miscdevice fuse_miscdevice = {
        .minor = FUSE_MINOR,
        .name  = "fuse",
        .fops = &fuse_dev_operations,
};      
        
int __init fuse_dev_init(void)
{
        int err = -ENOMEM;
        fuse_req_cachep = kmem_cache_create("fuse_request",
                                            sizeof(struct fuse_req),
                                            0, 0, NULL);
        if (!fuse_req_cachep)
                goto out;
                
        err = misc_register(&fuse_miscdevice);
        if (err)
                goto out_cache_clean;
                
        return 0;
        
 out_cache_clean:
        kmem_cache_destroy(fuse_req_cachep);
 out:   
        return err;
}

fuse_sysfs_init() 创建/sys/fs/fuse/connections目录

static int fuse_sysfs_init(void)
{
        int err;
        
        fuse_kobj = kobject_create_and_add("fuse", fs_kobj);
        if (!fuse_kobj) {
                err = -ENOMEM;
                goto out_err;
        }       
        
        connections_kobj = kobject_create_and_add("connections", fuse_kobj);
        if (!connections_kobj) {
                err = -ENOMEM;
                goto out_fuse_unregister;
        }
        
        return 0;
        
 out_fuse_unregister:
        kobject_put(fuse_kobj);
 out_err:
        return err;
}    

fuse_ctl_init() 注册fuse_ctl文件系统

int __init fuse_ctl_init(void)
{
        return register_filesystem(&fuse_ctl_fs_type);
} 

经过上面初始化,内核中多了以下东东,总结一下

1 现在内核了三种文件系统:fuse  fuseblk  fuse_ctl

2 与用户空间交互的设备接口 /dev/fuse

3 控制用的sysfs接口 /sys/fs/fuse



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值