Don't doubly unmount the file system when using libfuse
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 hmm, it seems like there's an assertion failure in the tests. Do you know what's up with that?
@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?
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
Yes, the kernel sends FUSE_DESTROY after the unmount.
Is this related to #295?