fusion 文件系统无法更改 getattr 函数中 struct stat *stbuf 的值?
问题解决了! 感谢@basile-starynkevitch,我发现不同文件中的 struct stat 大小不一样!
在
中,sizeof(struct stat)
是88字节,但是带有fuse的lib(我猜是由于-D_FILE_OFFSET_BITS=64< /code> 标志),这是 96 字节。
因此,当我将 fusion lib 添加到远程服务器时(将 -D_FILE_OFFSET_BITS=64 /usr/local/lib/libfuse.so /usr/local/lib/libulockmgr.so
标志添加到 gcc 中),那么我的程序运行正确!
感谢您的帮助!
我正在 fusion 上做一些项目,这让我抓狂。
我从远程服务器发送 struct stat *stbuf 的数据,并且数据在服务器和客户端中都是正确的,但是当我使用 memcpy 将数据复制到 stbuf 时,似乎没有复制任何内容。我还尝试使用 read(socked,stbuf,sizeof(struct stat));直接,但这也不起作用。
这是代码...(如果没有这样的文件,远程服务器将 -ENOENT 保存在 st_ino 中)
static int rof_getattr(const char *path, struct stat *stbuf)
{
int res = 0;
struct cmd sndcmd;
struct stat buf;
memset(&sndcmd, 0, sizeof(struct cmd));
strcpy(sndcmd.cmd, "GETATTR");
strcpy(sndcmd.str, path);
memset(stbuf, 0, sizeof(struct stat));
GTTR_AGN:
memset(&buf, 0,sizeof(struct stat));
write(sockfd, &sndcmd, sizeof(struct cmd));
res=read(sockfd, &buf, sizeof(struct stat));
if(res!=sizeof(struct stat))
goto GTTR_AGN;
memcpy(stbuf,&buf,sizeof(buf));
if (buf.st_ino==-ENOENT)
return -ENOENT;
return 0;
}
我从 gdb 获取的数据:
39 res=read(sockfd, &buf, sizeof(struct stat));
3: (struct stat)stbuf = {st_dev = 694294557525955008, __pad1 = 0, __st_ino = 0,
st_mode = 0, st_nlink = 0, st_uid = 0, st_gid = 0, st_rdev = 0, __pad2 = 0,
st_size = 0, st_blksize = 0, st_blocks = 0, st_atim = {tv_sec = 0, tv_nsec = 0},
st_mtim = {tv_sec = 0, tv_nsec = 0}, st_ctim = {tv_sec = 0, tv_nsec = 0},
st_ino = 0}
1: buf = {st_dev = 0, __pad1 = 0, __st_ino = 0, st_mode = 0, st_nlink = 0,
st_uid = 0, st_gid = 0, st_rdev = 0, __pad2 = 0, st_size = 0, st_blksize = 0,
st_blocks = 0, st_atim = {tv_sec = 0, tv_nsec = 0}, st_mtim = {tv_sec = 0,
tv_nsec = 0}, st_ctim = {tv_sec = 0, tv_nsec = 0}, st_ino = 0}
在 read() 之后,在 buf 中获取数据
(gdb) s
40 memcpy(stbuf,&buf,sizeof(buf));
3: (struct stat)stbuf = {st_dev = 694294557525955008, __pad1 = 2049, __st_ino = 0,
st_mode = 0, st_nlink = 943887, st_uid = 16877, st_gid = 2,
st_rdev = 4294967297000, __pad2 = 0, st_size = 0, st_blksize = 4096,
st_blocks = 34359742464, st_atim = {tv_sec = 1323833759, tv_nsec = 75415995},
st_mtim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ino = 0}
1: buf = {st_dev = 2049, __pad1 = 0, __st_ino = 943887, st_mode = 16877,
st_nlink = 2, st_uid = 1000, st_gid = 1000, st_rdev = 0, __pad2 = 0,
st_size = 17592186048512, st_blksize = 8, st_blocks = 323909233444133279,
st_atim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_mtim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {tv_sec = 0, tv_nsec = 0},
st_ino = 0}
(gdb) s
将数据复制到 stbuf
41 if (stbuf->st_ino==-ENOENT)
3: (struct stat)stbuf = {st_dev = 694294557525955008, __pad1 = 2049, __st_ino = 0,
st_mode = 0, st_nlink = 943887, st_uid = 16877, st_gid = 2,
st_rdev = 4294967297000, __pad2 = 0, st_size = 0, st_blksize = 4096,
st_blocks = 34359742464, st_atim = {tv_sec = 1323833759, tv_nsec = 75415995},
st_mtim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ino = 0}
1: buf = {st_dev = 2049, __pad1 = 0, __st_ino = 943887, st_mode = 16877,
st_nlink = 2, st_uid = 1000, st_gid = 1000, st_rdev = 0, __pad2 = 0,
st_size = 17592186048512, st_blksize = 8, st_blocks = 323909233444133279,
st_atim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_mtim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {tv_sec = 0, tv_nsec = 0},
st_ino = 0}
stbuf 根本没有改变。
有人可以给我一些关于这种现象的建议吗?我已经做了一些工作,但仍然没有找到解决方案。
Question Solved!
Thanks to @basile-starynkevitch , I find out that the struct stat
is not at the same size in different files!
In <sys/stat.h>
, sizeof(struct stat)
is 88bytes, but with fuse's lib(I guess that due to -D_FILE_OFFSET_BITS=64
flag), this is 96bytes.
So when I add fuse lib to my remote server(add -D_FILE_OFFSET_BITS=64 /usr/local/lib/libfuse.so /usr/local/lib/libulockmgr.so
flag to gcc), then my program runs correctly!
Thanks to your help!
I am doing some projects on fuse, and it got me crazy.
I send struct stat *stbuf 's data from a remote server, and the data is correct in both server and client, but when I use memcpy to duplicate the data into stbuf, it seems that nothing copied. I also try to use read(socked,stbuf,sizeof(struct stat)); directly, but that does not work too.
here is the codes...(if there is no such file, the remote server save -ENOENT in st_ino)
static int rof_getattr(const char *path, struct stat *stbuf)
{
int res = 0;
struct cmd sndcmd;
struct stat buf;
memset(&sndcmd, 0, sizeof(struct cmd));
strcpy(sndcmd.cmd, "GETATTR");
strcpy(sndcmd.str, path);
memset(stbuf, 0, sizeof(struct stat));
GTTR_AGN:
memset(&buf, 0,sizeof(struct stat));
write(sockfd, &sndcmd, sizeof(struct cmd));
res=read(sockfd, &buf, sizeof(struct stat));
if(res!=sizeof(struct stat))
goto GTTR_AGN;
memcpy(stbuf,&buf,sizeof(buf));
if (buf.st_ino==-ENOENT)
return -ENOENT;
return 0;
}
the data I get from gdb:
39 res=read(sockfd, &buf, sizeof(struct stat));
3: (struct stat)stbuf = {st_dev = 694294557525955008, __pad1 = 0, __st_ino = 0,
st_mode = 0, st_nlink = 0, st_uid = 0, st_gid = 0, st_rdev = 0, __pad2 = 0,
st_size = 0, st_blksize = 0, st_blocks = 0, st_atim = {tv_sec = 0, tv_nsec = 0},
st_mtim = {tv_sec = 0, tv_nsec = 0}, st_ctim = {tv_sec = 0, tv_nsec = 0},
st_ino = 0}
1: buf = {st_dev = 0, __pad1 = 0, __st_ino = 0, st_mode = 0, st_nlink = 0,
st_uid = 0, st_gid = 0, st_rdev = 0, __pad2 = 0, st_size = 0, st_blksize = 0,
st_blocks = 0, st_atim = {tv_sec = 0, tv_nsec = 0}, st_mtim = {tv_sec = 0,
tv_nsec = 0}, st_ctim = {tv_sec = 0, tv_nsec = 0}, st_ino = 0}
after read(), got data in buf
(gdb) s
40 memcpy(stbuf,&buf,sizeof(buf));
3: (struct stat)stbuf = {st_dev = 694294557525955008, __pad1 = 2049, __st_ino = 0,
st_mode = 0, st_nlink = 943887, st_uid = 16877, st_gid = 2,
st_rdev = 4294967297000, __pad2 = 0, st_size = 0, st_blksize = 4096,
st_blocks = 34359742464, st_atim = {tv_sec = 1323833759, tv_nsec = 75415995},
st_mtim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ino = 0}
1: buf = {st_dev = 2049, __pad1 = 0, __st_ino = 943887, st_mode = 16877,
st_nlink = 2, st_uid = 1000, st_gid = 1000, st_rdev = 0, __pad2 = 0,
st_size = 17592186048512, st_blksize = 8, st_blocks = 323909233444133279,
st_atim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_mtim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {tv_sec = 0, tv_nsec = 0},
st_ino = 0}
(gdb) s
copy data to stbuf
41 if (stbuf->st_ino==-ENOENT)
3: (struct stat)stbuf = {st_dev = 694294557525955008, __pad1 = 2049, __st_ino = 0,
st_mode = 0, st_nlink = 943887, st_uid = 16877, st_gid = 2,
st_rdev = 4294967297000, __pad2 = 0, st_size = 0, st_blksize = 4096,
st_blocks = 34359742464, st_atim = {tv_sec = 1323833759, tv_nsec = 75415995},
st_mtim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ino = 0}
1: buf = {st_dev = 2049, __pad1 = 0, __st_ino = 943887, st_mode = 16877,
st_nlink = 2, st_uid = 1000, st_gid = 1000, st_rdev = 0, __pad2 = 0,
st_size = 17592186048512, st_blksize = 8, st_blocks = 323909233444133279,
st_atim = {tv_sec = 1323729515, tv_nsec = 6514929}, st_mtim = {
tv_sec = 1323729515, tv_nsec = 6514929}, st_ctim = {tv_sec = 0, tv_nsec = 0},
st_ino = 0}
stbuf does not change at all.
Can anyone give me some suggestion about such phenomenon? I've done some work but still not find a solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不会在代码中检查读取的字节数
res
。在文件末尾它可以是 0,在错误时它可以是 -1,如果没有接收到所有字节,它可能小于
sizeof(struct stat)
...阅读(用你的眼睛)和大脑)非常仔细地(并再次阅读两次)read(2) 的手册页 系统调用。
You don't check the number of read bytes
res
in your code.It can be 0 on end of file, it can be -1 on errors, and it could be less than
sizeof(struct stat)
if all bytes have not being received...Read (with your eyes and brain) very carefully (and read it again twice) the man page of read(2) syscall.