Interviewer: does rm free the file space after deleting it?

From: programming Pearl

In Linux, have you ever naively thought that when you delete a file with rm, the occupied space will be released? Things may not always go as expected.

Generate a random content file of specified size

Let's take a look at the current space size of each mounted Directory:

$ df -h
/dev/sda11      454M  280M  147M  66% /boot

I have selected one of the result displays here (you can select any mounting directory), and then prepare to generate a file under /boot.

First, we generate a file of 50M size:

$ dd if=/dev/urandom of=/boot/test.txt bs=50M count=1

So far, we have generated a file with a size of 50M. Let's look at the boot:

$ df -h
/dev/sda11      454M  312M  115M  74% /boot

Here, you don't need to worry about how much more there are. You just need to pay attention to the increase in the number of files under /boot.

Test procedure:

int main(void)
{    FILE *fp = NULL;   
fp = fopen("/boot/test.txt", "rw+");   
if(NULL == fp)    
perror("open file failed");   
return -1;   
//do nothing       sleep(1);   
return 0;

As for the program itself, it doesn't really do anything. It just opens a file and keeps cycling. Compile and run:

$ gcc -o openFile openFile.c
$ ./openFile

Open another window and delete test Txt:

$ rm /boot/test.txt

Take another look at the boot space:

$ df -h
dev/sda11      454M  312M  115M  74% /boot

Eh? How come the space size hasn't changed at all!! Did Mingming delete it with rm?

Let's stop the openFile program and see:

$$ df -h
/dev/sda11      454M  280M  147M  66% /boot

Darling, the space will be released immediately, that is, our files will be deleted as expected.

When will a file be deleted?

In fact, unlink deletion can be called only when the reference count of a file is 0 (including the number of hard links). As long as it is not 0, it will not be deleted. The so-called deletion is just the deletion of the link from the file name to the inode. As long as the new data is not rewritten, the block data blocks on the disk will not be deleted. Therefore, you will see that even if the deleted database runs away, some data can be recovered. In other words, when a program opens a file (obtains the file descriptor), its reference count will be +1. Although rm seems to delete the file, it will actually reduce the reference count by 1. However, since the reference count is not 0, the file will not be deleted.

struct inode {
struct hlist_node   i_hash; /* hash Pointer to linked list*/
struct list_head    i_list; /* backing dev IO list */
struct list_head    i_sb_list; /* inode linked list of super block*/
struct list_head    i_dentry; /* Directory item object linked header referencing inode*/
unsigned long    i_ino; /* Inode number*/
atomic_t         i_count; /* Reference count*/
unsigned int     i_nlink; /* Number of hard links*/

There are many details about it (for example, the number of hard links will also affect whether the file is deleted), which will not be expanded here.

How to free the space occupied by deleted files?

As for release, you can restart the process of opening the file. But is there any way to find out which files were deleted, but still opened by some process?

Nature has its way:

$ lsof |grep deleted

The files marked as deleted are such files.

In fact, in the previous example, we can also easily observe (the openFile program runs, and the test.txt file is deleted):

$ ls -al /proc/`pidof openFile`/fdtotal 0
lrwx------ 1 root root 64 5 month   4 09:27 0 -> /dev/pts/25
lrwx------ 1 root root 64 5 month   4 09:27 1 -> /dev/pts/25
lrwx------ 1 root root 64 5 month   4 09:27 2 -> /dev/pts/25
lrwx------ 1 root root 64 5 month   4 09:27 3 -> /boot/test.txt (deleted)

See, test Txt followed by the word deleted.

Since we have said that the file has not been deleted in this case, can it be restored? It can actually be read.


In fact, when such files are deleted, they often appear in the program's log files. Maybe you have a scheduled task to clean up the log files generated by the program. However, if the program itself forgets to close the handle, the disk space will not be released. In the end, you think that all the files have been deleted, but the disk is still occupied. Therefore, make it a good habit to close the file descriptor after opening the file and when not in use.

If you find that Mingming has deleted a large number of files, but the space has not returned to normal, you might as well see if there are programs to open these files.

Tags: Linux Operation & Maintenance CentOS Programmer

Posted by Fergusfer on Wed, 01 Jun 2022 12:28:31 +0530