1

When you call fsync on a file, you flush its buffer and make sure it gets written to disk.

But if your program newly creates a file, then that needs to get recorded in the metadata of the parent directory. Thus, even if you fsync a file, it's not guaranteed to be persistent in the file system yet. You need to flush the parent directory's buffer as well.

Is there a simple call, such as fsync_parent(fd) that'll accomplish this? If?

(Looking at this question, it seems there's no C standard way to get the parent directory of a file)

Ari Sweedler
  • 807
  • 7
  • 25
  • If there isn't, it seems like a little bit of a strange limitation... And since nothing's been introduced to fix this, that leads me to believe that it's not a big problem. I suppose it would only be an issue for like the first 5-30(?) seconds after a file is created, but still... it seems like an unnecessary weakness. Is it really that much of a non issue that it doesn't warrant a fix? – Ari Sweedler Mar 01 '18 at 23:46
  • my off-the-top guess is `fsync` will take care of writing all file data and necessary metadata. Do you know this is false, or have evidence suggesting it is? – yano Mar 01 '18 at 23:56
  • 1
    nevermind, it says in the [man page](https://linux.die.net/man/2/fsync) "Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an explicit fsync() on a file descriptor for the directory is also needed." – yano Mar 02 '18 at 00:01
  • 1
    @yano, yes, but I don't think that means that the file and the directory can't be recovered after a crash or reboot. It was actually surprising to me that posix allows this state of affairs. – jwdonahue Mar 02 '18 at 00:04
  • @jwdonahue I agree, if file data gets written to disk (and not overwritten), it should be recoverable.. if not by the OS then by forensic tools. Interesting scenario, but surely low probability of occurring, at least for the file you're interested in. – yano Mar 02 '18 at 00:12
  • Right, low possibility of occurring. You have like 10 seconds (or however long you buffer writes) to crash your computer after creating a file, so you won't even have that much data in it probably. And yeah, the data will still be flushed to the file, but it just won't be linked in the directory!! I'm with you, @jwdonahue, it feels sloppy! – Ari Sweedler Mar 02 '18 at 00:24
  • 1
    Posix leaves much up the file system implementation. Depending on which one you are using, it's likely a moot issue. – jwdonahue Mar 02 '18 at 00:25
  • If you think about it, a directory is just another file with some references to other files. But, for a file to be created, it must exist in a directory somewhere, at least initially, otherwise other processes could create identical file names. In this scenario, it might be out of date in terms of exactly where on the disk the current start of the file exists, but I think there's got to be an entry for the file and file meta data that would be quickly stitched back together at boot, if the admin doesn't somehow skip file system integrity checks. – jwdonahue Mar 02 '18 at 00:32

1 Answers1

2

There is no canonical "the parent directory" of a file. A file can have any number of links, or no links at all. If you need a particular directory containing (a link to) the file to be synchronized, you have to track that yourself.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • How could one even do this? I see this approach: https://stackoverflow.com/questions/229012/getting-absolute-path-of-a-file but that feels a little too hacky. I'd do it in Python!! But in C? Doesn't sit right... How would you do it? – Ari Sweedler Mar 03 '18 at 06:13
  • I said track it, not get it. When you open the file, store alongside the fd the name you opened it with. – R.. GitHub STOP HELPING ICE Mar 03 '18 at 13:49
  • Calling [`sync`](https://linux.die.net/man/2/sync) will "cause all buffered modifications to file metadata and data to be written to the underlying file systems". – Ari Sweedler Aug 30 '18 at 01:02