Interviewer: rm delete the file space to free it?

In Linux, have you ever naively thought that if you delete a file with rm, the occupied space will be released? Things may not always be what you want.

Generates a random content file of a 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 selected one of the results here (you can select any mount 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. Look at boot:

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

You don't have to care how much more there is here. 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  
    return 0;  

As for the program itself, it doesn't do anything practical, that is, open a file and cycle all the time. 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? The space size hasn't changed at all!! Did you delete it using rm?

Let's stop the openFile program and take a look:

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

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

When will a file be deleted?

actually, Only when the reference count of a file is 0 (including the number of hard links), unlink deletion can be called. 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 new data is not rewritten, the block data block on the disk will not be deleted. Therefore, you will see that even if the deleted library runs away, some data can be recovered.

In other words, when a program opens a file (gets 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, but 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; /* Table of contents item object chain header referencing inode */  
unsigned long    i_ino; /* Inode number */  
atomic_t         i_count; /* Reference count */  
unsigned int     i_nlink; /* Number of hard links */  

As for the details inside, there are many contents (for example, the number of hard links will also affect whether the file is deleted), which will not be expanded one by one here.

How to free the space occupied by deleted files?

As for release, as mentioned earlier, 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?

Naturally, there are ways:

$ lsof |grep deleted  

The files marked 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`/fd  
total 0  
lrwx------ 1 root root 64 5 April 9:27 0 -> /dev/pts/25  
lrwx------ 1 root root 64 5 April 9:27 1 -> /dev/pts/25  
lrwx------ 1 root root 64 5 April 9:27 2 -> /dev/pts/25  
lrwx------ 1 root root 64 5 April 9: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 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 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 you have 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.

Keywords: Java Programming Linux Programmer

Added by wing_zero on Sun, 19 Dec 2021 19:57:48 +0200