Board logo

标题: 使用 FUSE 开发自己的文件系统(3) [打印本页]

作者: look_w    时间: 2018-5-18 21:37     标题: 使用 FUSE 开发自己的文件系统(3)

定义 RX RPC 层在继续之前,您需要先定义 RX RPC 层。要实现这种功能,请为 rxgen 创建一个 .xg 文件,用来描述代理和与 afsfuse_client.c 和 afsfuse_server.c 进行链接的桩代码。清单 2 显示了如何创建一个具有如下内容的 afsfuse.xg 文件:
清单 2. 创建 afsfuse.xg 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#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 调用如下所示:
1
2
3
4
5
6
7
8
9
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 调用如下所示:
清单 3. afsfuse_server.c 调用
1
2
3
4
5
6
7
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 和 -DFUSE_USE_VERSION=22。
清单 4. 生成编译客户机代码使用的 makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 和 RX 使用的 LWP 代码上。fuse/fuse.o、fuse/helper.o 和 fuse/mount.o 都是代码需要链接的 FUSE 库。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0