Conversation

@revk @torvalds Uh, that may require a lot of buffering for the replacement file in the Linux file handling code, right? I know you are thinking of config files etc., but how would the code know what size the file will be?

1
0
0

@Miq @torvalds Not sure, the notion of making a file not in a directory already exists. All that needs "buffering" is the path name of them file to replace on close.

0
0
0

@revk @torvalds Hmm does this already exist? I see in the flags for open(2) there's 'O_TMPFILE' - 'The pathname argument specifies a directory; an unnamed inode will be created in that directory's filesystem. Anything written to the resulting file will be lost when the last file descriptor is closed, unless the file is given a name.......linkat(2) can be used to link the temporary file into the filesystem, making it permanent,

1
0
0

@revk @torvalds I was going to suggest using O_TMPFILE with the target directory to open an anonymous file in the same filesystem, but unfortunately linkat(2) doesn't replace the target if it exists, so you'd first have to link it to a temporary name in the same directory, then rename it over the target.

Not perfect, but at least it avoids leaving temporary files around if you get interrupted while writing the contents.

0
0
0

@revk @torvalds Also, don't underestimate how much of a true PITA the unnamed file stuff is on network filesystems; good luck with NFS .nfs* files

0
0
0

@revk @torvalds you could do that with an fd-based (like fchmod instead od chmod) rename, perhaps? Create the file alongside the existing one with a .tmp suffix, immediately unlink, write at your leisure, then "rename" from the fd to the name. And that frename operation might be useful for other things too! Of course, it would be even better if there's a "create unlinked file on same filesystem as specified file, without even temporarily giving it a name" operation too...

2
0
0

@phlash @revk @torvalds Hmm adding a flag to allow replace to linkat() would seem a fairly small extension then?

1
0
0

@penguin42 @phlash @torvalds hmm, that is a pain, yes, linkat() allowing a replace makes sense. Bugger. So close.

0
0
0

@kitten_tech @revk @torvalds there's a full collection of them, openat for example.

1
0
0

@kitten_tech @torvalds yeh, I never knew of all the new …at() calls.

1
0
0

@f4grx @kitten_tech @torvalds yeh, if renameat2() could do the file fd as old filename, that would work.

0
0
0

@revk @torvalds I went and looked for an frename() in the spirit of fchmod(), believing the ...at() calls to all he about using an arbitrary directory fd as the cwd in order to support per-thread effective cwds, because that's what the man page said they were for...

1
0
0

@kitten_tech @torvalds indeed, the use of a file not a directory and an empty path is clearly a total bodge. Messy at best.

0
0
0

@revk @torvalds rename(2) is atomic within a filesystem and overwrites the target if it exists (even over NFS). So the normal way to do this since time immemorial is to create "foo.tmp.nn" in the same dir, then rename it on top of "foo". As a bonus, on startup your code should look for temp files with your pattern and clean up or recover.

0
0
0

@phlash @penguin42 @revk @torvalds there have been several discussions about a replace flag for linkat, not sure how far they got tho.

Eg https://lwn.net/Articles/810848/

0
0
0