libfuse3 low level API hangs when reading file

64 Views Asked by At

I'm implementing a userspace filesystem in C++ using libfuse's low level API, with the following functions already implemented: lookup, forget, getattr, setattr, mknod, read, write, opendir, readdir and releasedir.

I populate the root with some files during initialization for testing purposes, and I'm trying to write to / read from one of them. The write succeeds, but FUSE hangs when reading.

Here's the output:

unique: 302, opcode: LOOKUP (1), nodeid: 1, insize: 46, pid: 444120 <---- echo foo >cat mnt/foo
   unique: 302, success, outsize: 144
unique: 304, opcode: OPEN (14), nodeid: 2, insize: 48, pid: 444120
   unique: 304, success, outsize: 32
unique: 306, opcode: GETXATTR (22), nodeid: 2, insize: 68, pid: 444120
   unique: 306, error: -38 (Function not implemented), outsize: 16
unique: 308, opcode: FLUSH (25), nodeid: 2, insize: 64, pid: 444120
   unique: 308, error: -38 (Function not implemented), outsize: 16
unique: 310, opcode: WRITE (16), nodeid: 2, insize: 84, pid: 444120
   unique: 310, success, outsize: 24
unique: 312, opcode: LOOKUP (1), nodeid: 1, insize: 46, pid: 477019 <---- cat mnt/foo
   unique: 312, success, outsize: 144
unique: 314, opcode: OPEN (14), nodeid: 2, insize: 48, pid: 477019
   unique: 314, success, outsize: 32

For some reason I can cat files that are still empty, but once I write to them, FUSE hangs. I enabled single-threaded mode, but I'm having a hard time debugging this, because FUSE hangs after my callbacks execute.

Any directions on the possible issue?

Here's the stat of the file foo:

  File: mnt/foo
  Size: 4           Blocks: 8          IO Block: 4096   regular file
Device: 59h/89d Inode: 2           Links: 1
Access: (0666/-rw-rw-rw-)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-10-24 21:04:25.000000000 -0100
Modify: 2023-10-24 21:04:25.000000000 -0100
Change: 2023-10-24 21:04:25.000000000 -0100
 Birth: -
1

There are 1 best solutions below

0
On

I overlooked the usage of the fuse_reply_err call. It is supposed to be called with a value of 0 on success.

Missing this call in the release callback (or other callbacks that only expect a fuse_reply_err as reply) causes fuse to hang.