26

Hi I have many files that have been deleted but for some reason the disk space associated with the deleted files is unable to be utilized until I explicitly kill the process for the file taking the disk space

$ lsof /tmp/
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
cron     1623 root    5u   REG   0,21        0 395919638 /tmp/tmpfPagTZ4 (deleted)

The disk space taken up by the deleted file above causes problems such as when trying to use the tab key to autocomplete a file path I get the error bash: cannot create temp file for here-document: No space left on device

But after I run kill -9 1623 the space for that PID is freed and I no longer get the error.

My questions are:

  • why is this space not immediately freed when the file is first deleted?
  • what is the best way to get back the file space associated with the deleted files?

and please let me know any incorrect terminology I have used or any other relevant and pertinent info regarding this situation.

24

On unices, filenames are just pointers (inodes) that point to the memory where the file resides (which can be a hard drive or even a RAM-backed filesystem). Each file records the number of links to it: the links can be either the filename (plural, if there are multiple hard links to the same file), and also every time a file is opened, the process actually holds the "link" to the same space.

The space is physically freed only if there are no links left (therefore, it's impossible to get to it). That's the only sensible choice: while the file is being used, it's not important if someone else can no longer access it: you are using it and until you close it, you still have control over it - you won't even notice the filename is gone or moved or whatever. That's even used for tempfiles: some implementations create a file and immediately unlink it, so it's not visible in the filesystem, but the process that created it is using it normally. Flash plugin is especially fond of this method: all the downloaded video files are held open, but the filesystem doesn't show them.

So, the answer is, while the processes have the files still opened, you shouldn't expect to get the space back. It's not freed, it's being actively used. This is also one of the reasons that applications should really close the files when they finish using them. In normal usage, you shouldn't think of that space as free, and this also shouldn't be very common at all - with the exception of temporary files that are unlinked on purpose, there shouldn't really be any files that you would consider being unused, but still open. Try to review if there is a process that does this a lot and consider how you use it, or just find more space.

21

Files are deleted from filesystem where is deleted any reference to this inode. Reference can be on disk (link in any directory), and.. from open applications. If you remove file - you only delete reference from disk, but - there is still reference from application.

You can "free" space in two ways then:

  1. as mentioned above - you can kill application, which open file.
  2. you can... truncate file. Even if it's deleted:

If you know pid - look what files are open by this pid: ls -l /proc/PID/fd you see here links like:

undefine@uml:~$ ls -l /proc/18596/fd
razem 0
lrwx------ 1 undefine undefine 64 lut  1 00:06 0 -> /dev/pts/30
lrwx------ 1 undefine undefine 64 lut  1 00:06 1 -> /dev/pts/30
lrwx------ 1 undefine undefine 64 lut  1 00:05 2 -> /dev/pts/30
lr-x------ 1 undefine undefine 64 lut  1 00:06 3 -> /home/undefine/x (deleted)
lr-x------ 1 undefine undefine 64 lut  1 00:06 4 -> anon_inode:inotify

As you see - 3 fd is deleted. you can truncate it by command (for example):

undefine@uml:~$ :>/proc/18596/fd/3
undefine@uml:~$ 

Remember that if application read from this file - it can be dangerous to them. But - if it's only a log file - you can truncate it safetly.

  • note that after truncating the file, the original process holding it can still append to the end (where it expects the end). the result is seemingly huge but sparse files that take up less space on disk (if the file system supports sparse files) and they still keep growing! – törzsmókus May 18 at 5:08
  • yes. If something write to file, it will take place on disk. It's hard do avoid it without stopping application which write to disk ;) – undefine May 21 at 10:49
8

As others have said lsof can be used to list all the deleted files which are still on disk due to open file descriptors. However, this may be a very long list. Here is a command which lists these files sorted by ascending size in bytes:

sudo lsof -F sn0 | tr -d '\000' | grep deleted | sed 's/^[a-z]*\([0-9]*\)n/\1 /' | sort -n

There may be a more succinct way of doing this but the above command worked for me.

5

The space is not immediately freed because the running process still has an open file handle to the just-deleted file. After all, if a process is still trying to use a file, you probably don't really want the kernel to get rid of it (the file). That might make the process a bit upset. The best (and only, so far as I know) way to free the space is do just what you did - kill the process.

  • Probably a better sentence than "just how it works" is "if a process is still using a file Unix shouldn't be trying to get rid of it." – Bratchley Jan 30 '15 at 19:21
  • Good point. I've added that to the answer. – John Jan 30 '15 at 19:23
-1

(Mint 17.1)

TL;DR:

  • Inspect with sudo baobab (Disk Usage Analyzer).
  • Clear root user's trash.

Context

I was stuck with ever decreasing space while I constantly deleted files. I installed the trash-cli package to empty the trash, but this didn't help. Finally, I noticed that when I ran baobab (Disk Usage Analyzer in GUI, at least on Mint 17.1) to inspect the disk space structure, it gave a warning that some folders were not accessible. So I ran it as root using sudo baobab. This revealed the problem. A lot of the files that had been deleted were in the trashbin of the root user, not my own user. Thus, I could not free up the space. Then I simply emptied the trash using as root (sudo trash-cli) and all my space returned.

-1

Try using the below command

lsof | grep deleted

and then kill the pid of the deleted file.

  • The OP got that far; this doesn't answer their questions. – Jeff Schaller Feb 28 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.