基于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