【问题标题】:fuse filesystem can not change the value of struct stat *stbuf in getattr function?fuse 文件系统无法更改 getattr 函数中 struct stat *stbuf 的值?
【发布时间】:2011-12-14 05:25:32
【问题描述】:

问题已解决! 感谢@basile-starynkevitch,我发现struct stat在不同文件中的大小不一样!

<sys/stat.h> 中,sizeof(struct stat) 是 88 字节,但是使用 fuse 的库(我猜是因为 -D_FILE_OFFSET_BITS=64 标志),这是 96 字节。

所以当我将 fuse lib 添加到我的远程服务器(将 -D_FILE_OFFSET_BITS=64 /usr/local/lib/libfuse.so /usr/local/lib/libulockmgr.so 标志添加到 gcc)时,我的程序可以正常运行!

感谢您的帮助!


我正在做一些关于 fuse 的项目,这让我发疯了。

我从远程服务器发送 struct stat *stbuf 的数据,并且数据在服务器和客户端都是正确的,但是当我使用 memcpy 将数据复制到 stbuf 时,似乎没有复制任何内容。我也尝试使用 read(socked,stbuf,sizeof(struct stat));直接,但这也不起作用。

这里是代码...(如果没有这个文件,远程服务器在st_ino中保存-ENOENT)

    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 完全没有变化。

谁能给我一些关于这种现象的建议?我做了一些工作,但仍然没有找到解决方案。

【问题讨论】:

  • 感谢 Basile Starynkevitch,我添加了对 res 的检查。
  • 检查错误。正如我所解释的,您需要处理四种情况。
  • 尝试转储为 hex 和 ascii buf。你可能读到了一些意想不到的东西……
  • 你应该在gdb下打印*stbuf
  • 我发现了问题,问题是我没有给服务器添加编译标志,所以这个结构的大小和客户端的不一样。感谢您的帮助,这非常有用!

标签: c linux filesystems fuse stat


【解决方案1】:

您没有在代码中检查读取字节数 res

文件结尾可以是 0,错误可以是 -1,如果所有字节都没有被接收到,它可以小于 sizeof(struct stat)...

非常仔细地阅读(用你的眼睛和大脑)(并再次阅读两次)man page of read(2) 系统调用。

【讨论】:

  • 我不检查,我只是想知道我是否正确获取数据,我的代码中没有检查语句对吗?我添加这个是因为我想在调试时显示它。会影响结果吗?我只是在这里添加一个值...
  • 您应该检查res....的值。有几种情况需要处理:res<0(错误)、res==0(到达文件末尾)、res<sizeof(struct stat) (部分阅读)或res==sizeof(struct stat)(阅读完全完成)。您也可以考虑切换到FILE* 并使用fread
  • 知道了,谢谢。另一个问题,你能看一下gdb的输出吗,为什么我在buf中正确获取了数据,但不能将它复制到指针stbuf?
  • 你能看到gdb的输出吗?问题是我在 buf 中得到了我想要的数据......但无法将其保存到指针 stbuf (res==sizeof(struct stat))
  • 您是否签入了(res==sizeof(struct stat)) 的代码?我在res 上没有看到任何测试,您必须处理我提到的所有四种情况。
猜你喜欢
  • 2023-03-04
  • 2015-05-31
  • 2017-10-04
  • 2014-04-22
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
相关资源
最近更新 更多