файловая система fuse не может изменить значение struct stat * stbuf в функции getattr? - PullRequest
2 голосов
/ 14 декабря 2011

Вопрос решен! Благодаря @ 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));напрямую, но это тоже не работает.

вот коды ... (если такого файла нет, удаленный сервер сохраняет -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}

после чтения (), получил данные в 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 не изменяется привсе.

Кто-нибудь может дать мне какое-нибудь предложение о таком явлении?Я проделал некоторую работу, но все еще не нашел решения.

1 Ответ

1 голос
/ 14 декабря 2011

Вы не проверяете количество прочитанных байтов res в своем коде.

Это может быть 0 в конце файла, это может быть -1 в случае ошибок, иэто может быть меньше sizeof(struct stat), если не были получены все байты ...

Чтение (вашими глазами и мозгом) очень внимательно (и прочитайте его дважды) справочную страницу для чтения (2) системный вызов.

...