在开发fuse的时候,使用libfuse,这个库要求定义 -D_FILE_OFFSET_BITS=64,如果没有定义这个宏,在包含fuse头文件的时候,fuse头文件会报错。
我的源码fuse相关的操作都在fuse_fs.c源文件,因此只有编译这个源文件的时候定义了这个宏。
cc -MT obj/fuse_fs.o -MMD -MP -MF obj/fuse_fs.d -m32 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wall -Werror -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse -c fuse_fs.c -o obj/fuse_fs.o
另外一个文件convert.c 有一个函数,将服务器返回的大端字节消息转换成struct stat,这个stat会返回给fuse。
在编译32位时,运行报错了:
$ ls tmp/linux
ls: cannot access 'tmp/linux': No such file or directory
fuse_fs.c
static void tcpfs_on_lookup(struct tcpfs_client *cli,
struct request *req,
struct tcpfs_msg *msg)
{
struct fuse_entry_param e = {
.attr_timeout = 1.0,
.entry_timeout = 1.0,
};
attr_n2h(msg_attr(msg), &e.attr);
e.ino = e.attr.st_ino;
printf("stat size %d\n", sizeof(struct stat));
printf("%p\n", &e.attr.st_ino);
printf("ino %" PRIu64 "\n",e.attr.st_ino);
DBG("reply ok\n");
fuse_reply_entry((fuse_req_t)req->req_t, &e);
}
convert.c
void attr_n2h(struct tcpfs_attr *attr, struct stat *stbuf)
{
stbuf->st_ino = be64toh(attr->ino);
stbuf->st_size = be64toh(attr->size);
stbuf->st_blocks = be64toh(attr->blocks);
printf("ino %lld %lld\n", (long long)attr->ino, (long long)stbuf->st_ino);
printf("%p\n", &stbuf->st_ino);
}
打印如下:
ino -9064811465013198848 5387138
0xffca0cc8
stat size 96
0xffca0d14
可以看到convert.c里面和fuse_fs.c里面,stbuf->st_ino的地址不一样,且结构体的大小也不一样,这就导致了,数据异常。解决办法,是所有源码定义-D_FILE_OFFSET_BITS=64