The reason why I am asking is because I'm using iwatch (not to confuse with a gadget device) to watch for filesystem events (in my case – file creation/renaming).
What I cannot explain is this log:
/path/to/file.ext.filepart 0 IN_MODIFY
/path/to/file.ext.filepart 0 IN_MODIFY
/path/to/file.ext.filepart 0 IN_MODIFY
/path/to/file.ext.filepart 0 IN_MODIFY
/path/to/file.ext.filepart 0 IN_CLOSE_WRITE
/path/to/file.ext 0 IN_CREATE
/path/to/file.ext.filepart 0 IN_DELETE
/path/to/file.ext 0 IN_ATTRIB
To get it I've copied a file.ext
from a remote machine using WinSCP with temporary file creation option turned on (so that it was either no file file.ext
at all, in case if transfer was terminated, or the complete file was in the destination).
And what confuses me is that the /path/to/file.ext
is only created IN_CREATE
and its attributes modified IN_ATTRIB
(not sure which ones though, but I think that's where all the magic happens).
The strangest thing here is that:
- The
file.ext
is not a result of movingfile.ext.filepart
– there would be a different move event - The
file.ext
is not a result of copyingfile.ext.filepart
– there would be a bunch of write events following byIN_CLOSE_WRITE
So my question is – what is happening here under the hood: how the file.ext
was created with the contents without an explicit rename or data copy?
Best Answer
Transcript from running
Moving a file generates a
move
event, but creating a hard link generates the samecreate
event as creating a new, empty file (as domkfifo
and other ways to create files).Why does the SCP or SFTP server creates a hard link then remove the temporary file rather than moving the temporary file into place? In the source code of OpenSSH (portable 6.0), in
sftp-server.c
, in the functionprocess_rename
, I see the following code (reformatted and simplified to illustrate the part I want to show):That is: try to create a hard link from the temporary file name to the desired file name, then remove the temporary file. If creating the hard link doesn't work because the OS or the filesystem doesn't support that, fall back to a different method: test if the desired file exists, and if doesn't, rename the temporary file. So the point is to rename the temporary file to its final location without risking overwriting a file that may have been created while the copy was in progress. Renaming wouldn't do because
rename
overwrites the target file if it exists.