用FUSE开发自己的文件系统一 [转]- -| 回首页 | 2006年索引 | - -Linux中文件查找技术大全

用FUSE开发自己的文件系统二 [转]

                                      

定义 RX RPC

在更进一步之前, 你需要定一个你的RX RPC . 为了做到这个, 要为rxgen创建一个.xg 文件, 来描述你的将用afsfuse_client.c afsfuse_server.c被连接起来的代理和桩代码. Listing 2 描述了怎么创建含有以下内容的afsfuse.xg 文件:


Listing 2. 创建一个afsfuse.xg 文件

#define MYMAXPATH 512

#include <rx/rx.h>

#include </rx_null.h >

#define SAMPLE_SERVER_PORT 5000

#define SAMPLE_SERVICE_PORT 0

/* i.e. user server's port */

#define SAMPLE_SERVICE_ID 4 /* Maximum number of requests that will be handled by this

                                service simultaneously */

/* This number will also be guaranteed to execute in parallel if no services' requests

   are being processed */

#define SAMPLE_MAX 2 /* Minimum number of requests that are guaranteed to be handled

                         immediately */

#define SAMPLE_MIN 1 /* Index of the "null" security class in the sample service. This

                         must be 0 (there are N classes, numbered from 0. In this case,

                         N is 1) */

#define SAMPLE_NULL 0 /********************** fuse4_file_info taken from fuse.h the

                        rxgen does not understands fuse.h  mystat taken from man 2

                        mystat these are required again rxgen does not understand the

                        struct paras and will bump.. **********************/

struct my_file_info { /** Open flags. Available in open() and release() */

                     int flags; /** File handle. May be filled in by filesystem in

                                    open(). Available in all other file operations */

                     unsigned int fh; /** In case of a write operation indicates if

                                          this was caused by a writepage */

                     int writepage;

                    };

struct mystatfs {

                    afs_uint32 f_type; /* type of filesystem (see below) */

                    afs_uint32 f_bsize; /* optimal transfer block size */

                    afs_uint32 f_blocks; /* total data blocks in file system */

                    afs_uint32 f_bfree; /* free blocks in fs */

                    afs_uint32 f_bavail; /* free blocks avail to non-superuser */

                    afs_uint32 f_files; /* total file nodes in file system */

                    afs_uint32 f_ffree; /* free file nodes in fs */

                    afs_uint32 f_fsid1; /* file system id */

                    afs_uint32 f_fsid2; /* file system id */

                    afs_uint32 f_namelen; /* maximum length of filenames */

                    afs_uint32 f_spare[6]; /* spare for later */

                };

struct mystat {

                    afs_uint32 st_dev; /* device */

                    afs_uint32 st_ino; /* inode */

                    afs_uint32 st_mode; /* protection */

                    afs_uint32 st_nlink; /* number of hard links */

                    afs_uint32 st_uid; /* user ID of owner */

                    afs_uint32 st_gid;/* group ID of owner */

                    afs_uint32 st_rdev; /* device type (if inode device) */

                    afs_uint32 st_size; /* total size, in bytes */

                    afs_uint32 st_blksize; /* blocksize for filesystem I/O */

                    afs_uint32 st_blocks; /* number of blocks allocated */

                    afs_uint32 st_atim; /* time of last access */

                    afs_uint32 st_mtim; /* time of last modification */

                    afs_uint32 st_ctim; /* time of last change */

                };

struct my_dirhandle{

                    afs_uint32 type;

                    afs_uint32 inode;

                    char name[MYMAXPATH];

                };

typedef my_dirhandle bulkmydirhandles<>;

 /*********************phase 1 functions *********************************************/

rxc_getattr(IN string mypath<MYMAXPATH>, IN int dummy) split = 1;

rxc_getdirWrapper(IN string path<MYMAXPATH>, OUT bulkmydirhandles *handles) = 2;

rxc_read(IN string path<MYMAXPATH>;, IN afs_uint32 size, IN afs_uint32 offset,

         IN struct my_file_info *fi) split = 3;

rxc_open(IN string path<MYMAXPATH>, IN int flags, OUT u_int *hd) = 4;

rxc_write(IN string path<MYMAXPATH>,IN afs_uint32 size, IN afs_uint32 offset,

          IN struct my_file_info *fi) split = 5;

rxc_chmod(IN string path<MYMAXPATH>, IN afs_uint32 mode) = 6;

rxc_chown(IN string path<MYMAXPATH>, IN afs_uint32 uid, IN afs_uint32 gid) = 7;

rxc_utime(IN string path<MYMAXPATH>, IN afs_uint32 at,IN afs_uint32 mt) = 8;

rxc_mknod(IN string path<MYMAXPATH>, afs_uint32 mode, afs_uint32 rdev) = 9 ;

rxc_mkdir(IN string path<MYMAXPATH>, IN afs_uint32 mode) = 10;

rxc_unlink(IN string path<MYMAXPATH>) = 11 ;

rxc_rmdir(IN string path<MYMAXPATH>) = 12;

rxc_rename(IN string from<MYMAXPATH>, IN string to<MYMAXPATH>) = 13;

rxc_truncate(IN string path<MYMAXPATH>, IN afs_uint32 size) = 14;

rxc_release(IN string path<MYMAXPATH>, IN struct my_file_info *fi) = 15;

rxc_readlink(IN string path<MYMAXPATH>, IN afs_uint32 size,OUT string

             data<MYMAXPATH>) = 16;

rxc_symlink(IN string from<MYMAXPATH>, IN string to<MYMAXPATH>) = 17;

rxc_link(IN string from<MYMAXPATH>, IN string to<MYMAXPATH>) = 18;

rxc_statfs(IN string path<MYMAXPATH>, OUT struct mystatfs *stbuf) = 19;

rxc_fsync(IN string path <MYMAXPAT>, IN int isdatasync, IN struct my_file_info

          *fi) = 20 ;

rxc_flush(IN string path <MYMAXPATH>, IN struct my_file_info *fi) = 21 ;

 

当要定义这个RX RPC 层的时候, 请注意下面的几点:

 

 

创建客户端和桩文件

下一步是编译rxgen afsfuse.xg 文件去生成客户端和桩文件. 从包含afsfuse_server afsfuse_client的源代码的目录里, 运行命令 openafs-1.2.13/i386_linux24/dest/bin/rxgen afsfuse.xg. 这将生成下面的文件:

现在增加一些做实际工作的代码到afsfuse_client.c afsfuse_server.c 文件里. 几乎这些调用看起来都像下面那样:

afsfuse_client.c 调用看起来像下面那样:

int afsfuse_readlink(const char *path, char *buf, size_t size){

    rx_connection *local& int ret& char *buffer = malloc (512)&

    memset(buffer,0,512)& memset(buf,0,size)& local = getconnection()&

    ret = rxc_rxc_readlink(local,path,512,&buffer) // rpc call

         relconnection(local)&

         strncpy(buf,buffer,512-1)&

        //<- demarshall the parametrs

        return ret&

    }

 

afsfuse_server.c 的调用看起来像下面那样:

Listing 3. afsfuse_server.c 的调用

int rxc_rxc_readlink( struct rx_call *call, char * path, afs_uint32 size, char**data)

    { int ret& char lbuff[512] ={0}&

    translatePath(path,lbuff)& //<- make filesystem call

     *data = malloc(512)&

     res = readlink(lbuff, *data, 512-1)&

     if(res == -1) return -errno& (*data)[res] = '\0'& return 0&

    }

 

同样的, 你可以最佳一个代码到其他的函数里去加强你的文件系统.

你将需要创建一个makefile文件去编译你的代码. 记住当编译afsfuse_client的代码时要包含下面的选项: -D_FILE_OFFSET_BITS=64 and -DFUSE_USE_VERSION=22.


Listing 4.
生成makefile文件去编译客户端代码

SRCDIR=./ LIBRX=${SRCDIR}lib/librx.a

LIBS=${LIBRX} ${SRCDIR}lib/liblwp.a

#CC = g++

CFLAGS=-g -I. -I${SRCDIR}include -I${SRCDIR}include/fuse/ -DDEBUG ${XCFLAGS}

    -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=22

afsfuse_client: afsfuse_client.o afsfuse.xdr.o ${LIBS} bulk_io.o afsfuse.cs.o

    ${CC} ${CFLAGS} -o afsfuse_client afsfuse_client.o ${SRCDIR}lib/fuse/fuse.o

    ${SRCDIR}lib/fuse/mount.o ${SRCDIR}lib/fuse/helper.o

    ${SRCDIR}lib/fuse/fuse_mt.o bulk_io.o afsfuse.cs.o afsfuse.xdr.o ${LIBS}

afsfuse_server: afsfuse_server.o afsfuse.xdr.o afsfuse.ss.o bulk_io.o ${LIBS}

    ${CC} ${CFLAGS} -o afsfuse_server afsfuse_server.o bulk_io.o afsfuse.ss.o

    afsfuse.xdr.o ${LIBS}

#afsfuse_client.o: afsfuse.h

#afsfuse_server.o: afsfuse.h

bulk_io.o: ${CC} -c -g -I${SRCDIR}include bulk_io.c afsfuse.cs.c afsfuse.ss.c

    afsfuse.er.c afsfuse.h afsfuse.xdr.c: afsfuse.xg rxgen afsfuse.xg

afsfuse.xdr.o: afsfuse.xdr.c ${CC} -c -g -I{SRCDIR}include afsfuse.xdr.c

all: afsfuse_server afsfuse_client

clean: rm *.o rm afsfuse_client rm afsfuse_server

 

记住, 你将需要使用librx.a liblwp.a 去连接RX LWP 代码. 并且fuse/fuse.o, fuse/helper.o, fuse/mount.o 你需要连接的FUSE .

 

 

结论

本文里, 你已经学到了怎么去安装FUSE OpenAFS 并且怎么去使用它们去创建和定制你自己的用户空间文件系统, 一个在Linux里完全功能的, 稳定的文件系统而且不要求你去给你当前的内核去打补丁或者重新编译它-- 你甚至不用去了解内核的模块编程. 你已经看见了在使能一个FUSE文件系统里的两个关键概念的细节: 怎么去安装和配置FUSE内核模块,以及怎么去撬动FUSE 库和 APIs的能量.

 

 

下载

Description

Name

Size

Download method

AFSFuse filesystem sample code

l-fuse.zip

9KB

HTTP

http://www-128.ibm.com/developerworks/linux/library/l-fuse/?ca=dgr-lnxw09FUSE

【作者: colding】【访问统计:】【2006年08月24日 星期四 17:52】【 加入博采】【打印

Trackback

你可以使用这个链接引用该篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=5571749

回复

验证码:   
评论内容: