Can write data and sync a removed file

124 views
Skip to first unread message

Benjamin

unread,
Dec 8, 2021, 8:25:50 AM12/8/21
to golang-nuts
The code is pretty simple,  see below
Screen Shot 2021-12-08 at 1.23.19 PM.png

I added breakpoints at line 18. I manually removed the file /tmp/db, and then continued to run the file. Everything was working well. Is this a bug or expected behavior?

Brian Candler

unread,
Dec 8, 2021, 11:13:31 AM12/8/21
to golang-nuts
As a general request, please don't post screen images.  They are very hard to read, especially for (but not exclusively for) those with visual impairment. They also can't be copy-pasted.

You haven't said what platform you are running on.  However if this is Linux or another POSIX-compatible system, it's perfectly fine to delete a file while it's open.  The file remains on disk until the last process which has an open file handle has closed it.

You can demonstrate this quite easily:
- create a large (multi-gigabyte) file
- check the filesystem free space
- open the file
- delete it
- check the filesystem free space
- close it
- check the filesystem free space

Only after closing the file will the free space be returned to the filesystem.

Benjamin

unread,
Dec 8, 2021, 12:10:00 PM12/8/21
to golang-nuts
I tested the program on both Linux and Mac, and the behavior is consistent.  Makes sense, Looks like an expected behavior. Thanks.

Just paste the program as below,

package main

import (
"fmt"
"os"
)

func main() {
f, err := os.OpenFile("/tmp/db", os.O_RDWR | os.O_CREATE, 0666)
if err != nil {
panic(err)
}

if n, err := f.Write([]byte{1, 2, 3, 4, 5}); err != nil || n != 5 {
panic (err)
}

if n, err := f.Write([]byte{6, 7, 8}); err != nil || n != 3 {
panic (err)
}

if err := f.Sync(); err != nil {
panic (err)
}

if err := f.Close(); err != nil {
panic(err)
}

fmt.Println("Done!")
}


Marco Ippolito

unread,
May 4, 2025, 4:29:05 PM (5 days ago) May 4
to Brian Candler, golang-nuts
I wrote this shell script to exemplify the bullet points below:

#! /usr/bin/env bash

space() {
    df -h /
    echo
}

echo Space before creating large file:
space

echo Creating large file:
dd if=/dev/zero of=large_file bs=1G count=10
echo

echo Space after creating large file:
space

echo Opening large file in background process:
bash -c 'exec 3< large_file; sleep 10; echo Closing large file' &
pid=$!
echo

echo Removing large file:
sleep 1; rm -v large_file
echo

echo Space after removing large file:
space

echo Waiting for large file closure:
wait "$pid"
echo

echo Space after closing large file:
space

Which confirms expectations:

Space before creating large file:
Filesystem        Size    Used   Avail Capacity iused ifree %iused  Mounted on
/dev/disk3s3s1   228Gi    10Gi   188Gi     6%    425k  2.0G    0%   /

Creating large file:
10+0 records in
10+0 records out
10737418240 bytes transferred in 5.169940 secs (2076894169 bytes/sec)

Space after creating large file:
Filesystem        Size    Used   Avail Capacity iused ifree %iused  Mounted on
/dev/disk3s3s1   228Gi    10Gi   178Gi     6%    425k  1.9G    0%   /

Opening large file in background process:

Removing large file:
large_file

Space after removing large file:
Filesystem        Size    Used   Avail Capacity iused ifree %iused  Mounted on
/dev/disk3s3s1   228Gi    10Gi   178Gi     6%    425k  1.9G    0%   /

Waiting for large file closure:
Closing large file

Space after closing large file:
Filesystem        Size    Used   Avail Capacity iused ifree %iused  Mounted on
/dev/disk3s3s1   228Gi    10Gi   188Gi     6%    425k  2.0G    0%   /


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/db180a5a-71f3-4328-a50b-cea0f85bd174n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages