ZFS unable to overwrite file content in zpool (full of files)

hi fellow,

have got unsuspected behavior in Zpool volumes and am looking for a workaround, if any, or at least better understand of my system.

shortly the goal : fill an USB memstick with same-size, plain-text files; then delete the content of the files, leaving untouched the name and location.

Code:
root@Amsterdam:~ #  uname -a
FreeBSD Amsterdam 15.0-RELEASE FreeBSD 15.0-RELEASE releng/15.0-n280995-7aedc8de6446 GENERIC amd64

root@Amsterdam:~ #  gpart destroy -F da0
root@Amsterdam:~ #  gpart create -s GPT /dev/da0
root@Amsterdam:~ #  mount /dev/da0 /mnt/test

root@Amsterdam:~ #  gpart destroy -F da1
root@Amsterdam:~ #  zpool create -f -O compression=off -O encryption=on -O keyformat=passphrase ZP_test da1
root@Amsterdam:~ #  zpool status
  pool: ZP_test
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        ZP_test     ONLINE       0     0     0
          da1       ONLINE       0     0     0

errors: No known data errors
said that /tmp holds sufficient files to fillup both memsticks
Code:
root@Amsterdam:~ #  cp /tmp/pic* /mnt/test/
root@Amsterdam:~ #  cp /tmp/pic* /ZP_test/
manually deleted last, partially wrote, file : both USB are now full of equally-sized text files
Code:
root@Amsterdam:~ #  df -h
Filesystem            Size    Used   Avail Capacity  Mounted on
..............
ZP_test                56G     56G      0B   100%    /ZP_test
/dev/da0               56G     56G   -4.5G   109%    /mnt/test

exec a simple C program that write zeroes (%llu) to whole file(s)

Code:
root@Amsterdam:~ #  ./delete /mnt/test
try /mnt/test/pic.0000000 :       zero filled
try /mnt/test/pic.0000001 :       zero filled
try /mnt/test/pic.0000002 :       zero filled
try /mnt/test/pic.0000003 :       zero filled
try /mnt/test/pic.0000004 :       zero filled
try /mnt/test/pic.0000005 :       zero filled
^C


root@Amsterdam:~ #  ./delete /ZP_test
try /ZP_test/pic.0000000 :       zero filled
try /ZP_test/pic.0000001 :       zero filled
try /ZP_test/pic.0000002 :       zero filled
try /ZP_test/pic.0000003 :       zero filled
try /ZP_test/pic.0000004 :       zero filled
try /ZP_test/pic.0000005 :       zero filled
try /ZP_test/pic.0000006 :       zero filled
try /ZP_test/pic.0000007 :       zero filled
^C

while the first run effectively zero-fills the files, the second report the same result, but original data remains in place.

if I instruct program to do multiple SEEK_SET the zfs deletion reports an unexpected error 28 (ENOSPC) that arise a question about how it is possible, while the program opens file in "r+" and does not try to add anything at all.
maybe a misuse of code 28 under some circumstances?

while it is reasonable that system-reported free-space differs, it is unreasonable that overwriting a file in a "full" volume does not.

so the question is : do you know a way to get the desired behavior with zfs ?
in suborder : what is happen for zfs react in that way?

thank you all

______________________________________

fyi the code is

Code:
int main(int argc, char **argv) {

    long                size=262144;
    char                fnam[50];
    unsigned int        a,c;
    FILE*               fp;

    for (a=0;a<29000;a++) {
        sprintf (fnam, "/%s/pic.%07u", argv[1],a);
        printf ("try %s :\t",fnam);
        fp = fopen(fnam, "r+");
        if (fp == NULL) {
            printf ("%s unreadable, skipping\n",fnam);
            return 1;
        } else {
            if (fseek(fp, 0L , SEEK_SET)) {
                fprintf(stderr, "%d\n", errno);
                return 4;
            }
            for (c=0;c<size;c++) {
                fprintf(fp,"%llu\n",(long long) 0);
            }
            printf ("zero filled\n");
        }
        fclose (fp);
    }

    printf ("\n");
    return 0;
}
 
You hopefully understand that ZFS is a Copy-on-write filesystem, while UFS is not?

In traditional file systems, modifying a file overwrites the original data blocks in place. In a copy-on-write (COW) file system, the original blocks remain unchanged. When part of a file is modified, only the affected blocks are written to new locations, and metadata is updated to point to them, preserving the original version until it's no longer needed.

You're never overwriting something on ZFS, it creates new data blocks, which will be really difficult to do if the filesystem is 100% full.
 
i don't know the original file sizes but you are writing 2 bytes in every cycle so your files will have 512k in the end. you don't really zero the file you fill it with
0
0
0
in ascii
 
Back
Top