Fundamentals 7 min read

Why Deleting a File on Linux Doesn’t Always Free Disk Space

This article explains how Linux file deletion works, why space may not be released when a file is removed, and shows practical commands and a C example to illustrate inode reference counting, using tools like df, dd, lsof, and proper file‑descriptor handling.

Open Source Linux
Open Source Linux
Open Source Linux
Why Deleting a File on Linux Doesn’t Always Free Disk Space

Generating a Random File of Specified Size

First check the current disk usage of each mounted directory with df -h. Then create a 50 MB file in /boot using:

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

After the file is created, run df -h again to see the increased usage in /boot.

Testing File Deletion with a Simple C Program

Compile and run a small C program that opens the file and then loops forever:

#include <stdio.h>
#include <unistd.h>
int main(void) {
    FILE *fp = NULL;
    fp = fopen("/boot/test.txt", "rw+");
    if (NULL == fp) {
        perror("open file failed");
        return -1;
    }
    while (1) {
        // do nothing
        sleep(1);
    }
    fclose(fp);
    return 0;
}

Build and start the program:

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

In another terminal delete the file with rm /boot/test.txt and check the disk usage again. The space does not shrink because the program still holds an open file descriptor, so the inode’s reference count is not zero.

Stop the program, then run df -h once more; the space is released as expected.

When Is a File Actually Deleted?

A file is only removed from the filesystem when its reference count (including hard‑link count) drops to zero. The unlink operation merely removes a name‑to‑inode link; the underlying data blocks remain until no process holds the file open.

struct inode {
    struct hlist_node   i_hash;      /* hash list pointer */
    struct list_head    i_list;      /* backing dev IO list */
    struct list_head    i_sb_list;   /* superblock inode list */
    struct list_head    i_dentry;    /* dentry list */
    unsigned long       i_ino;       /* inode number */
    atomic_t            i_count;     /* reference count */
    unsigned int        i_nlink;     /* hard‑link count */
};

If a process has the file open, its reference count stays above zero, so the file’s data blocks are not reclaimed.

How to Find and Release Space Held by Deleted Files

Use lsof | grep deleted to list files that have been unlinked but are still open by some process. The output shows the file path followed by (deleted).

For example, after deleting test.txt while the program is running, you can see the open descriptor:

$ ls -al /proc/$(pidof openFile)/fd
lrwx------ 1 root root 64 ... 3 -> /boot/test.txt (deleted)

Closing the offending process (or its file descriptor) frees the space.

Summary

Files that appear to be deleted but still occupy disk space are usually still held open by a running process—often log files left open by daemons. Always close file descriptors when they are no longer needed to avoid hidden disk‑space consumption.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

inodedisk spacelsofddfile-systemc-program
Open Source Linux
Written by

Open Source Linux

Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.