10

The FUSE API doesn't expose a file-system level sync call, just fsync and fsyncdir. Does it mean that when sync is called (or syncfs inside a FUSE mountpoint), the kernel invokes fsync on all open files on all FUSE mounted file-systems? Or is there a different semantics?

Petr
  • 62,528
  • 13
  • 153
  • 317

1 Answers1

2

Looking at the kernel source, it seems that on sync and syncfs any pending writebacks are performed, but fsync is not called (not AFAICS anyway), so there is not really any way to know that sync or syncfs is called.

Relevant code is in https://github.com/torvalds/linux/blob/v4.16/fs/sync.c, e.g. https://github.com/torvalds/linux/blob/v4.16/fs/sync.c#L31-L41

As shown, this calls the fsync_fs operation on the fileystem superblock, but fuse does not define any:

https://github.com/torvalds/linux/blob/v4.16/fs/fuse/inode.c#L803-L814

I also recall reading a mailing list thread about this, which suggested that implementing sync_fs in fuse is non-trivial, since it would allow a fuse filesystem (which might run as a non-privileged user) to block any global sync system calls indefinitely, posing a security (DoS) problem. I can't quite find that thread anymore, though.

Matthijs Kooijman
  • 2,498
  • 23
  • 30
  • Since fuse does not implement sync_fs, does that mean the call to __sync_blockdev() is a no-op as far as sending a sync to the fuse client on the files that might have been opened by the application is concerned? – itisravi Apr 11 '18 at 16:50
  • In other words, if the application has opened fds on some files for writing, and wants to sync the contents, the only way is to send an explicit fsyc(2) individually on those fds? – itisravi Apr 11 '18 at 16:52
  • I believe `__sync_blockdev()` will only sync an underlying block device, which is not usually present with fuse filesystems (and thus is probably a no-op). As for fuse not implementing `sync_fs`, that means that [this if](https://github.com/torvalds/linux/blob/v4.16/fs/sync.c#L38-L39) will be false, so no `sync_fs` is called. – Matthijs Kooijman Apr 11 '18 at 20:37
  • As for an application sending `fsync`/`syncfs`: `fsync` is the only message that will reach the fuse filesystem. `syncfs` is not a complete no-op, since [any cached pages will still be sent to fuse for writing](https://github.com/torvalds/linux/blob/v4.16/fs/sync.c#L33-L36) (though that is really only relevant when writeback caching is enabled, fuse defaults to write-through caching where each write is immediately sent to fuse already). However, a fuse application will not explicitly *know* that a `syncfs` happened, so in that sense it is a no-op and an application must resort to `fsync`. – Matthijs Kooijman Apr 11 '18 at 20:39
  • @PetrPudlák I think this is the right answer that you should accept. I should probably delete my answer. – itisravi Apr 12 '18 at 00:29