@HUST张友东 work@taobao zyd_com@126.com
分类: 服务器与存储
2010-08-10 18:01:23
上个月给文件系统添加额外的属性设置接口,但却是完全脱离文件系统实现的,直接使用rpc连接元数据服务器来设置/获取属性,而没有通过文件系统的客户端。当时想着还有一种方法就是在fuse-2.8中支持了ioctl接口,可通过为分布式文件系统实现ioctl接口实现扩展属性的获取与设置。
使用ioctl首先要理解ioctl命令的封装格式,ioctl的命令对应一个32bits的整数,其格式如下:
2位,访问模式 |
14位,参数的大小 |
8位,魔数 |
8位序号 |
/usr/include/asm-generic/ioctl.h中提供了一系列操作ioctl命令的宏:
/* ioctl command encoding: 32 bits total, command in lower 16 bits, |
在fu***mp.c中的简单的实现了ioctl接口,我系统上安装的fuse-2.7,提示fuse_operations中没有ioctl成员,这是由于fuse-2.8才引入ioctl接口,于是重新安装fuse-2.8,编译OK,但不能正常工作。
由于从fuse-2.8开始,fuse包中不再附带内核模块,内核模块已经加入到内核源代码中,而我机器上之前安装的fuse中带有内核模块,故虽然fuse的用户编程库更新到2.8版本,但运行的内核模块仍不支持ioctl接口,重启进入2.6.30.5内核,同时发现fuse-2.8.0中带了ioctl接口使用的实例(fioc.h, fioc.c, fioclient.c),运行OK。在测试自己下的例子时,发现ioctl只对文件生效,不能对目录进行操作。
怀疑是fuse对inode进行初始化时,目录的inode的i_fop结构中不含ioctl接口,读fuse内核模块的代码,验证了我的想法:
fuse_init_inode为fuse初始化inode的代码,在代码中,对于普通的文件调用了fuse_init_common,fuse_init_inode方法,最终普通文件的i_fop为fuse_file_operations;而对于目录文件,其i_fop为fuse_dir_operations,而该结构中的ioctl接口并没有被实现。
static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) |
fuse的ChangeLog节选:(fuse-2.8.0/ChangeLog)
2008-12-05 Miklos Szeredi
* Implement ioctl support. On high level interface only "restricted" ioctls are supported (which are defined with the _IO(), _IOR(), _IOW() or _IOWR() macros). Unrestricted ioctls will only be allwed to CUSE (Character Device in Userspace) servers. Patch by Tejun Heo
2008-06-16 Miklos Szeredi
* Remove fuse kernel module sources. Linux 2.6.27 will support NFS exporting.
(故要支持fuse-2.8的新特性,最好使用linux-2.6.27+的内核)
2008-05-09 Miklos Szeredi
* Don't allow bigger than 4kB writes by default on 2.6.26 and later kernels, so that filesystems not expecting this are not broken on a kernel upgrade. Provide a 'big_writes' mount option to enable this feature. In future API revisions this may become the default.