简体   繁体   中英

How does Linux manage deleting temporary files?

I've been studying some Linux implementation and a question came up to my mind.

As far as I know, there is a bit which marks a file as a temporary file. When the process which generated that file dies, how does the kernel delete it? I've thinking that it might be related to the file descriptor table, but I'm not sure whatsoever.

If someone could give an explanation step-by-step, that would come in handy!

There's no bit that marks a file as a temporary file.

Every inode has a link count field, which is the number of directory entries that refer to the file. Every time you make a hard link to a file this count is increased, and when you remove a name it's decreased; when the count goes to zero, the file is deleted (the inode is marked as available, and all the data blocks are put on the free list).

When a file is opened in a process, a copy of the inode is kept in the kernel's file table, and the number of file handles that refer to it are added into the link count in this copy. When a process closes its file descriptor, the link count is decremented. The file isn't actually removed until this in-memory link count drops to zero. This is what keeps a file on disk while it's open, even if all the names are removed.

So when you create a temporary file, it performs the following steps:

  1. Creates the file. The on-disk inode link count = 1.
  2. Opens the file. The kernel inode link count = 2.
  3. Removes the filename. The kernel inode link count = 1.

At this point, the process can keep using the temporary file, but it can't be opened by another process because it has no name.

When the process closes the file handle, the link count goes to 0, and the file is deleted.

Recent versions of Linux have an O_TMPFILE flag to open(2) that automates this. Instead of specifying a filename, you just specify the directory, which is just used to find a filesystem to hold the file data. When this is used, it effectively does all 3 steps above in one call, but it never actually creates the filename anywhere (so race conditions and name conflicts are avoided).

I've been doing some research on the topic and I found out some extra info to complement the answer that Barmar provided.

I read about tmpfile() system call. This system call creates a temporary file and returns a stream descriptor.

The thing is that tmpfile makes a call to unlink internally. Thus decrementing the link count. Although this link was the last one, if the file has been opened by any process it remains in existence until it is closed. I'm not 100% sure about how this procedure works internally, but I think it is due to the order in which iPut algorithm verifies both reference count and link count. I've seen some implementations of iPut and, first of all, it checks if the reference count equals zero, and if so, then it goes to the link count, deallocating all blocks asigned to the file if it equals zero.

So in this situation, we would have the reference count==1, because we'd still have a process having the file open, but the link count would be zero. So iput would not release the i-node until the process closes the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM