fuser icon indicating copy to clipboard operation
fuser copied to clipboard

Don't doubly unmount the file system when using libfuse

Open asomers opened this issue 5 months ago • 5 comments

fuse_session_destroy already includes an unmount, so it's redundant do call both that and fuse_session_unmount. It's dangerous even, because it could race with a different process using the same mountpoint, and unmount that process's file system.

This change will be more important after the next libfuse release, which will fix a similar double-unmount problem: 1287^1.

Both this commit and ^1 are necessary to eliminate "unmounting /tmp/mnt failed: Invalid argument" warnings that appeared beginning with libfuse 3.17.0.

asomers avatar Jul 16 '25 00:07 asomers

@asomers hmm, it seems like there's an assertion failure in the tests. Do you know what's up with that?

cberner avatar Jul 18 '25 03:07 cberner

@asomers hmm, it seems like there's an assertion failure in the tests. Do you know what's up with that?

The assertion only triggers on Linux, which is why I didn't see it before. But it looks like it probably should be called on FreeBSD too. Digging deeper, I see that libfuse isn't unmounting that file system automatically because the fuse_session has no destroy method. In fact, it has no methods at all! That's because it doesn't get completely initialized in fuse_session_new.

(gdb) p se->op
$2 = {init = 0x0, destroy = 0x0, lookup = 0x0, forget = 0x0, getattr = 0x0, 
  setattr = 0x0, readlink = 0x0, mknod = 0x0, mkdir = 0x0, unlink = 0x0, 
  rmdir = 0x0, symlink = 0x0, rename = 0x0, link = 0x0, open = 0x0, 
  read = 0x0, write = 0x0, flush = 0x0, release = 0x0, fsync = 0x0, 
  opendir = 0x0, readdir = 0x0, releasedir = 0x0, fsyncdir = 0x0, 
  statfs = 0x0, setxattr = 0x0, getxattr = 0x0, listxattr = 0x0, 
  removexattr = 0x0, access = 0x0, create = 0x0, getlk = 0x0, setlk = 0x0, 
  bmap = 0x0, ioctl = 0x0, poll = 0x0, write_buf = 0x0, retrieve_reply = 0x0, 
  forget_multi = 0x0, flock = 0x0, fallocate = 0x0, readdirplus = 0x0, 
  copy_file_range = 0x0, lseek = 0x0, tmpfile = 0x0}

Maybe we need a different approach. During Drop, what if we call the operating system's unmount, but only if we haven't already received a FUSE_DESTROY?

asomers avatar Jul 18 '25 16:07 asomers

I must admit to being a bit ignorant of how FUSE_DESTROY works. Is it delivered by the kernel after the mountpoint has already been removed?

If so, then ya skipping over the unmount code in that case sounds right. There's already a destroyed flag on Session, and that can probably be propagated through to the Mount fairly easily

cberner avatar Jul 18 '25 23:07 cberner

Yes, the kernel sends FUSE_DESTROY after the unmount.

asomers avatar Jul 20 '25 00:07 asomers

Is this related to #295?

rarensu avatar Sep 17 '25 20:09 rarensu